且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

哪里可以释放Bison/Flex中的内存?

更新时间:2021-07-28 20:58:16

一旦不再需要复制的字符串,则需要释放它.在您相当简单的情况下,您可以在将它打印出来后释放($ 1),但通常情况是解析器将复制的字符串插入某些数据结构中,在这种情况下,数据结构成为malloc存储的所有者,并且免费电话将在析构函数中执行.

You need to free the copied string once you no longer need it. In your rather simple case you could free($1) after printing it out, but it is often the case that the parser inserts the copied string into some datastructure, in which case that datastructure becomes the owner of the malloc'd storage, and the call to free will be performed in a destructor.

与其他任何资源管理问题并没有真正的不同;您需要始终清楚谁是分配资源的所有者,因为所有者有责任在不再需要时释放资源.

It's not really different from any other resource management issue; you need to always be clear who is the owner of an allocated resource because the owner has the responsibility for releasing the resource when it is no longer needed.

内部发生的情况是bison维护了一个语义值堆栈,每个语义值都具有类型YYSTYPE(即语义类型"),也就是yylval的类型.当令牌移到堆栈上时,bisonyylval复制到堆栈顶部.在执行与产品对应的动作之前,bison将产品中每个终端和非终端的语义值安排为$1$2等.(这不是副本; $x符号将替换为对bison堆栈上某个位置的引用.)

What's going on internally is that bison maintains a stack of semantic values, each of which has the type YYSTYPE (i.e. "semantic type"), which is also the type of yylval. When a token is shifted onto the stack, bison copies yylval onto the top of the stack. Before executing an action corresponding to a production, bison arranges for the semantic values of each terminal and non-terminal in the production to be known as $1, $2, etc. (This is not a copy; the various $x symbols are replaced with a reference to a location on the bison stack.)

非终端也具有语义值,因为每个动作都会将值存储到伪变量$$中. (如果操作不执行此操作,则$$的值是不可预测的,但它仍然存在.)操作完成后,bison从堆栈顶部删除了$1$2 ...值,然后将伪变量$$复制到堆栈的顶部.它不会对弹出的值做任何事情,因此,如果需要释放或破坏它们,则操作必须自己执行.

Non-terminals also have semantic values, because each action stores a value into the pseudo-variable $$. (If the action doesn't do this, the value of $$ is unpredictable, but it still exists.) After the action finishes, bison removes the $1, $2... values from the top of the stack, and then copies the pseudo-variable $$ onto the top of the stack. It does not do anything to the values which were popped, so if they need to be freed or otherwise destructed, the action must do this itself.

因为语义值是天真的复制的,所以语义类型不应包含任何不能轻易复制的C ++对象.

Because semantic values are copied naively, the semantic type should not contain any C++ object which is not trivially copyable.

如果使用%union声明,则语义类型YYSTYPEunion对象,并且您需要告诉bison哪个联合标记适用于每个终端和非终端.在这种情况下,$$和所有$n会自动附加正确的.tag,并且操作在某种程度上更安全​​.

If you use the %union declaration, then the semantic type YYSTYPE is a union object, and you need to tell bison which union tag applies to each terminal and non-terminal. In that case, $$ and all the $n have the correct .tag appended to them automatically, and the actions become somewhat more type-safe.