Parsing ANTLR语法未按预期工作。我做错了什么?
下面的语法用于在操作符中实现一个,获取数字或字符串列表Parsing ANTLR语法未按预期工作。我做错了什么?,parsing,antlr,grammar,lexer,Parsing,Antlr,Grammar,Lexer,下面的语法用于在操作符中实现一个,获取数字或字符串列表 grammar listFilterExpr; listFilterExpr: entityIdNumberListFilter | entityIdStringListFilter; entityIdNumberProperty : 'a.Id' | 'c.Id' | 'e.Id' ; entityIdStringProperty : 'f.phone' ; listFilt
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]
然后我在解析器中得到以下错误:
不匹配的输入“1”应为ID
请帮我改正这语法
更新
我在我的项目的巨大语法文件中发现了以下规则,在它与ID
匹配之前,可能与“1”匹配:
NUMBER
: '-'? INT ('.' [0-9] +)?
;
fragment INT
: '0' | [1-9] [0-9]*
;
但是,如果我在NUMBER
之前编写ID
规则,那么其他东西就会失败,因为它们已经匹配了ID
,而ID应该匹配NUMBER
我该怎么办?正如rici所说:
ID
不应该是片段
。片段只能由其他lexer规则使用,它们自己永远不会成为令牌(因此不能在解析器规则中使用)
只需从中删除片段
关键字:ID:[1-9][0-9]*代码>
请注意,您还必须考虑空格。您可能想跳过它们:
SPACES : [ \t\r\n] -> skip;
。。。
不匹配的输入“1”应为ID
这看起来像是除了ID
之外还有另一个lexer,它也匹配输入1
,并且在ID
之前定义。在这种情况下,请看以下问答:
编辑
因为规则是这样排列的:
NUMBER
: '-'? INT ('.' [0-9] +)?
;
fragment INT
: '0' | [1-9] [0-9]*
;
ID
: [1-9][0-9]*
;
id : POS_NUMBER;
number : POS_NUMBER | NEG_NUMBER;
POS_NUMBER : INT ('.' [0-9] +)?;
NEG_NUMBER : '-' POS_NUMBER;
fragment INT
: '0' | [1-9] [0-9]*
;
lexer永远不会创建ID
令牌(只会创建NUMBER
令牌)。这就是ANTLR的工作原理:如果两个或多个lexer规则匹配相同数量的字符,则第一个定义的规则“获胜”
首先,我认为有一个只匹配数字的ID
规则是很奇怪的,但是,如果这是您正在解析的语言,好的。在您的情况下,您可以这样做:
NUMBER
: '-'? INT ('.' [0-9] +)?
;
fragment INT
: '0' | [1-9] [0-9]*
;
ID
: [1-9][0-9]*
;
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
。我认为您不希望ID
成为fragment
。即使我删除fragment
,它也会给我同样的错误。@teenup那么您可能没有重新生成lexer和parser,因为它在片段
被删除时工作。另一个选择是,你删除了太多的规则,你刚刚发布,你有一些冲突的lexer规则,你没有把你原来的问题。始终发布一个独立的示例,以便其他人看到您所看到的。谢谢。我正在浏览你的答案,并将尝试根据它修复我的项目,然后返回。从这个答案中,我发现了语法中可能存在的冲突,并更新了上面的问题以添加详细信息。如果可能,请帮助解决它。@teenup签出我的EDITOk。谢谢你的回复。在研究了你最初的答案后,我终于明白了。