【问题标题】:ANTLR: "for" keyword used for loops conflicts with "for" used in messagesANTLR:用于循环的“for”关键字与消息中使用的“for”冲突
【发布时间】:2020-01-09 15:28:53
【问题描述】:

我的语法如下:

myg                : line+ EOF ;

line                : ( for_loop | command params ) NEWLINE;

for_loop : FOR WORD INT DO NEWLINE stmt_body;

stmt_body: line+ END;

params              : ( param | WHITESPACE)*;

param                : WORD | INT;

command             : WORD;


fragment LOWERCASE  : [a-z] ;
fragment UPPERCASE  : [A-Z] ;
fragment DIGIT : [0-9] ;

WORD                : (LOWERCASE | UPPERCASE | DIGIT | [_."'/\\-])+ (DIGIT)* ;
INT : DIGIT+ ;
WHITESPACE          : (' ' | '\t')+ -> skip;
NEWLINE             : ('\r'? '\n' | '\r')+ -> skip;
FOR: 'for';
DO: 'do';
END: 'end';

我的问题是以下 2 个在该语言中有效:

message please wait for 90 seconds 

这将是一个有效的命令,打印带有单词“for”的消息。

for n 2 do 

这将是for 循环的开始。

问题在于当前的词法分析器与 for 循环不匹配,因为 'for' 与首先出现的 WORD 规则匹配。

我可以通过将 FOR 规则放在 WORD 规则之前来解决这个问题,但是消息中的“for”将被 FOR 规则匹配

【问题讨论】:

  • 你能限制command 不能是其他关键字之一吗?这意味着当令牌for在开头时,它是一个for_loop,否则它是一个command
  • 这是可能的。这有什么帮助,因为在词法分析期间,“for”仍然会被标记为 WORD(因为它首先出现)不?

标签: sequence antlr4 grammar rules


【解决方案1】:

这是典型的关键字与标识符问题,我认为在 Stackoverflow 上有很多关于此的问题。但令我惊讶的是,我只能找到old answer of mine for ANTLR3

即使此处提到的原理保持不变,您也不能再使用 ANTLR4 在解析器规则中更改返回的令牌类型。

需要 2 个步骤才能使您的方案发挥作用。

  1. WORD 规则之前定义关键字。通过这种方式,他们可以获得需要特定关键字的语法部分所需的自己的标记类型。
  2. 有选择地将关键字添加到规则中,这些规则解析名称,您也希望在其中允许这些关键字。

第二步修改你的规则:

param: WORD | INT | commandKeyword;
command: WORD | commandKeyword;
commandKeyword: FOR | DO | END; // Keywords allowed as names in commands.

【讨论】:

  • 谢谢。因此,这意味着消息中的“for”将生成为 FOR 标记,而不是单词,只是在解析方面将在 AST 中正确进行。这是机制吗?
  • 是的。因此,当您遍历解析树时,您应该知道您可以获得WORD、INT 或其中一个关键字作为内容。使用 ANTLR3,我能够将此类已识别关键字的标记类型更改为 ID 以使其更简单。这在 ANTLR4 中不再可能。
猜你喜欢
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 2015-02-11
  • 2017-03-05
相关资源
最近更新 更多