Flex / Lex - how to know if a variable has been specified

My grammar allows:

C -> id: = E // assign value / expression to variable (VAR)

C β†’ print (id) // values ​​of print variables (VAR)

To do this, my lex file:

[a-z]{
    yylval.var_index=get_var_index(yytext);
    return VAR;
}

      

get_var_index returns the index of the variable in the list, if it doesn't exist it creates one. He works!

Problem :

  • Each time a variable is mapped in a lex file, it creates an index for that variable.
  • I have to report if 'print (a)' is called and 'a' was not declared, and this will never happen, as print (a) always creates an index in 'a'. *

How can I solve it?

Part of the yacc file:

   %union {
int     int_val;
int var_index;
} 
%token <int_val>   INTEGER
%token <var_index>   VAR
...
| PRINT '(' VAR ')'{
 n_lines++;
printf("%d\n",values[$3]);
}
...
| VAR {$$ =values[$1];}

      

+3


source to share


1 answer


This is similar to the Computer Science class homework question for us.

You should generally not use bison / yacc this way. It would be possible to parse with bison / yacc and create a parse tree that would then go through to perform semantic checks like checking a declaration before use, etc. Identifiers are usually managed in a symbol table rather than just a value table to include other attributes such as those declared for control. For these reasons, it looks like an exercise rather than a realistic use of tools. OK; those disclaimers let you get an answer.



The problem will be solved by remembering what was announced and what was not. If you do not plan on using the complete symbol table, then a simple boolean array can be used to indicate which values ​​are valid. The array can be initialized to false and set to true when declared. This value can be checked by using a variable. Since C uses int for boolean, we can use that. The only changes needed are bison / yacc. You missed any syntax for declarations, but as you pointed out, they are declared, there must be some. I guessed.

%union {
int     int_val;
int var_index;
} 
int [MAX_TABLE_SIZE] declared; /* initialize to zero before starting parse */
%token <int_val>   INTEGER
%token <var_index>   VAR
...
| DECLARE '(' VAR ')' { n_lines++; declared[$3] = 1; }
...
| PRINT '(' VAR ')'{
 n_lines++;
if (declared[$3]) printf("%d\n",values[$3]);
else printf("Variable undeclared\n");
}
...
| VAR {$$ =value[$1]; /* perhaps need to show more syntax to show how VAR used */}

      

+1


source







All Articles