sequence - ANTLR:用于循环的“for”关键字与消息中使用的“for”冲突
问题描述
我有以下语法:
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';
我的问题是以下两个在这种语言中有效:
message please wait for 90 seconds
这将是一个有效的命令,打印带有单词“for”的消息。
for n 2 do
这将是一个for
循环的开始。
问题是当前的词法分析器与 for 循环不匹配,因为 'for' 与首先出现的 WORD 规则匹配。
我可以通过将 FOR 规则放在 WORD 规则之前来解决这个问题,但是消息中的“for”将与 FOR 规则匹配
解决方案
这是典型的关键字与标识符问题,我认为在 Stackoverflow 上有很多关于此的问题。但令我惊讶的是,我只能为 ANTLR3 找到我的旧答案。
即使那里提到的原理保持不变,您也不能再使用 ANTLR4 在解析器规则中更改返回的令牌类型。
使您的方案工作需要两个步骤。
WORD
在规则之前定义关键字。通过这种方式,他们获得了需要特定关键字的语法部分所需的自己的标记类型。- 有选择地将关键字添加到规则中,这些规则解析名称,您也希望在其中允许这些关键字。
第二步修改你的规则:
param: WORD | INT | commandKeyword;
command: WORD | commandKeyword;
commandKeyword: FOR | DO | END; // Keywords allowed as names in commands.
推荐阅读
- c# - C# 在 DataGridView 上显示我的自定义控件,即使不编辑
- apache-spark - Pyspark 没有从 kafka 流中打印任何数据,也没有失败
- excel - 捕获列中的最后填充日期(VBA)
- discord - 如何将我的“检查”更改为不出错?
- swift - SwiftUI - 从嵌套子视图更改模型
- android - 如何在 React Native 中隐藏渲染元素?
- node.js - 有没有办法在 facebook messenger 聊天机器人上设置 cookie?
- css - 如何在 Rmarkdown Xaringan 代码块中包含不匹配的“]”?
- javascript - 链接预览不适用于 Telegram 和 Whatsapp
- ios - 如何使用 react-native-sensors 或 expo-sensor 计算 React Native 中的总旋转角度或旋转计数?