I am trying to generate intermediate code of the following grammar for while loop and general statements, but I keep encountering syntax error. Though earlier, the grammar for statements and expressions worked, but after adding the production for while loop this program doesn't work.
this is my lex.l file
%{
#include "y.tab.h"
%}
NUMBER [0-9]
ALPHABET [a-zA-Z]
%%
[\t];
{NUMBER}+ { strcpy(yylval.str, yytext); return ID; }
{ALPHABET} { strcpy(yylval.str, yytext); return ID; }
"while" { return WHILE; }
"do" { return DO; }
"<" { yylval.symbol=yytext[0]; return OP; }
">" { yylval.symbol=yytext[0]; return OP; }
"!=" { yylval.symbol=yytext[0]; return OP; }
"==" { yylval.symbol=yytext[0]; return OP; }
[\n];
. { return yytext[0]; }
%%
And this is my yacc.y file
%{
#include <stdio.h>
#include <string.h>
char result_gen();
char quadruple_entry(char a[], char b, char c[]);
char quadruple_entry_assign(char a[], char b, char c[]);
char quadruple_entry_loop();
char quadruple_entry_do();
void three_address_code();
int q_index = 0;
char result[3] = {'t','0','\0'};
char result2[3] = {'L','0','\0'};
char temp[3];
char temp2[3];
struct QuadrupleStructure {
char arg1[10];
char op;
char arg2[10];
char rslt[3];
}quadruple[25];
%}
%union {
char str[10];
char symbol;
}
%token WHILE DO
%token <str> ID
%token <symbol> OP
%type <str> expr
%right '='
%left '+' '-'
%left '/' '*'
%%
wstmt : WHILE { quadruple_entry_loop(); } stmt DO { quadruple_entry_do(); }
;
stmt : ID '=' expr { quadruple_entry_assign($1, '=', $3); }
| ID OP ID { quadruple_entry($1,$2,$3); }
;
expr : expr '+' expr { quadruple_entry($1, '+', $3); strcpy($$,temp); }
| expr '-' expr { quadruple_entry($1, '-', $3); strcpy($$,temp); }
| expr '/' expr { quadruple_entry($1, '/', $3); strcpy($$,temp); }
| expr '*' expr { quadruple_entry($1, '*', $3); strcpy($$,temp); }
| '(' expr ')' { strcpy($$,$2); }
| ID { strcpy($$,$1); }
;
%%
char result_gen() {
strcpy(temp,result);
result[1]++;
}
char quadruple_entry(char a[], char b, char c[]) {
result_gen();
strcpy(quadruple[q_index].arg1, a);
quadruple[q_index].op = b;
strcpy(quadruple[q_index].arg2, c);
strcpy(quadruple[q_index].rslt, temp);
q_index++;
}
char quadruple_entry_assign(char a[], char b, char c[]) {
char tempLocal[3] = {' ',' ','\0'};
strcpy(quadruple[q_index].arg1, a);
quadruple[q_index].op = b;
strcpy(quadruple[q_index].arg2, c);
strcpy(quadruple[q_index].rslt, tempLocal);
q_index++;
}
char quadruple_entry_loop() {
char tempLocal[3];
strcpy(tempLocal, result2);
char tempLocal2[] = " if ";
char tempLocal3 = ' ';
char tempLocal4[] = " ";
strcpy(quadruple[q_index].rslt, tempLocal);
strcpy(quadruple[q_index].arg1, tempLocal4);
quadruple[q_index].op = tempLocal3;
strcpy(quadruple[q_index].arg2, tempLocal2);
q_index++;
}
char quadruple_entry_do() {
char tempLocal[4];
strcpy(tempLocal, result2);
tempLocal[3] = ':';
strcpy(quadruple[q_index].arg1,tempLocal);
char tempLocal2[] = " ";
char tempLocal3 = ' ';
quadruple[q_index].op = tempLocal3;
strcpy(quadruple[q_index].arg2, tempLocal2);
q_index++;
result2[1]++;
char tempLocal4[4];
strcpy(tempLocal4, result2);
tempLocal4[3] = ':';
strcpy(quadruple[q_index].arg1,tempLocal4);
char tempLocal5[] = " ";
char tempLocal6 = ' ';
quadruple[q_index].op = tempLocal6;
strcpy(quadruple[q_index].arg2, tempLocal5);
q_index++;
result2[1]++;
}
void three_address_code() {
int i;
for(i=0 ; i<q_index ; i++)
printf("\n%s := %s %c %s", quadruple[i].rslt, quadruple[i].arg1, quadruple[i].op, quadruple[i].arg2);
}
void yyerror(char *s){
printf("Errror %s",s);
}
int yywrap() {
return 1;
}
int main() {
yyparse();
three_address_code();
return 0;
}
Input:
i=2*5-10
while i<5 do
Output:
Errror syntax error
If someone can figure out where the grammar is wrong, or if my code is wrong, it'd be very helpful.
Your start symbol is wstmt
, so the program accepts a single while statement as an input. If you need to accept a sequence of statements, you need a symbol that expands into a sequence of statements as your starting symbol.
In addition, your lexer doesn't swallow spaces, so any program that has spaces has an error.