Flex/Lex-如何知道是否声明了变量 [英] Flex/Lex - How to know if a variable was declared

查看:96
本文介绍了Flex/Lex-如何知道是否声明了变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的语法允许:

C→id:= E//将值/表达式分配给变量(VAR)

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

C→print(id)//打印变量(VAR)值

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

要完成它,我的lex文件是:

To get it done, my lex file is:

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

get_var_index返回列表中变量的索引,如果不存在则创建一个. 它正在工作!

get_var_index returns the index of the variable in the list, if it does not exist then it creates one. It is working!

问题是:

  • 每次在lex文件上匹配一个变量时,它都会为该变量创建一个索引.
  • 我必须报告是否调用了'print(a)'且未声明'a',并且这将永远不会发生,因为print(a)始终会创建指向'a'的索引.*

我该如何解决?

yacc文件的部分

   %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];}

推荐答案

这似乎有点像我们要做的计算机科学课作业.

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

通常,人们不会以这种方式使用bison/yacc.一个人将用bison/yacc进行解析,并创建一个解析树,然后解析树以执行语义检查,例如在使用前检查声明等.标识符通常将在符号表中进行管理,而不只是在值表中进行管理以使其他属性(例如, declared )得以管理.由于这些原因,它看起来像是对工具的练习而不是实际的应用.好的;那些免责声明已被处理,让我们得到答案.

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.

可以通过记住已声明的内容和未声明的内容来解决问题.如果不打算使用完整的符号表,则可以使用一个简单的 booleans 数组来指示哪些是有效值.可以将数组初始化为 false ,并在声明时将其设置为 true .使用变量时可以检查该值.由于 C 将整数用于 boolean ,因此我们可以使用它.唯一需要的更改是在野牛/yacc中.您省略了声明的任何语法,但是正如您指出的那样,必须声明一些语法.我猜到了.

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 */}

这篇关于Flex/Lex-如何知道是否声明了变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆