Flex/Lex - How to know if a variable was declared

依然范特西╮ 提交于 2019-12-20 01:38:50

问题


My grammar allows:

C → id := E // assign a value/expression to a variable (VAR)

C → print(id) // print variables(VAR) values

To get it done, my lex file is:

[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 does not exist then it creates one. It is working!

The problem is:

  • Everytime a variable is matched on lex file it creates a index to that variable.
  • I have to report if 'print(a)' is called and 'a' was not declared, and that will never happen since print(a) always creates an index to 'a'.*

How can I solve it?

Piece of 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];}

回答1:


This does seem a bit like a Computer Science class homework question for us to do.

Normally one would not use bison/yacc in this way. One would do the parse with bison/yacc and make a parse tree which then gets walked to perform semantic checks, such as checking for declaration before use and so on. The identifiers would normally be managed in a symbol table, rather than just a table of values to enable other attributes, such as declared to be managed. It's for these reasons that it looks like an exercise rather than a realistic application of the tools. OK; those disclaimers disposed of, lets get to an answer.

The problem would be solved by remembering what has been declared and what not. If one does not plan to use a full symbol table then a simple array of booleans indicating which are the valid values could be used. The array can be initialised to false and set to true on declaration. This value can be checked when a variable is used. As C uses ints for boolean we can use that. The only changes needed are in the bison/yacc. You omitted any syntax for the declarations, but as you indicated 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 */}


来源:https://stackoverflow.com/questions/27284546/flex-lex-how-to-know-if-a-variable-was-declared

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!