ANTLR语法:布尔文字,可以在忽略空格的情况下作为合格的变量名称出现

时间:2019-03-28 19:11:11

标签: antlr4

我正在使用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在不带点的情况下工作。

谢谢。

1 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

qualifiedName
 : ID ('.' (anyId | INT))*
 ;

anyId
 : ID
 | TRUE
 | FALSE
 ;