Antlr 如何解析带括号的层次结构根?

Antlr 如何解析带括号的层次结构根?,antlr,Antlr,我正在尝试用ANTLR解析值。以下是我语法的相关部分: root : IDENTIFIER | SELF | literal | constructor | call | indexer; hierarchy : root (SUB^ (IDENTIFIER | call | indexer))*; factor : hierarchy ((MULT^ | DIV^ | MODULO^) hierarchy)*; sum : factor ((PLUS^ | MINUS^) factor

我正在尝试用ANTLR解析值。以下是我语法的相关部分:

root : IDENTIFIER | SELF | literal | constructor | call | indexer;

hierarchy : root (SUB^ (IDENTIFIER | call | indexer))*;

factor  : hierarchy ((MULT^ | DIV^ | MODULO^) hierarchy)*;

sum : factor ((PLUS^ | MINUS^) factor)*;

comparison  : sum (comparison_operator^ sum)*;

value   : comparison | '(' value ')';
我不会描述每一个标记或规则,因为它们的名称很好地解释了它们的作用。该语法运行良好,可编译,允许我使用
value
解析以下内容:

a.b[c(5).d[3] * e()] < e("f")
但是,由于非LL(*)ism,这违反了
规则:

即使在阅读了大多数权威的ANTLR参考之后,我仍然不理解这些错误。然而,我所理解的是,在看到一个圆括号打开时,ANTLR无法知道它是在看圆括号值的开头,还是在圆括号根的开头

如何清楚地定义带括号的根层次结构的行为

编辑:根据要求,附加规则:

parameter : type IDENTIFIER -> ^(PARAMETER ^(type IDENTIFIER));

constructor : NEW type PAREN_OPEN (arguments+=value (SEPARATOR arguments+=value)*)? PAREN_CLOSE -> ^(CONSTRUCTOR type ^(ARGUMENTS $arguments*)?);

call : IDENTIFIER PAREN_OPEN (values+=value (SEPARATOR values+=value)*)? PAREN_CLOSE -> ^(CALL IDENTIFIER ^(ARGUMENTS $values*)?);

indexer : IDENTIFIER INDEX_START (values+=value (SEPARATOR values+=value)*)? INDEX_END -> ^(INDEXER IDENTIFIER ^(ARGUMENTS $values*));
value
中删除
”(“value”)”
,并将其置于
根目录中:

root : IDENTIFIER | SELF | literal | constructor | call | indexer | '(' value ')';

...

value : comparison;
现在
(a.b).c
将导致以下解析:

(3
中:

当然,您可能希望从AST中省略括号:

root : IDENTIFIER | SELF | literal | constructor | call | indexer | '('! value ')'!;
此外,您不需要在解析器规则中使用
+=
列表中追加标记。以下是:

call 
 : IDENTIFIER PAREN_OPEN (values+=value (SEPARATOR values+=value)*)? PAREN_CLOSE 
   -> ^(CALL IDENTIFIER ^(ARGUMENTS $values*)?)
 ;
可以改写为:

call 
 : IDENTIFIER PAREN_OPEN (value (SEPARATOR value)*)? PAREN_CLOSE 
   -> ^(CALL IDENTIFIER ^(ARGUMENTS value*)?)
 ;
编辑 您的主要问题是,某些输入可以通过两种(或更多)方式进行解析。例如,输入的
(a)
可以通过
值的备选方案1和2进行解析
规则:

root : ... | '(' value ')';
value 
 : comparison    // alternative 1
 | '(' value ')' // alternative 2
 ;
运行解析器规则:
比较
(备选方案1)可以匹配
(a)
,因为它匹配
规则,而根
规则又匹配
”(“值”)
。但这也是备选方案2所匹配的!这就是:解析器“看到”一个输入,两个不同的输入
解析并报告此歧义。

您能发布完整的解析文件吗?(例如,什么是
构造函数
调用
索引器
)我不是ANTLR专家,但我过去也做过类似的事情(确切地说,编译器-使用Lex/Yacc作为解析器部分-我可能能够帮助你。我真的相信这些与问题无关,但我会把它们添加到问题中。只是一个想法(这可能看起来很愚蠢,但如果我是你,我会尝试):创建另一个元素
superroot:PAREN\u OPEN root PAREN\u CLOSE
,看看会发生什么。(我希望我没有弄乱语法,但你明白我的意思了……)或者基本上:
super:PAREN_OPEN root PAREN_CLOSE | root
我本可以添加
|'(“root”)
而不是
|'(“value”)
,但这只允许将其他根元素括起来,而不是像
(3
。非常感谢。你能给我一些关于如何理解和分析这些错误的解释吗?我的大脑仍然无法掌握出了什么问题,因此它显然无法修复它。(附言:我的语法还没有针对美进行优化,但谢谢你的隐含列表提示)@LazloBonin,请看我的编辑。谢谢。然而,我坚持认为,这在
规则具有非LL(*)决策中是不明确的,因为从alts 1,2可以访问递归规则调用。我看不出你的解释有什么反复。@LazloBonin:对。我只注册了“alts错误”,但这只是问题的一部分。递归的事实是,
也是括号内的
。如果在
value
-和
root
规则中删除文本括号内的
value
,您将看到只有一个“alts错误”,没有提到递归。
call 
 : IDENTIFIER PAREN_OPEN (value (SEPARATOR value)*)? PAREN_CLOSE 
   -> ^(CALL IDENTIFIER ^(ARGUMENTS value*)?)
 ;
value 
 : comparison    // alternative 1
 | '(' value ')' // alternative 2
 ;