I was doing my project for my compilers lessons, I finally finished it and it compilers but I keep getting a syntax error, and I don't know why! I tried using differences sources to see what I can find but nothing really helped. I even tried ChatGPT, so I came here to ask for advice and see what I am doing wrong from people that might know.
lab1.fl
%{
#include "lab1.tab.h"
int line = 1; //what line are we on in the code
char filename[20];
int comment = 0;
int yywrap(void) {
return 1;
}
%}
ID [a-zA-Z_][a-zA-Z0-9_]*
NUM [0-9]+
%%
"\n" {return 0;}
"//"(.)*"\n" {}
"/*" { comment=1; printf("multiline comment\n");}
"*/" {comment=0;}
"int" { if (!comment) return INT; }
"void" { if (!comment) return VOID; }
"if" { if (!comment) return IF; }
"else" { if (!comment) return ELSE; }
"while" { if (!comment) return WHILE; }
"return" { if (!comment) return RETURN; }
{ID} { yylval.strval = strdup(yytext); if (!comment) return ID; }
{NUM} { if (!comment) return NUM; }
"==" { if (!comment) return EQ; }
"!=" { if (!comment) return NE; }
"<=" { if (!comment) return LE; }
">=" { if (!comment) return GE; }
"<" { if (!comment) return LT; }
">" { if (!comment) return GT; }
"+" { if (!comment) return ADD; }
"-" { if (!comment) return SUB; }
"*" { if (!comment) return MUL; }
"/" { if (!comment) return DIV; }
"(" { if (!comment) return LPAREN; }
")" { if (!comment) return RPAREN; }
"[" { if (!comment) return LBRACKET; }
"]" { if (!comment) return RBRACKET; }
"{" { if (!comment) return LBRACE; }
"}" { if (!comment) return RBRACE; }
"," { if (!comment) return COMMA; }
";" { if (!comment) return SEMICOLON; }
"=" { if (!comment) return ASSIGN; }
[\t| \r | \f | \v] {}
<<EOF>> {return 0;}
%%
int main (int argc, char *argv[]){
if (argc==2)
yyin = fopen(argv[1], "rt");
else
{
printf("No file-Exit\n");
exit(1);
}
strcpy(filename,argv[1]);
yylex();
yyparse();
fclose(yyin);
}
lab1.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex();
void yyerror(char *s);
#define YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_TRIVIAL 1
typedef struct {
int numval; // For NUM
char *strval; // For ID
} YYSTYPE;
#include "lab1.tab.h"
%}
%token INT VOID IF ELSE WHILE RETURN
%token <strval> ID
%token <numval> NUM
%token EQ NE LT LE GT GE ADD SUB MUL DIV
%token LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE COMMA SEMICOLON ASSIGN
%union {
char *strval; // Define the type of the semantic value
}
%type <strval> type_specifier
%type <strval> var
%type <strval> call
%type <strval> args
%type <strval> arg_list
%nonassoc LOWER_THAN_ELSE
%left ADD SUB
%left MUL DIV
%nonassoc EQ NE
%nonassoc LT LE GT GE
%start program
%%
program: {printf("Program \n declaration_list\n");} declaration_list
declaration_list: declaration_list declaration {printf("declaration_list\n");}
| declaration {printf("declaration ");}
;
declaration: var_declaration {printf("var declaration\n");}
| fun_declaration {printf("fun declaration\n");}
var_declaration: type_specifier ID SEMICOLON {printf("variable_declaration(INT)");}
| type_specifier ID ASSIGN NUM SEMICOLON {printf("type_specifier(INT)\n"); printf("variable_declaration\n");}
type_specifier: INT {printf("type_specifier(INT)\n");}
| VOID {printf("type_specifier(VOID)\n");}
fun_declaration: type_specifier ID LPAREN params RPAREN compound_stmt {printf("fun_definition");}
params: param_list
| VOID {printf("params(VOID)\n");}
param_list: param_list COMMA param {printf("tparams list\n");} |
param {printf("params list");}
param: type_specifier ID {printf("params(%s)\n",$2);} | type_specifier ID LBRACE RBRACE {printf("params{$s [])\n",$2);}
compound_stmt: LPAREN local_declarations statement_list RPAREN {printf("compound_stmt\n");}
local_declarations: local_declarations var_declaration {printf("local declaration\n");} | /* empty */
statement_list: statement_list statement {printf("statement list\n");} | /* empty */
statement: expression_stmt {printf("expression statement\n");}
| compound_stmt {printf("compound statement\n");}
| selection_stmt {printf("selection statement\n");}
| iteration_stmt {printf("iteration statement\n");}
| return_stmt {printf("return statement\n");}
expression_stmt: expression SEMICOLON | SEMICOLON
selection_stmt: IF LPAREN expression RPAREN statement %prec LOWER_THAN_ELSE | IF LPAREN expression RPAREN statement ELSE statement
iteration_stmt: WHILE LPAREN expression RPAREN statement
return_stmt: RETURN SEMICOLON | RETURN expression SEMICOLON
expression: var ASSIGN expression {printf("expression \n");}| simple_expression {printf("simple expression\n");}
var: ID {printf("var(%s)\n",$1);} | ID expression {printf("var(%s)\n",$1);}
simple_expression: additive_expression relop additive_expression {printf("additive expression\n");} | additive_expression {printf("additive expression\n");}
relop: EQ | NE | LE | GE | LT | GT
additive_expression: additive_expression addop term | term
addop: ADD | SUB
term: term mulop factor {printf("term\n");} | factor {printf("term\n");}
mulop: MUL | DIV
factor: var | call | NUM
call: ID LPAREN args RPAREN
args: arg_list {printf("args list\n");} | /* empty */ {$$ = NULL;}
arg_list: arg_list COMMA expression | expression {$$ = NULL;} | /* empty */ {$$ = NULL;}
%%
void yyerror(char *s) {
printf("%s",s);
}
I use an input.txt file to run the program but even a blank program doesn't work
even if I only insert a int a;
for example into it, still nothing
I was expecting a syntax tree from my program but I only get the declaration_list and everything else doesn't work and I get a syntax error.
EDIT: I found the issue being that it doesn't return the tokens to the parser for some reason, I am still trying to figure out the issue, if anyone can help!
I finally figured out the issue with the tokens, I was using both yylex() and yyparse() but I found out that the parser also does yylex by itself so I removed it and it finally worked.