Monday, 5 September 2016

Abstrct syntax tree using LEX and YACC

*******LEX***

   %{
   #include "y.tab.h"
   extern int yylval;
   %}
   %%
   "="      { return EQ; }
   "!="     { return NE; }
   "<"      { return LT; }
   "<="     { return LE; }
   ">"      { return GT; }
   ">="     { return GE; }
   "+"      { return PLUS; }
   "-"      { return MINUS; }
   "*"      { return MULT; }
   "/"      { return DIVIDE; }
   ")"      { return RPAREN; }
   "("      { return LPAREN; }
   ":="     { return ASSIGN; }
   ";"      { return SEMICOLON; }
   "IF"     { return IF; }
   "THEN"   { return THEN; }
   "ELSE"   { return ELSE; }
   "FI"     { return FI; }
   "WHILE"  { return WHILE; }
   "DO"     { return DO; }
   "OD"     { return OD; }
   "PRINT"  { return PRINT; }
   [0-9]+   { yylval = atoi(yytext); return NUMBER; }
   [a-z]    { yylval = yytext[0] - 'a'; return NAME; }  
   \        { ; }
   \n       { nextline(); }
   \t       { ; }
   "//".*\n { nextline(); }
   .        { yyerror("illegal token"); }
   %%
   #ifndef yywrap
   yywrap() { return 1; }
   #endif

*************Yacc*********

   %start ROOT

   %token EQ
   %token NE
   %token LT
   %token LE
   %token GT
   %token GE
   %token PLUS
   %token MINUS
   %token MULT
   %token DIVIDE
   %token RPAREN
   %token LPAREN
   %token ASSIGN
   %token SEMICOLON
   %token IF
   %token THEN
   %token ELSE
   %token FI
   %token WHILE
   %token DO
   %token OD
   %token PRINT
   %token NUMBER
   %token NAME

   %%

   ROOT:
     stmtseq { execute($1); }
   ;

   statement:
     designator ASSIGN expression { $$ = assignment($1, $3); }
   | PRINT expression { $$ = print($2); }
   | IF expression THEN stmtseq ELSE stmtseq FI
        { $$ = ifstmt($2, $4, $6); }
   | IF expression THEN stmtseq FI
        { $$ = ifstmt($2, $4, empty()); }
   | WHILE expression DO stmtseq OD { $$ = whilestmt($2, $4); }  
   ;

   stmtseq:
     stmtseq SEMICOLON statement { $$ = seq($1, $3); }
   | statement { $$ = $1; }
   ;

   expression:
     expr2 { $$ = $1; }
   | expr2 EQ expr2 { $$ = eq($1, $3); }
   | expr2 NE expr2 { $$ = ne($1, $3); }
   | expr2 LT expr2 { $$ = le($1, $3); }
   | expr2 LE expr2 { $$ = le($1, $3); }
   | expr2 GT expr2 { $$ = gt($1, $3); }
   | expr2 GE expr2 { $$ = gt($1, $3); }
   ;

   expr2:
     expr3 { $$ == $1; }
   | expr2 PLUS expr3 { $$ = plus($1, $3); }
   | expr2 MINUS expr3 { $$ = minus($1, $3); }
   ;

   expr3:
     expr4 { $$ = $1; }
   | expr3 MULT expr4 { $$ = mult($1, $3); }
   | expr3 DIVIDE expr4 { $$ = divide ($1, $3); }
   ;

   expr4:
     PLUS expr4 { $$ = $2; }
   | MINUS expr4 { $$ = neg($2); }
   | LPAREN expression RPAREN { $$ = $2; }
   | NUMBER { $$ = number($1); }
   | designator { $$ = $1; }
   ;

   designator:
     NAME { $$ = name($1); }
   ;
Here is the complete definition of the abstract syntax:

   domain Statement {

      assignment (Expression lhs, Expression rhs)
      print (Expression x)
      ifstmt (Expression cond, Statement thenpart, Statement elsepart)  
      whilestmt (Expression cond, Statement body)
      seq (Statement s1, Statement s2)
      empty ()

   }

   domain Expression {

      eq (Expression x, Expression y)
      ne (Expression x, Expression y)
      lt (Expression x, Expression y)
      le (Expression x, Expression y)
      gt (Expression x, Expression y)
      ge (Expression x, Expression y)
      plus (Expression x, Expression y)
      minus (Expression x, Expression y)
      mult (Expression x, Expression y)
      divide (Expression x, Expression y)
      neg (Expression x)
      number (int x)
      name (int location)

   }


No comments:

Post a Comment