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 );
%%
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 );
%%
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
;
optionalelse: /* empty */
| ELSIFSY stat