这是antlr4语法的歧义吗?

时间:2015-11-28 06:57:25

标签: 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 : 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?

谢谢!

1 个答案:

答案 0 :(得分:0)

我得到了以下内容:

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。此外,charcters-to-match语法列表错误并导致逗号上出现意外匹配。卫生署。