0
votes

First of all I have to make it clear that I am a beginner regarding flex and bison programming.

I'm trying to write a code recognizing a particular declaration part. Its syntax and logic can be understood by the flex and bison code, I present below:

%{
#include <stdio.h>
%}
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}

The problem lies to compiling. When compiling on the terminal I get the following lines of errors:

enter image description here

What is going wrong with my code? How can I fix the errors?

I am looking forward to reading your answers!

1

1 Answers

2
votes

You have misread the instructions for using these tools!

Two different files are required, not one.

A file such as exercise4.l is the input to flex which defines the mapping from lexemes to tokens, and exercise4.y would be the input to bison which defines the order of the tokens in a grammar. To use the two tools together we have to combine the output of flex (in this case lex.yy.c with the bison grammar using the #include "lex.yy.x" directive; the tokens are declared with the %token declaration.)

Based on your example, we could re-factor this into two files:

exercise4.l:

%%
[ \t\n]+                { /* Ignore all whitespace */ }
var                     { return VAR; }
real                    { return REAL; }
boolean                 { return BOOLEAN; }
integer                 { return INTEGER; }
char                    { return CHAR; }
[a-zA-Z][a-zA-Z0-9_]*   { return VAR_NAME; }
.                       { return yytext[0]; }
%%

exercise4.y:

%{
#include <stdio.h>    
%}
%token VAR VAR_NAME REAL BOOLEAN INTEGER CHAR
%%
program : VAR typedecls ;
typedecls : typedecl | typedecls typedecl ;
typedecl : varlist ':' var_type ';' ;
varlist : VAR_NAME | varlist ',' VAR_NAME ;
var_type : REAL | BOOLEAN | INTEGER | CHAR ;
%%
main( argc, argv )
int argc;
char **argv;
{
extern FILE *yyin;
++argv, --argc; /* skip over program name */
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
/* yylex(); */
yyparse();
}
yyerror(char *s)  
{  
 printf("\nError\n");  
}
#include "lex.yy.c"

We can now combine these with the following command lines operations:

C:\Users\Brian>flex exercise4.l    
C:\Users\Brian>bison exercise4.y    
C:\Users\Brian>gcc -o exercise4.exe exercise4.tab.c -lfl

and test the resultant parser:

C:\Users\Brian>.\exercise4
var a:integer;
^Z