我有以下语法:
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规则匹配
这是典型的关键字与标识符问题,我认为在Stackoverflow上存在很多与此有关的问题。但是令我惊讶的是,我只能找到一个old answer of mine for ANTLR3。
即使这里提到的原理保持不变,您也无法使用ANTLR4在解析器规则中更改返回的令牌类型。
要使方案正常工作,需要两个步骤。
WORD
规则之前定义关键字。这样,他们就能获得语法部分所需的自己的令牌类型,而令牌部分需要特定的关键字。第二步,修改规则:
param: WORD | INT | commandKeyword;
command: WORD | commandKeyword;
commandKeyword: FOR | DO | END; // Keywords allowed as names in commands.