Compiler construction Bison-Yacc-If语句始终执行

Compiler construction Bison-Yacc-If语句始终执行,compiler-construction,bison,flex-lexer,yacc,lex,Compiler Construction,Bison,Flex Lexer,Yacc,Lex,我试图以以下形式在Flex和Bison中实现一个简单的if语句: (表达式)?(表达式) 如果左表达式是非零值,则将执行右表达式 使用Bison语法规则,有人能给我举个例子说明我是如何做到的吗 下面是我的野牛代码的piec,它显示了我到目前为止所拥有的: %union{ int d; char *s; } %token <d>INTEGER %token <s>VARIABLE %nonassoc IF %type <d>expr %type <

我试图以以下形式在Flex和Bison中实现一个简单的if语句:

(表达式)?(表达式)

如果左表达式是非零值,则将执行右表达式

使用Bison语法规则,有人能给我举个例子说明我是如何做到的吗

下面是我的野牛代码的piec,它显示了我到目前为止所拥有的:

    %union{
int d;
char *s;
}

%token <d>INTEGER
%token <s>VARIABLE
%nonassoc IF
%type <d>expr
%type <s> statement
%error-verbose
%left '+' '-'
%left '*' '/'
%left POWER
%right '!'



%%
program:
program statement {printf("Prefix notation of given expression: %s \n", stack[head]); /*Print final expression*/ }

|

;

statement:
expr '\n' { /* printf(" = %d \n", $1); */}
| VARIABLE '=' expr { sym[get_var_index($1)] = $3; printf(" = %d \n", $3); printf("Assigning var %s = %d index %d \n", $1, sym[get_var_index($1)],get_var_index($1)); }
| '(' expr ')' IF '('statement')' '\n' {printf("Bison found if statement: if(stmnt) then stmnt \n"); ($2)?$6: printf("False \n");}
|'\n'

;

expr:
INTEGER { $$ = $1; pushInt($1); printf("Got an Integer %d \n", $1);}
| VARIABLE { $$= sym[get_var_index($1)]; pushChars($1); printf("Printing %s = %d \n", $1, sym[get_var_index($1)]); }
| expr '+' expr { $$ = $1 + $3; popAndCalc("+"); }
| expr '-' expr { $$ = $1 - $3; popAndCalc("-"); }
| expr '*' expr { $$ = $1 * $3; popAndCalc("*"); }
| expr '/' expr { $$ = $1 / $3; popAndCalc("/"); }
| expr POWER expr { $$ = pow($1, $3); popAndCalc("**"); }
| '(' expr ')' { $$ = $2;}
| '!' expr { $$ = !$2; popAndCalc("!"); }
%union{
int d;
char*s;
}
%令牌整数
%标记变量
%非ASSOC IF
%类型表达式
%类型语句
%错误详细
%左'+''-'
%左'*''/'
%左幂
%对‘!’
%%
节目:
程序语句{printf(“给定表达式的前缀表示法:%s\n”,stack[head]);/*Print final expression*/}
|
;
声明:
expr'\n'{/*printf(=%d\n',$1);*/}
|变量'='expr{sym[get_var_index($1)]=$3;printf(=%d\n',$3);printf(“赋值变量%s=%d索引%d\n”,$1,sym[get_var_index($1)],get var_index($1));]
|“('expr')'IF'('statement')”\n'{printf(“Bison发现IF语句:IF(stmnt)then stmnt\n”);($2)?$6:printf(“False\n”);}
|“\n”
;
表达式:
整数{$$=$1;pushInt($1);printf(“得到一个整数%d\n”,$1);}
|变量{$$=sym[get_var_index($1)];pushChars($1);printf(“打印%s=%d\n”,$1,sym[get_var_index($1)];}
|expr'+'expr{$$=$1+$3;popAndCalc(“+”;}
|expr'-'expr{$$=$1-$3;popAndCalc(“-”;}
|expr'*'expr{$$=$1*$3;popAndCalc(“*”;}
|expr'/'expr{$$=$1/$3;popAndCalc(“/”;}
|expr POWER expr{$$=pow($1,$3);popAndCalc(“**;”)
|“('expr')”{$$=$2;}
| '!' expr{$$=!$2;popAndCalc(!”;}
但是,当我运行它时,即使它为false,它也会运行块:


我如何解决这个问题?我想我遗漏了一些东西,请帮助……

根本的问题是,在解析代码时,您正在无条件地执行代码。因此,无论上下文如何,程序中的所有内容都只执行一次。问题的一般解决方案是将执行与解析分开——而不是在解析时执行,而是解析成某种可以稍后执行的数据结构。然后,当您想要执行某些代码时,您只执行该代码。这可以处理条件、循环、函数以及将来可能要执行的任何其他操作。

基本问题是,在解析代码时,您正在无条件地执行代码。因此,无论上下文如何,程序中的所有内容都只执行一次。问题的一般解决方案是将执行与解析分开——而不是在解析时执行,而是解析成某种可以稍后执行的数据结构。然后,当您想要执行某些代码时,您只执行该代码。这可以处理条件、循环、函数以及将来可能需要执行的任何其他操作