Link to home
Start Free TrialLog in
Avatar of rschippendale
rschippendale

asked on

extending if then else statments in lexical analysis

How would I extend the syntax of the if then else end statement and the if then end statement in the syn.y file, to allow optionally repeating "elif" clauses.
An example: if a>b then c:=10
            elif a<b then c:=100
            else c:=0 end;

Here are the two files for your reference:
------------------------------------------------------------------------------------
Grammar syn.y file

%{
/*            pl 1/2

    this is compiler for a very little language called pl1/2
    (pronounced pl-a-half).
    this is a syntax checker version
*/

#include <stdio.h>
extern int fatalerror;  
%}

%start prog
%token IDENT NUMBER
%token PROGSY BEGINSY IFSY WHILESY THENSY ELSESY DOSY
%token ENDSY ASSIGNSY CONSTSY VARSY WRITESY READSY
%nonassoc '<' '>' '=' '#'
%left '+' '-'
%left '*'

%%
/*  beginning of grammar rules
    ==========================
*/

prog:
      PROGSY ';' decls BEGINSY stats ENDSY '.'
          { /* found a program, */
                if (fatalerror > 0 )
                printf("errors detected\n");
            else
                      printf("program found\n");
        }
   ;

decls:
      /* empty */ { printf("doing: decls\n"); }
   |
decls decl { printf("doing: decls decl\n"); }
   ;

stats:
      stat { printf("doing: stat\n"); }
   |
      stats ';' stat  { printf("doing: stats ; stat\n"); }
   ;

decl:
      CONSTSY IDENT '=' NUMBER ';' { printf("doing: CONST\n"); }
   |
      VARSY IDENT ':' type ';' { printf("doing: VAR\n"); }
   |
      error ';' { fatal("error in declarations",""); }
   ;

stat:
      /* empty */
   |
      IDENT ASSIGNSY expr   { printf("doing: ASSIGN\n"); }
   |
      WHILESY expr DOSY stats ENDSY  { printf("doing: WHILE\n"); }
   |
      IFSY expr THENSY stats ENDSY { printf("doing: IF THEN\n"); }
   |
      IFSY expr THENSY stats ELSESY stats ENDSY { printf("doing: IF THEN ELSE\n"); }
   |
      READSY '(' IDENT ')'  { printf("doing: READ\n"); }
   |
      WRITESY '(' expr ')'    { printf("doing: WRITE\n"); }
   |
      error { fatal("error in statement",""); }
   ;
   
expr:
      expr '+' expr   { printf("doing: + \n"); }
   |
      expr '*' expr   { printf("doing: * \n"); }
   |
      expr '-' expr     { printf("doing: - \n"); }
   |
      '(' expr ')'   { printf("doing: (e) \n"); }
   |
      IDENT        { printf("doing: IDENT \n"); }
   |
      NUMBER       { printf("doing: NUMBER \n"); }
   |
      expr '<' expr        { printf("doing: < \n"); }
   |
      expr '>' expr        { printf("doing: > \n"); }
   |
      expr '=' expr          { printf("doing: = \n"); }
   |
      expr '#' expr      { printf("doing: # \n"); }
   |
      error
         { fatal("error in expression",""); }
   ;

type:
      IDENT      { printf("doing: TYPE \n"); }
   ;
   
%%

int fatalerror=0;

int fatal(char *s){
    fatalerror++;
      fprintf(stderr,"%s\n",s);
}
int yyerror(char *s){
      fprintf(stderr,"%s\n",s);
}

int main() {
    printf("starting...\n");
    yyparse();
}
--------------------------------------------------------------------------
Lexical analyser lex.l file

%{
#include "syn.tab.h"
%}

DIGIT    [0-9]
ID       [a-zA-Z][a-zA-Z0-9]*

%%
[ \t\n]+    /* eat up whitespace */


{DIGIT}+    {  yylval = atoi(yytext);
               return NUMBER;
            }
begin       { return BEGINSY; }
do          { return DOSY; }
end         { return ENDSY; }
program     { return PROGSY; }
if          { return IFSY; }
while       { return WHILESY; }
then        { return THENSY; }
else        { return ELSESY; }
var         { return VARSY; }
const       { return CONSTSY; }
write       { return WRITESY; }
read        { return READSY; }


{ID}        { return IDENT; }
":="        { return ASSIGNSY; }

"+"|"-"|"*"|"/"   { return yytext[0]; }
"."|"("|")"|";"   { return yytext[0]; }
"="|"#"|"<"|">"   { return yytext[0]; }
":"               { return yytext[0]; }

.           printf( "Unrecognized character: %s\n", yytext );
%%



Avatar of ecw
ecw

ifexp: IFSY expr THENSY stats ENDSY

     ;

optionalelse: /* empty */
     | ELSIFSY stat
ASKER CERTIFIED SOLUTION
Avatar of ecw
ecw

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial