yacc / bison行动的范围是什么?

时间:2011-02-23 22:18:17

标签: c parsing yacc bison lex

我正在尝试在flex / bison中编写一个(相对)简单的配置文件解析器。基本思想是我的bison语法使用一些C函数将解析后的数据组织成一系列C结构。如果有人认为有必要回答这个问题,我会很乐意发布我的代码,只需发表评论。

我遇到的问题涉及bison行动中的程序范围。例如,如果我有类似的东西:

set
          : NTOK name    {
                          section *sec
                          init_s(sec, $2);
                          add_s(cf, sec);
                         }

以后的语法规则中不应该sec可用吗?当我稍后再尝试将其作为参数时,我得到error: 'sec' undeclared。谁能开导我?

2 个答案:

答案 0 :(得分:4)

bison中的操作生成的所有代码都在其自己的范围内(IIRC,生成的代码将其包装在大括号中以强制执行此操作)。如果要使数据全局可用于其他操作,则需要在某处显式声明全局变量(可能位于flexbison脚本的顶部?),然后写入该变量。这背后的基本原理是,如果一个动作中的每个变量都是隐式全局的,或者至少可以被其他动作读取,那么当您打算创建新数据时,很容易意外地回收垃圾数据。

答案 1 :(得分:0)

通常通过将types分配给令牌和规则来解决此问题。您还可以将自己的parameters附加到解析器函数。

%union {
  char* name;
  section* sec;
}

%parse-param {whatever_type cf}

%token <name> name
%type <sec> set

%%

set      : NTOK name    {
                          init_s(&$$, $2);
                          add_s(cf, $$);
                         }
         ;

other_rule: set name {do_something_other($1 $2);}
          ;