How to create top-down "tree" construction using bison?

853 views Asked by At

I've found this example, but it creates tree bottoms-up. Is it possible to create tree topdown using bison, flex?

Pseudocode:

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)); }
3

There are 3 answers

1
Chris Dodd On BEST ANSWER

You can do pretty much exactly what you describe with btyacc. You can write:

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

You can do the same thing in bison, but you have to use embedded actions with explicit type tags:

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); }
0
waTeim On

So like in your example does yacc/bison have a way to parametrize the nonterminals in the productions thereby equating it to a call to a generated function?

That would be a no; here's reference for the syntax.

Keep in mind that yacc/bison generates shift-reduce parsers not recursive descent ones. If you want to do something like that, a recursive descent generator would be more likely to allow it. Here's a list of them.

1
user207421 On

No. A yacc/bison parser is an LALR(1) parser. These are bottom-up parsers.

I don't see why you care.