Унарный приоритет операторов в yacc - PullRequest
0 голосов
/ 28 мая 2019

Я получаю странную ошибку в моем парсере 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 Ответ

2 голосов
/ 28 мая 2019

Единственное правило в вашем лексере, которое соответствует круглым скобкам, - это правило ., которое ничего не возвращает (или не дает никаких признаков того, что символ был проигнорирован, что является плохой идеей именно потому, что оно так много делает с подобными проблемами).проще пропустить).Таким образом, круглые скобки в вашем вводе полностью игнорируются, '(' и ')' в вашей грамматике никогда не могут быть сопоставлены, и ввод, который видит анализатор, просто not True and False.

...