野牛非关联优先规则

时间:2016-03-16 00:04:01

标签: parsing grammar bison

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

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仍然通过,有人可以告诉我我做错了吗?

1 个答案:

答案 0 :(得分:3)

您需要设置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 ...