微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ANTLR 匹配标识符但不是保留关键字

如何解决ANTLR 匹配标识符但不是保留关键字

我正在尝试使用不同的符号匹配复数,其中之一使用 cis 函数,例如:MODULUS cis PHASE

问题是我的标识符规则与 cis 以及它后面的数字的开头匹配,并且由于它比 CIS 标记本身大,所以它总是返回一个标识符标记类型。我怎么能避免这种情况?

语法如下:

grammar SandBox;

input : number? CIS UNSIGNED 
    | IDENTIFIER
    ;

number : FLOAT
    | UFLOAT 
    | UINT
    | INT
    ;

fragment DIGIT : [0-9] ;

UFLOAT : UINT (DOT UINT? | 'f') ;
FLOAT : SUB UFLOAT ;
UINT : DIGITS ;
INT : SUB UINT ;
UNSIGNED : UFLOAT 
    | UINT 
    ;
DIGITS : DIGIT+ ;

// Specific lexer rules
CIS : 'cis' ;
SUB : '-' ; 
DOT : '.' ;
WS : [ \t]+ -> skip ;
NEWLINE : '\r'? '\n' ;

IDENTIFIER : [a-zA-Z_]+[a-zA-Z0-9_]* ;  // has to be after complex so i or cis doesn't match this first

编辑: 我试图解析的输入是复杂的 1+i,但使用它各自的模数和相位,如下所示:1.4142135623730951cis0.7853981633974483

我的实际问题是 IDENTIFIER 规则匹配 cis0 而不是仅仅匹配 CIS 词法分析器规则,即使它在它之前定义。

我隐约知道 ANTLR 根据最大​​匹配选择规则,但在这种情况下,我想避免 =o。

解决方法

我在这里看到两个解决方案:

  1. 使复数成为单个词法分析器规则:
COMPLEX:  (FLOAT | UFLOAT | UINT | INT) WS* CIS WS* UNSIGNED;

这将比标识符或 pur CIS 关键字更长(因此首先匹配)。

  1. cis 序列是一个关键字,当它跟在一个数字之后(它们之间有可选的空格),对吗?因此,您可以进行回顾(如果条件为真,则在谓词中使用 LA(-1) 拒绝 cis 作为标识符。

我更喜欢解决方案 1,因为惯例是单个实体(和复数,如浮点数或字符串,单个逻辑实体)在词法分析器规则中完全匹配,而不是在解析器规则中.

,

我只是把它放在这里是因为我认为这可能是一个潜在的解决方案,尽管我不想使用语义谓词,因为它将我的语法与目标/特定语言联系起来 =/(我以前从未使用过它们所以我不确定是否还有其他警告):

IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]* { identifierIsNotReserved() }?;

然后我们只需要实现 identifierIsNotReserved 方法来检查标识符规则是否消耗了保留关键字,如果是,则阻止规则被应用。我引用:

语义谓词是目标语言中由 {...}? 包围的任意代码块,其计算结果为布尔值。如果返回值为 false,则跳过词法分析器规则。

编辑:忘记添加对我发现它的位置的引用,这里是: https://riptutorial.com/antlr/example/11237/actions-and-semantic-predicates

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。