I'm trying to implement an if-statement in yacc. I've already wrote some code a few month ago, but i'm not sure in what i have done. This is what i have to do:
if(condition_1) { z=constant_1; }
else_if(condition_2) {z=constant_2;}
else_if ...
…
…
else_if(condition_N-1) {z=constant_N-1;}
else { z=constant_N;}
Where condition_1..N-1 must involve only var-operation(<,>,==,!=)-var or var-operation-constatnt like x<5, y==x, and so on. The variable must be only 'x' or 'y' and initialised before the if-statement (set to zero otherwise). At the end i have to print the output of the variable 'z'. I try to execute it and it seems to work correctly, but i don't know if i have make some mistake that could lead to an error. Any help would be appreciate.
Here is the lex file:
%{
#include "y.tab.h"
void yyerror (char *s);
int yylex();
%}
%%
"print" {return PRINT;}
"exit" {return EXIT_COMMAND;}
"if" {return IF;}
"elseif" {return ELSEIF;}
"elif" {return ELSEIF;}
"else" {return ELSE;}
"(" {return LP;}
")" {return RP;}
"{" {return GLP;}
"}" {return GRP;}
"==" {return EQEQ;}
"=" {return EQ;}
"!=" {return NEQ;}
";" {return SEMI;}
"<" {return LT;}
">" {return GT;}
"x" {return _X;}
"y" {return _Y;}
"z" {return _Z;}
[-]?[0-9]+ {yylval.val = atoi(yytext); return NUMBER;}
[ \t\n]+ ;
. ;
%%
here's the yacc file:
%{
void yyerror (char *s); /* Viene chiamato in caso di errore sintattico o grammatico */
int yylex();
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int x = 0,y = 0, z = 0;
%}
%union {
int val;
int a;
}
%token PRINT
%token EXIT_COMMAND
%token IF
%token ELSEIF
%token ELSE
%token _X
%token _Y
%token _Z
$token _VAR
%token<val> NUMBER
%token LP
%token RP
%token GLP
%token GRP
%token EQEQ
%token EQ
%token NEQ
%token SEMI
%token LT
%token GT
%type<a> then
%type<a> condition
/* assignment */
%right EQ
%start main_program
%%
main_program:
| main_program rule
;
rule: '\n'
| init_variables
| if_condition
| printing
| EXIT_COMMAND {printf("Uscita dal programma in corso...\n"); exit(0);}
| error rule {yyerrok;} /* skip line */
;
printing: PRINT _X {printf("\nx=%d\n",x);}
| PRINT _Y {printf("\ny=%d\n",y);}
| PRINT _Z {printf("\nz=%d\n",z);}
;
init_variables:
_X EQ NUMBER SEMI {x = $3;}
| _Y EQ NUMBER SEMI {y = $3;}
;
if_condition: IF LP condition RP GLP then GRP else_condition {if($3 == 1){z=$6;} printf("\nz=%d\n",z);}
;
condition: _X LT NUMBER {if(x<$3){$$=1;}else{$$=0;}}
| _X GT NUMBER {if(x>$3){$$=1;}else{$$=0;}}
| _X EQEQ NUMBER {if(x==$3){$$=1;}else{$$=0;}}
| _X NEQ NUMBER {if(x!=$3){$$=1;}else{$$=0;}}
| _X LT _VAR {if(x<$3){$$=1;}else{$$=0;}}
| _X GT _VAR {if(x>$3){$$=1;}else{$$=0;}}
| _X EQEQ _VAR {if(x==$3){$$=1;}else{$$=0;}}
| _X NEQ _VAR {if(x!=$3){$$=1;}else{$$=0;}}
| _Y LT _VAR {if(y<$3){$$=1;}else{$$=0;}}
| _Y GT _VAR {if(y>$3){$$=1;}else{$$=0;}}
| _Y EQEQ _VAR {if(y==$3){$$=1;}else{$$=0;}}
| _Y NEQ _VAR {if(y!=$3){$$=1;}else{$$=0;}}
| _Y LT NUMBER {if(y<$3){$$=1;}else{$$=0;}}
| _Y GT NUMBER {if(y>$3){$$=1;}else{$$=0;}}
| _Y EQEQ NUMBER {if(y==$3){$$=1;}else{$$=0;}}
| _Y NEQ NUMBER {if(y!=$3){$$=1;}else{$$=0;}}
;
then: _Z EQ NUMBER SEMI {$$ = $3;}
;
else_condition: ELSE GLP then GRP {z = $3;}
| ELSEIF LP condition RP GLP then GRP else_condition {if($3 == 1){z=$6;}}
;
%%
void yyerror(char *s){
printf("ERRORE: %s\n",s);
}
int yywrap(){
return 1;
}
int main (void){
return yyparse();
}
Aucun commentaire:
Enregistrer un commentaire