System Programming

Using Lex and YACC, a simple parser for Arithmetic Expression

Author: Manav Sanghavi

"yacc.y" file


%{
#include "stdio.h"
int result=0;
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}

int yywrap(void)
{
return 1;
}
%}
%token number plus minus divide multiply
%left plus minus
%left multiply divide
%right '^'
%nonassoc UMINUS

%%
ae: exp  {result=$1;}
  ;
exp: number {  $$ = $1;}
   | exp minus exp {$$ = $1 - $3;}
   | exp plus exp { $$ = $1 + $3;}
   | exp divide exp { if ( $3 == 0 ) yyerror("divide by zero"); else $$ = $1 / $3;}
   | minus exp %prec UMINUS {$$ = -$2; }
   | exp multiply exp { $$ = $1 * $3 ;}
   | exp '^' exp {  }
   ;
%%
#include "math.h"

int main(void)
{

yyparse();
printf("=%d",result);
return 0;
}

"lex.l" file


%{
#include "stdio.h"
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {yylval=atoi(yytext);return number;}
\+ { return plus;}
\- { return minus;}
\* { return multiply;}
\/ {return divide;}
. {return yytext[0];}
[ \t]+ ;
\n return 0;
%%

Sample Output

steps to execute and output


[kjsce@localhost ~]$ lex lex.l
[kjsce@localhost ~]$ yacc -d yacc.y
[kjsce@localhost ~]$ cc -o anyopfilename y.tab.c lex.yy.c
[kjsce@localhost ~]$ ./anyopfilename*
5+9*10
=95[kjsce@localhost ~]$
[kjsce@localhost ~]$ ./anyopfilename*
*9
=error[kjsce@localhost ~]$
Program List