Antlr4匹配部队优先级
我有一个查询语法,我正在工作,并发现了一个案件,是证明难以解决。下面提供了复制语法的最低版本Antlr4匹配部队优先级,antlr4,Antlr4,我有一个查询语法,我正在工作,并发现了一个案件,是证明难以解决。下面提供了复制语法的最低版本 grammar scratch; query : command* ; // input rule RANGE: '..'; NUMBER: ([0-9]+ | (([0-9]+)? '.' [0-9]+)); STRING: ~([ \t\r\n] | '(' | ')' | ':' | '|' | ',' | '.' )+ ; WS: [ \t\r\n]+ -> skip ; comma
grammar scratch;
query : command* ; // input rule
RANGE: '..';
NUMBER: ([0-9]+ | (([0-9]+)? '.' [0-9]+));
STRING: ~([ \t\r\n] | '(' | ')' | ':' | '|' | ',' | '.' )+ ;
WS: [ \t\r\n]+ -> skip ;
command
: 'foo:' number_range # FooCommand
| 'bar:' item_list # BarCommand
;
number_range: NUMBER RANGE NUMBER # NumberRange;
item_list: '(' (NUMBER | STRING)+ ((',' | '|') (NUMBER | STRING)+)* ')' # ItemList;
使用此选项时,您可以匹配类似于bar:(bob,blah,57,4.5)foo:2..4.3
没问题。但如果你在栏中输入:(bob.smith,blah,57,4.5)foo:2..4
它会在“.s”处抱怨行1:8令牌识别错误,并将其分为“bob”和“mith”。有道理,
作为字符串的一部分被忽略。虽然不知道为什么它会吃“s”
因此,将字符串更改为string:~([\t\r\n]|'('|')'|':'|'|'|',')+而不是代码>中没有点。现在它将把2..4.3
识别为字符串,而不是数字范围
我相信这是因为字符串在一段中匹配的字符比其他选项多。但是有没有办法强制字符串仅在它还没有匹配语法中较高的元素时才匹配?这意味着如果它不包含范围
或数字
,那么它只是一个字符串
我知道我可以添加术语:'“.*?”
然后将术语
添加到项目列表中,但我希望尽可能避免引用内容。但这似乎是保持。
范围的唯一途径,我发现。字符串中只能有一个点,如下所示:
STRING : ATOM+ ( '.' ATOM+ )*;
fragment ATOM : ~[ \t\r\n():|,.];
哦,还有编号:([0-9]+|([0-9]+)?'。[0-9]+)代码>相当冗长。这是相同的:NUMBER:([0-9]*')?[0-9]+;代码>