【问题标题】:Why is this grammar giving me a "non LL(*) decision" error?为什么这个语法给我一个“非 LL(*) 决定”错误?
【发布时间】:2012-07-16 18:49:35
【问题描述】:

我正在尝试在我的语法中添加对表达式的支持。我正在遵循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'
    ;

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

【问题讨论】:

    标签: antlr antlrworks


    【解决方案1】:

    让一个或多个表达式匹配的事实:

    multiFunc   
     : IDENT expression+
     ;
    

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

    解析1

    解析2

    【讨论】:

    • 啊!那讲得通。我必须想出一种不同的方法来创建参数列表。谢谢!顺便说一句,您提供的图表帮助了一个捆绑包。
    【解决方案2】:

    规则multiFunc 中的语法有一个表达式列表。表达式可以以+- 开头,代表unary,因此由于列表的原因,它也可以后跟相同的标记。这与add 规则相冲突:在继续和终止之间做出决定时出现问题。

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 1970-01-01
      • 1970-01-01
      • 2015-12-11
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多