简单的模糊语法与减少 - 减少冲突

问题描述 投票:2回答:1

以下用于解析逻辑表达式的简单语法会导致减少/减少冲突:

%token AND OR
%token NUMBER VARIABLE
%%
logical_expr
    : logical_expr AND logical_term
    | logical_expr OR logical_term
    | logical_term
    ;
logical_term
    : VARIABLE
    | comparison
    | '(' logical_expr ')'
    ;
comparison
    : expr '<' expr
    | expr '>' expr
    ;
expr
    : expr '+' term
    | expr '-' term
    | term
    ;
term
    : NUMBER
    | VARIABLE
    | '(' expr ')'
    ;
%%

来自野牛的状态报告包括:

state 2

    4 logical_term: VARIABLE .
   13 term: VARIABLE .

    ')'       reduce using rule 4 (logical_term)
    ')'       [reduce using rule 13 (term)]
    '<'       reduce using rule 13 (term)
    '>'       reduce using rule 13 (term)
    '+'       reduce using rule 13 (term)
    '-'       reduce using rule 13 (term)
    $default  reduce using rule 4 (logical_term)

我猜测问题是它无法弄清楚如何解析“(a)+ 1 <2”。如何消除这种语法的歧义?可能吗?

grammar bison reduce-reduce-conflict ambiguous-grammar
1个回答
4
投票

你的语法的基本问题是,当你看到( VARIABLE和下一个标记是)时,解析器无法判断这是否应该是带括号的exprlogical_expr - 它取决于)之后的下一个标记。如果下一个标记是+-<>然后它的expr,而如果它是ANDOR(或EOF),那么它的logical_expr

通常的解决方案是不要尝试在语法中进行类型检查。虽然它可能,但它需要额外的前瞻,可能需要多级语法或这样的复杂性。

在您的情况下,如果您将logical_term规则更改为

logical_term
    : comparison
    | expr
    ;

冲突消失了,但你的解析器会接受非类型正确的东西,比如a > 3 AND 22 + 2 OR 7。您需要对生成的解析树(或者您正在创建的任何数据结构)进行类型检查以确保正确性,尽管您可能仍然需要(至少您已经需要检查VARIABLE以确保变量是数字或布尔值,具体取决于上下文。)

© www.soinside.com 2019 - 2024. All rights reserved.