ANTLR:用于循环的 "for" 关键字与消息中使用的 "for" 冲突
ANTLR: "for" keyword used for loops conflicts with "for" used in messages
我有以下语法:
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 规则匹配
这是典型的关键字与标识符问题,我认为 Whosebug 上有很多关于此的问题。但令我惊讶的是,我只能找到 old answer of mine for ANTLR3.
即使那里提到的原则保持不变,您也不能再使用 ANTLR4 更改解析器规则中返回的标记类型。
需要 2 个步骤才能使您的方案正常运行。
- 在
WORD
规则之前定义关键字。通过这种方式,他们可以获得自己的标记类型,您需要特定关键字的语法部分。
- 将关键字选择性地添加到解析名称的规则中,您也希望在其中允许这些关键字。
第二步修改你的规则:
param: WORD | INT | commandKeyword;
command: WORD | commandKeyword;
commandKeyword: FOR | DO | END; // Keywords allowed as names in commands.
我有以下语法:
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 规则匹配
这是典型的关键字与标识符问题,我认为 Whosebug 上有很多关于此的问题。但令我惊讶的是,我只能找到 old answer of mine for ANTLR3.
即使那里提到的原则保持不变,您也不能再使用 ANTLR4 更改解析器规则中返回的标记类型。
需要 2 个步骤才能使您的方案正常运行。
- 在
WORD
规则之前定义关键字。通过这种方式,他们可以获得自己的标记类型,您需要特定关键字的语法部分。 - 将关键字选择性地添加到解析名称的规则中,您也希望在其中允许这些关键字。
第二步修改你的规则:
param: WORD | INT | commandKeyword;
command: WORD | commandKeyword;
commandKeyword: FOR | DO | END; // Keywords allowed as names in commands.