为什么这个语法给我一个“非LL(*)决定”错误?

时间:2012-07-16 18:49:35

标签: antlr antlrworks

我正在尝试在语法中添加对表达式的支持。我遵循Scott Stanchfield's Antlr Tutorial给出的例子。由于某种原因,添加规则导致错误。它导致非LL(*)错误,“决策可以匹配输入,例如”'+'..' - 'IDENT'使用多个替代“

简单输入如:

a.b.c + 4

导致错误。我正在使用AntlrWorks Interpreter来测试我的语法。对于一元+/-和添加规则,如何构建树似乎存在问题。我不明白为什么有两种可能的解析。

这是语法:

path    :   (IDENT)('.'IDENT)* //(NAME | LCSTNAME)('.'(NAME | LCSTNAME))*
    ;

term    :   path
    |   '(' expression ')'
    |   NUMBER
    ;

negation 
    :   '!'* term
    ;

unary   :   ('+' | '-')* negation

    ;

mult    :   unary (('*' | '/' | '%') unary)*
    ;

add     :   mult (( '+' | '-' ) mult)*
    ;

relation 
    :   add (('==' | '!=' | '<' | '>' | '>=' | '<=') add)*
    ;

expression
    :   relation (('&&' | '||') relation)*
    ;

multiFunc   
    :   IDENT expression+
    ;

NUMBER  :   DIGIT+ ('.'DIGIT+)?
    ;

IDENT   :   (LCLETTER|UCLETTER)(LCLETTER|UCLETTER|DIGIT|'_')*
    ;

COMMENT
        :       '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |       '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
        ;

WS  :   (' ' | '\t' | '\r' | '\n' | '\f')+ {$channel = HIDDEN;}
    ;

fragment
LCLETTER 
    :   'a'..'z'
    ;

fragment
UCLETTER:   'A'..'Z'
    ;   

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

我需要一双额外的眼睛。我错过了什么?

2 个答案:

答案 0 :(得分:1)

您允许一个或多个表达式匹配的事实:

multiFunc   
 : IDENT expression+
 ;

使你的语法模棱两可。假设您尝试使用"a 1 - - 2"规则匹配multiFunc。解析器现在有两种可能的方法来解析它:aIDENT匹配,但是2个减号1 - - 2会导致expression+出现问题。以下2种解析是可能的:

解析1

enter image description here

解析2

enter image description here

答案 1 :(得分:0)

规则multiFunc中的语法有一个表达式列表。表达式可以代表+-unary开头,因此,由于列表,它也可以跟随相同的令牌。这与add规则相冲突:在继续和终止之间存在问题。