我正在使用ANTLR在Java中创建解释器。我有一个已经使用了很长时间的语法,并且围绕该语法生成的类构建了很多代码。
在语法中,“ false”定义为文字,还有变量名的定义,该变量名允许从数字,数字,下划线和点构建变量名(请参见下面的定义)。
问题是-当我使用'false'作为变量名时。
varName.nestedVar.false
。将false
标记为falseLiteral的规则优先。
我尝试使用互联网上发现的所有内容来处理空白。当我删除WHITESPACE : [ \t\r\n] -> channel (HIDDEN);
并在每个规则中使用显式WS *或WS +的解决方案适用于解析器时,但我将不得不在AST访问者中调整很多代码。我试着告诉boolLiteral规则,它必须在实际文字之前像WHITESPACE * trueLiteral之前有一些空间,但是当将空白发送到HIDDEN通道时,这是行不通的。并再次完全禁用它=重写大量代码。 (因为我经常依赖标记的顺序。)我还尝试按照文字规则对非终结符进行重新排序,但这没有任何作用。
...
literal:
boolLiteral
| doubleLiteral
| longLiteral
| stringLiteral
| nullLiteral
| varExpression
;
boolLiteral:
trueLiteral | falseLiteral
;
trueLiteral:
TRUE
;
falseLiteral:
FALSE
;
varExpression:
name=qualifiedName ...
;
...
qualifiedName:
ID ('.' (ID | INT))*
...
TRUE : [Tt] [Rr] [Uu] [Ee];
FALSE : [Ff] [Aa] [Ll] [Ss] [Ee];
ID : (LETTER | '_') (LETTER | DIGIT | '_')* ;
INT : DIGIT+ ;
POINT : '.' ;
...
WHITESPACE : [ \t\r\n] -> channel (HIDDEN);
我最好的选择是将qualifiedName定义移至词法引诱
qualifiedName:
QUAL_NAME
;
QUAL_NAME: ID ('.' (ID | INT))* ;
然后适用于
varName.false AND false
varName.whatever.ntimes AND false
结果是正确的-> varExpression-> quilafiedName在左侧,而boolLiteral-> falseLiteral在右侧。 但是有了这个定义,这是行不通的,而且我真的不知道为什么
varName AND false
不含的合格名称。返回
line 1:8 no viable alternative at input 'varName AND'
期望的解决方案是仅对特定规则使用以太坊启用/禁用空白->频道{hiddne}
告诉boolLiteral规则,它不能以点开始,有点像〜POINT falseLiteral,但是我也尝试了这一点,但没有运气。
或者当规则移至词法分析器规则时,使qualifiedName在不带点的情况下工作。
谢谢。
答案 0 :(得分:0)
您可以执行以下操作:
qualifiedName
: ID ('.' (anyId | INT))*
;
anyId
: ID
| TRUE
| FALSE
;