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。谢谢你的回复。在研究了你最初的答案后,我终于明白了。