yacc中的一元运算符优先级

时间:2019-05-27 22:45:34

标签: yacc

我的YACC解析器出现一个奇怪的错误。这是一个简单的布尔代数表达式求值器。

除以下几种情况外,其他所有方法都适用:

> True and False
False
> (True and False)
False
> not (True and False)     <--- interpreted as (not True and False)
False

example.y:

%{
#include <stdio.h>
int yylex();
void yyerror(const char *err);

%}

%token NEWLINE EQUIV IMPL OR AND NOT CONST

%union {
    bool value;
}

%type <value> CONST value not and or impl equiv expr

%%

program:
    |
    program expr NEWLINE
    ;

expr:
    equiv               { printf("%s\n", $1?"True":"False"); }             
    ;

equiv:
    impl                { $$ = $1; }                   
    |
    equiv EQUIV impl    { $$ = $1 == $3; }     
    ;

impl:
    or              { $$ = $1; }               
    |
    impl IMPL or    { $$ = !$1 || $3; }
    ;

or:
    and             { $$ = $1; }   
    |
    or OR and       { $$ = $1 || $3; } 
    ;

and:
    not             { $$ = $1; }           
    |
    and AND not     { $$ = $1 && $3; }     
    ;

not:
    value           { $$ = $1; }           
    |
    NOT not         { $$ = !$2; }
    ;

value:
    CONST           { $$ = $1; }           
    |
    '(' expr ')'    { $$ = $2; }
    ;

%%

void yyerror(const char *err) {
    fprintf(stderr, "%s\n", err);
}

int main() {
    yyparse();
}

example.l:

%{
#include "y.tab.h"
extern "C" int yywrap();
%}

%%

True                yylval.value = true; return CONST;
False               yylval.value = false; return CONST;

"<=>"               return EQUIV;
=>                  return IMPL;
or                  return OR;
and                 return AND;
not                 return NOT;

[ \t]               ;
\n                  return NEWLINE;
.                   ;

%%

int yywrap() {
    return 1;
}

编译为

bison -dy example.y
flex -l example.l
g++ y.tab.c lex.yy.c

1 个答案:

答案 0 :(得分:2)

词法分析器中唯一与括号匹配的规则是.规则,该规则不返回任何内容(或给出任何字符已被忽略的指示,这是一个坏主意,正是因为它会产生这样的问题非常容易错过)。因此,输入中的括号将被完全忽略,语法中的'('')'永远不会匹配,并且解析器看到的输入只是not True and False