【问题标题】:Bison nonassociative precedence ruleBison 非关联优先规则
【发布时间】:2016-03-16 00:04:01
【问题描述】:

我试图通过定义非关联优先级来强制执行一些解析错误。 这是我的语法文件的一部分:

Comparison :
    Value ComparisonOp Value 
    {
        $2->Left($1);
        $2->Right($3);
        $$ = $2;
    } 
    ;

应该解析像 1 = 2 这样的表达式,但是语法中不允许像 1 = 2 = 3 这样的表达式。为了适应这一点,我尝试使我的运算符非关联,如下所示:

%nonassoc NONASSOCIATIVE
.
.(rest of the grammar)
.
Comparison :
    Value ComparisonOp Value %prec NONASSOCIATIVE
    {
        $2->Left($1);
        $2->Right($3);
        $$ = $2;
    } 
    ;

1 = 2 = 3 仍然通过,谁能告诉我我做错了什么?

【问题讨论】:

    标签: parsing grammar bison


    【解决方案1】:

    您需要设置ComparisonOp 标记的关联性。要么

    %nonassoc ComparisonOp NONASSOCIATIVE
    

    如果ComparisonOp 是令牌或类似的东西

    %nonassoc '=' '<' '>' NOT_EQUAL GREATOR_OR_EQUAL LESS_OR_EQUAL NONASSOCIATIVE
    

    如果您有多个令牌并且ComparisonOp 是扩展至其中任何一个的规则


    作为一个具体示例,以下内容与您的要求完全一样:

    %{
    #include <stdio.h>
    #include <ctype.h>
    int yylex();
    void yyerror(const char *);
    %}
    %nonassoc '=' '<' '>' CMPOP
    %left '+' '-' ADDOP
    %left '*' '/' '%' MULOP
    %token VALUE
    %%
    expr: expr cmp_op expr %prec CMPOP
        | expr add_op expr %prec ADDOP
        | expr mul_op expr %prec MULOP
        | VALUE
        | '(' expr ')'
        ;
    cmp_op: '=' | '<' | '>' | '<' '=' | '>' '=' | '<' '>' ;
    add_op: '+' | '-' ;
    mul_op: '*' | '/' | '%' ;
    %%
    int main() { return yyparse(); }
    int yylex() {
        int ch;
        while(isspace(ch = getchar()));
        if (isdigit(ch)) return VALUE;
        return ch;
    }
    void yyerror(const char *err) { fprintf(stderr, "%s\n", err); }
    

    因此,如果您遇到其他问题,请尝试发布 MVCE 以显示您遇到的实际问题...

    【讨论】:

    • ComparisonOp 是一个规则,它扩展到令牌 EQ、NEQ,我尝试为这些令牌添加优先规则,但显然优先级不会传播到父规则
    • 您需要在规则和令牌上正确设置优先级——野牛优先级解析通过比较要减少的规则的优先级和要移动的令牌的优先级来工作。如果你只设置一个或另一个,什么都不会发生。
    • 我都做了,还是不行。一个微妙的地方是,在我拥有的价值规则中
    • 很抱歉超过了 5 分钟的编辑时间限制。 --> 这两样我都做了,还是不行。一个微妙的地方是,在价值的规则中,我有Value : MathExpression + 其他东西,还有MathExpression : Comparison + 其他东西。我不希望第一个比较 (1 = 2 ) 减少到一个值并允许另一个比较 (1= 2) = 3。
    • 问题解决了,克里斯,谢谢,我在两个单独的行上做 %nonassoc '=' '&lt;' '&gt;' 和 %nonassoc CMPOP。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多