mardi 9 juillet 2019

How to correctly implement an if-statment using yacc?

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