【问题标题】:Context Free Grammar in ANTLR throwing error for if-statementANTLR 中的上下文无关语法为 if 语句抛出错误
【发布时间】:2014-04-10 03:02:20
【问题描述】:

我在 ANTLR 中为类似 Java 的 if 语句编写了一个语法如下:

if_statement
    :   'if' expression
        (statement | '{' statement+ '}')
        ('elif' expression (statement | '{' statement+ '}'))*
        ('else' (statement | '{' statement+ '}'))?
    ;

我已经正确实现了“语句”和“表达式”,但是 if_statement 给了我以下错误:

Decision can match input such as "'elif'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
 |---> ('elif' expression (statement | '{' statement+ '}'))*

warning(200): /OptDB/src/OptDB/XL.g:38:9: 
Decision can match input such as "'else'" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
 |---> ('else' (statement | '{' statement+ '}'))?

“elif”和“else”块似乎存在问题。 基本上,我们可以有 0 个或多个“elif”块,所以我用 * 包裹它们 我们也可以有 0 或 1 个“else”块,所以我用 ? 包裹它。

似乎是什么导致了错误?



================================================ ==========================

我还会放“表达式”和“语句”的实现:

statement
    :   assignment_statement
    |   if_statement
    |   while_statement
    |   for_statement
    |   function_call_statement
    ;


term
    :   IDENTIFIER
    |   '(' expression ')'
    |   INTEGER
    |   STRING_LITERAL
    |   CHAR_LITERAL
    |   IDENTIFIER '(' actualParameters ')'
    ;

negation
    :   'not'* term
    ;

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

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

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

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

expression
    :   relation (('and' | 'or') relation)*
    ;

actualParameters
    :   expression (',' expression)*
    ;

【问题讨论】:

    标签: parsing programming-languages antlr grammar lexical-analysis


    【解决方案1】:

    因为您的语法允许语句块不按{...} 分组,所以您有一个经典的dangling else 歧义。

    简短的解释。输入:

    if expr1 if expr2 ... else ...
    

    可以解析为:

    解析 1

    if expr1
        if expr2
            ...
        else
            ...
    

    也可以这样:

    解析 2

    if expr1
        if expr2
            ...
    else
        ...
    

    要消除歧义,请更改:

    (statement | '{' statement+ '}')
    

    进入:

    '{' statement+ '}'
    // or
    '{' statement* '}'
    

    以便通过查看if 所属的大括号可以清楚地看到else 或添加a predicate 以强制解析器选择Parse 1

    if_statement
     : 'if' expression statement_block
       (('elif')=> 'elif' expression statement_block)*
       (('else')=> 'else' statement_block)?
     ;
    
    statement_block
     : '{' statement* '}'
     | statement
     ;
    

    【讨论】:

    • +1:经典问题,经典解决方案,优秀答案,包括规范参考。我希望我可以添加一些东西。
    • 第 3rd 解决方案使用类似于 Java 语言规范中的 NoShortIf 规则,显示为 here in Chapter 19(搜索以 NoShortIf 结尾的规则)。
    猜你喜欢
    • 1970-01-01
    • 2015-01-05
    • 2022-08-16
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多