我在下面有此语法,用于实现采用IN
数字或字符串列表的运算符。
grammar listFilterExpr;
listFilterExpr: entityIdNumberListFilter | entityIdStringListFilter;
entityIdNumberProperty
: 'a.Id'
| 'c.Id'
| 'e.Id'
;
entityIdStringProperty
: 'f.phone'
;
listFilterExpr
: entityIdNumberListFilter
| entityIdStringListFilter
;
listOperator
: '$in:'
;
entityIdNumberListFilter
: entityIdNumberProperty listOperator numberList
;
entityIdStringListFilter
: entityIdStringProperty listOperator stringList
;
numberList: '[' ID (',' ID)* ']';
fragment ID: [1-9][0-9]*;
stringList: '[' STRING (',' STRING)* ']';
STRING
: '"'(ESC | SAFECODEPOINT)*'"'
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
如果我尝试解析以下输入:
c.Id $in: [1,1]
然后我在解析器中收到以下错误:
mismatched input '1' expecting ID
请帮助我纠正此语法。
更新资料
我在项目的巨大语法文件中找到了以下遵循以下规则的方法,该文件可能与'1'匹配之前才匹配ID
:
NUMBER
: '-'? INT ('.' [0-9] +)?
;
fragment INT
: '0' | [1-9] [0-9]*
;
但是,如果我ID
在之前编写规则,NUMBER
那么其他事情就会失败,因为它们已经匹配ID
,应该匹配NUMBER
我该怎么办?
如rici所述:ID
不应为fragment
。片段只能由其他词法分析器规则使用,它们永远不会自己成为令牌(因此不能在解析器规则中使用)。
只需fragment
从中删除关键字即可:ID: [1-9][0-9]*;
请注意,您还必须考虑空格。您可能想跳过它们:
SPACES : [ \t\r\n] -> skip;
...预期ID的输入“ 1”不匹配...
看来,还有另外一个词法分析器,ID
它也匹配输入1
并在之前定义ID
。在这种情况下,请查看以下问答:ANTLR 4.5-输入“ x”不匹配,期望“ x”
因为您有这样的规则排序:
NUMBER
: '-'? INT ('.' [0-9] +)?
;
fragment INT
: '0' | [1-9] [0-9]*
;
ID
: [1-9][0-9]*
;
词法分析器将永远不会创建ID
令牌(只会创建令牌NUMBER
)。ANTLR就是这样工作的:如果2个或更多的词法分析器规则匹配相同数量的字符,则定义的第一个“获胜”。
首先,我认为有一个ID
仅匹配数字的规则很奇怪,但是,如果这是您要解析的语言,那么可以。就您而言,您可以执行以下操作:
id : POS_NUMBER;
number : POS_NUMBER | NEG_NUMBER;
POS_NUMBER : INT ('.' [0-9] +)?;
NEG_NUMBER : '-' POS_NUMBER;
fragment INT
: '0' | [1-9] [0-9]*
;
然后在解析器规则中ID
使用代替id
。以及使用number
而不是NUMBER
您现在使用的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句