繁体   English   中英

这是antlr4语法中的歧义吗?

[英]Is this an ambiguity in antlr4 grammar?

我试图解析这样的输入:

(0002,0980);
(000a,f987);
(0001,[foo]00);

模式是(g,e); 其中g是四位数的十六进制数。 如果g为偶数,则e是一个四位数的十六进制数,即偶数或奇数。 如果g为奇数,则e的格式为[[IDENT] hex-digit hex-digit]。

我尝试了许多变体,但这总结了我的想法。

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_even和e_even模棱两可而g_odd和e_even模棱两可这一事实造成的。 但是,这种模式可以避免这种歧义,因为总是先解析g,并且g_even和g_odd不会模糊。 一旦知道g,就不会有任何歧义。 如果解析器不知道它总是在先寻找g,则只有模棱两可。 如果解析可能以e开头,那将是唯一的模棱两可,而事实并非如此。

也许问题根本不是模棱两可。 我是这个游戏的新手。 我该如何解析,以便解析树标记g_even,g_odd,e_even和e_odd?

谢谢!

我得到这个与以下工作:

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_EVEN。 另外,字符列表匹配语法是错误的,并导致逗号意外匹配。 h

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM