Parsing 这是antlr4语法中的歧义吗?

Parsing 这是antlr4语法中的歧义吗?,parsing,antlr4,Parsing,Antlr4,我正试图像这样解析输入: (0002,0980); (000a,f987); (0001,[foo]00); 模式为(g,e); 其中g是一个四位十六进制数。如果g是偶数,则e是一个四位数的十六进制数,可以是偶数,也可以是奇数。如果g为奇数,则e的模式为“[IDENT]十六进制数字十六进制数字” 我尝试了很多变化,但这总结了我的想法 grammar Post; script : statement (statement)* EOF ; statement : tag ';' ; tag

我正试图像这样解析输入:

(0002,0980);
(000a,f987);
(0001,[foo]00);
模式为(g,e); 其中g是一个四位十六进制数。如果g是偶数,则e是一个四位数的十六进制数,可以是偶数,也可以是奇数。如果g为奇数,则e的模式为“[IDENT]十六进制数字十六进制数字”

我尝试了很多变化,但这总结了我的想法

grammar Post;


script : statement (statement)* EOF ;

statement : tag ';' ;

tag : even_tag | odd_tag ;

even_tag : '(' g_even ',' e_even ')' ;
odd_tag  : '(' g_odd ',' e_odd ')' ;

g_even : HEXDIGIT HEXDIGIT HEXDIGIT EVEN_HEXDIGIT ;
g_odd  : HEXDIGIT HEXDIGIT HEXDIGIT ODD_HEXDIGIT ;
e_even : HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT ;
e_odd  : '[' IDENT ']' HEXDIGIT HEXDIGIT ;

HEXDIGIT : ODD_HEXDIGIT | EVEN_HEXDIGIT ;

ODD_HEXDIGIT    :   ['1','3','5','7','9', 'b', 'B', 'd', 'D', 'f', 'F'];

EVEN_HEXDIGIT   :   ['0','2','4','6','8', 'a', 'A', 'c', 'C', 'e', 'E'];

IDENT  : LETTER (LETTER | DIGIT | ' ')*;

fragment LETTER : ('a'..'z' | 'A'..'Z') ;

fragment DIGIT  : ('0'..'9');
它失败了,出现了不鼓舞人心的错误 第2行:12处的令牌识别错误:'\n' 第3行:4在输入端(0001)没有可行的替代方案

将此修改为

grammar P2;

script : statement (statement)* EOF ;

statement : tag ';' ;

tag : even_tag | odd_tag ;

even_tag : '(' g_even ',' e_even ')' ;
odd_tag  : '(' g_odd ',' e_odd ')' ;

g_even : G_EVEN ;
g_odd  : G_ODD ;
e_even : E_EVEN ;
e_odd  : E_ODD ;

G_EVEN : HEXDIGIT HEXDIGIT HEXDIGIT EVEN_HEXDIGIT ;
G_ODD  : HEXDIGIT HEXDIGIT HEXDIGIT ODD_HEXDIGIT ;
E_EVEN : HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT ;
E_ODD  : '[' IDENT ']' HEXDIGIT HEXDIGIT ;

ODD_HEXDIGIT    :   ['1','3','5','7','9', 'b', 'B', 'd', 'D', 'f', 'F'];

EVEN_HEXDIGIT   :   ['0','2','4','6','8', 'a', 'A', 'c', 'C', 'e', 'E'];

HEXDIGIT : ODD_HEXDIGIT | EVEN_HEXDIGIT ;

IDENT  : LETTER (LETTER | DIGIT | ' ')*;

fragment LETTER : ('a'..'z' | 'A'..'Z') ;

fragment DIGIT  : ('0'..'9');
这很有帮助,但问题看起来更像是e

line 2:5 mismatched input ',098' expecting ','
line 2:12 token recognition error at: '\n'
我怀疑这个问题是因为g_偶数和e_偶数是不明确的,而g_奇数和e_偶数是不明确的。然而,这种模式是可以避免这种不明确的,因为g总是首先被解析,g_偶数和g_奇数不是不明确的。一旦g已知,就没有不明确的地方了。只有在解析器不知道的情况下才有不明确的地方要知道它总是先寻找g。只有当解析可能以e开头时才有歧义,而事实并非如此

也许问题根本不是含糊不清。我对这个游戏还不熟悉。 我如何解析它,以便解析树标签g_偶数、g_奇数、e_偶数、e_奇数


谢谢!

我将此功能用于以下功能:

grammar P2;

script : statement (statement)* EOF ;

statement : tag ';' ;

tag : even_tag | odd_tag ;

even_tag : '(' g_even ',' e_even ')' ;
odd_tag  : '(' g_odd ',' e_odd ')' ;

g_even : G_EVEN ;
g_odd  : G_ODD ;
e_even : G_EVEN | G_ODD;
e_odd  : E_ODD ;

G_EVEN : HEXDIGIT HEXDIGIT HEXDIGIT EVEN_HEXDIGIT ;
G_ODD  : HEXDIGIT HEXDIGIT HEXDIGIT ODD_HEXDIGIT ;
//E_EVEN : HEXDIGIT HEXDIGIT HEXDIGIT HEXDIGIT ;
E_ODD  : '[' IDENT ']' HEXDIGIT HEXDIGIT ;

ODD_HEXDIGIT    :   [13579bBdDfF];

EVEN_HEXDIGIT   :   [02468aAcCeE];

HEXDIGIT : ODD_HEXDIGIT | EVEN_HEXDIGIT ;

IDENT  : LETTER (LETTER | DIGIT | ' ')*;


fragment LETTER : ('a'..'z' | 'A'..'Z') ;

fragment DIGIT  : ('0'..'9');

甚至不需要定义重叠的E_。此外,要匹配语法的字符列表是错误的,并且导致了逗号.Doh上的意外匹配。

如果允许ANTLR解析所有情况而不考虑奇偶校验,然后通过CST进行验证传入代码,可能会更简单。是的,这似乎是一门艺术。我们选择了ions:lexer?parser?tree walker?我认为这很酷,因为人们只需要阅读语法就可以看到发生了什么,而解析器会执行所有提升操作。但这只是更大问题的一小部分。如果在扩展时遇到冲突,我可能会改变思路。