我找到了this example,但它创造了树的底部。是否可以使用bison创建树自上而下,flex?
伪代码:
block(parent):
{ current = new Block(); parent.addBlock(this); }
BLOCK_BEGIN_TOKEN block_content(current) BLOCK_END_TOKEN
;
block_content(parent)
: block_content(parent) statement(current)
| block_content(parent) block(current)
| statement(parent)
| block(parent)
;
statement(parent)
: STATEMENT_TOKEN { parent.addStatement(new Statement($1)); }
答案 0 :(得分:1)
因此,在你的例子中,yacc / bison是否有办法对制作中的非终结进行参数化,从而将其等同于对生成函数的调用?
那不是;这是reference for the syntax。
请记住,yacc / bison生成shift-reduce解析器而不是递归下降解析器。如果你想做类似的事情,递归下降生成器将更有可能允许它。这是一个list of them。
答案 1 :(得分:1)
您可以使用btyacc完全按照您的描述进行操作。你可以写:
%union {
Statement *stmt;
Block *blk;
}
%token BLOCK_BEGIN_TOKEN BLOCK_END_TOKEN
%token<stmt> STATEMENT_TOKEN
%type block(<blk>) block_content(<blk>) statement(<blk>)
%%
input: block(new Block())
;
block($parent):
BLOCK_BEGIN_TOKEN block_content(new_block($parent)) BLOCK_END_TOKEN
;
block_content($parent)
: block_content($parent) statement($parent)
| block_content($parent) block($parent)
| statement($parent)
| block($parent)
;
statement($parent)
: STATEMENT_TOKEN { $parent->addStatement($1); }
%%
Block *new_block(Block *parent) {
Block *b = new Block();
parent->addBlock(b);
return b;
}
你可以在野牛中做同样的事情,但是你必须使用带有显式类型标签的嵌入式动作:
block:
BLOCK_BEGIN_TOKEN { $<blk>$ = new_block($<blk>0); } block_content BLOCK_END_TOKEN
;
block_content
: block_content { $$=$0; } statement
| block_content { $$=$0; } block
| statement
| block
;
statement
: STATEMENT_TOKEN { $<blk>0->addStatement($1); }
答案 2 :(得分:-1)
没有。 yacc / bison解析器是LALR(1)解析器。这些是自下而上的解析器。
我不明白你为何关心。