我的问题基本上是“什么是YACC /Bison的良好风格?”与此相关的是,不管我是否让野牛做它擅长的事情。
例如,我发现我的Bison程序比我的原始代码更依赖全局。请考虑以下几点:
prog :
vents{ /*handle semantics...*/ }
unity{ /*handle semantics...*/ }
defs;如果我想在“通风口”和“统一”之后的两个以大括号分隔的块之间传递信息,我认为从信息隐藏的角度来看,使用全局变量(从技术上讲,是一个具有文件级作用域和内部链接的变量)是我所能做的最好的事情。我在这些块中声明的任何变量都是其块的本地变量(我认为.),而我可以放置C++声明的其他指定位置会导致文件级别的作用域。
如果我能够将一个变量声明注入到"yyparse()“函数中,这将更符合我的需要。这类代码是否有钩子,或者注入这样一个变量的其他方法?或者全球只是使用Bison的一个公认的部分?
我也意识到,也许我甚至不想以这种方式在这些部分之间传递信息。但是仅仅使用$$、$1、$2等就可以把所有的东西都传递出去,这对我来说似乎很困难。我只是没有“得到”吗?
我发现我的一个全局变量特别值得怀疑,即使我接受其中的其他变量。它是std::堆栈类型,与输入语言对条件词的支持有关。
当我在编译器输入中遇到一个条件(“if/ text”)时,最终会产生三个汇编语言标签,其中包含一个文本字符串,后面跟着从序列中提取的一个数字。
因此,当我第一次遇到"if“时,我会获得一个序列号,将它推到堆栈上(因为"if”结构可以嵌套),然后使用它(通过“窥视”或"pops")来构造必要的标签和跳转,例如在我的条件、我的"if“块和我的"else”块之后。
我试着使用$-2这样的方法来完成这项工作,但是发现这个标识符不是与我的条件开头有关,而是与刚刚编译的任何块的末尾有关。由$抽象的系统似乎与从左到右读取的代码有关,没有任何概念说明内部的结构是如何嵌套的。
我不指望你们都能帮我.但是,我是否至少在正确的道路上尝试使用$$,$1,$-1,等等?很有可能我放弃得太早了,而且/或我会受益于采取一个干净的工作表方法,即扔掉我的旧的临时代码。
是这样吗?或者我用它的std:堆栈和它的全局集合的方法还好吗?
发布于 2012-02-17 02:11:56
中级规则可以在堆栈上推送一个值。
如果你有
rule
: A B { ... } C野牛会自动把它转换成
some_identifier
: /* empty */ { ... }
rule
: A B some_identifier C而且它的值也同样可以被访问。在这种情况下,中间规则语义操作在Bison堆栈上存储了一个值,然后在同一条规则中再次访问。
通常,这些函数是递归的。考虑下面的简单片段
// C++
class Statement { public: virtual ~Statement() {} };
class Expression : public Statement {};
class IfStatement : public Statement { Statement* if_true; Expression* condition; }
// Bison
%type if_statement if_stmt
%type statement stmt
%union {
IfStatement* if_stmt;
Statement* stmt;
}
if_statement
: if { $$ = new IfStatement(); }
'(' expression { $2->condition = $4; }
')' statement { $2->if_true = $7; $$ = $2; }
statement
: if_statement { $$ = $1; }
| ...不需要外部堆栈来执行这样的递归功能。
https://stackoverflow.com/questions/9321815
复制相似问题