1
votes

I am writing a parser with flex and bison and so far have these tokens for flex:

[ \t\n] ;
(x[0-9]+)   {
    yylval.var = strdup(yytext);
    return VARIABLE;
}
~(x[0-9]+)  {
    yylval.var = strdup(yytext);
    return NEG_VARIABLE;
}
[a-zA-Z0-9]+ {
                yylval.name = strdup(yytext);
                return NAME;
            }
~[a-zA-Z0-9]+ {
                    yylval.name = strdup(yytext);
                    return NEG_NAME;
                }
[\{\},\(\)] { return yytext[0];}
. ;

and these parse rules for bison are:

fol:
        clauses {cout << "Done with file"<<endl;}
        ;
clauses:
        clauses clause
        | clause
        ;
clause:
        startc terms endc
        ;
startc:
        '{' {cout << "Bison found start of clause" << endl;}
        ;
endc:
        '}' {cout << "Bison found end of clause" << endl;}
        ;
function:
        NAME startfun endfun {cout << "Bison found a function " << $1 << endl;}
        |NEG_NAME startfun endfun {cout << "Bison found a negative function " << $1 << endl;}
        ;
startfun:
        '(' {cout << "Bison found start of params" << endl;}
        ;
endfun:
        terms ')' {cout << "Bison found a function end" << endl;}
        ;
terms:
        terms ',' term
        | term
        ;
term:
        VARIABLE {cout << "Bison found a variable "<< $1 << endl;}
        | NEG_VARIABLE {cout << "Bison found a negative variable " << $1 << endl;}
        | NAME {cout << "Bison found a constant " << $1 << endl;}
        |function
        ;

Now it all works great except that when it parses a function it first parses the parameters and parens and then gives me the function name at the end. I can work around this, but it makes my life harder since I am storing functions as disjoint sets and I would need to keep a list of the parameters until I can get the name of the function to create the root and then union them in instead of creating it directly.

Can anyone show me how to get Bison to give me the function name before the parameters? I have been trying for over an hour with no luck.

1

1 Answers

2
votes

What do you mean by "give me the function name before the parameters"? Currently you don't print the function name until after you see the endfun and reduce the function rule, which is after the various parameter rules. The usual technique is to have the terms rules produce a list of things that can then be used in the function rule:

terms:  terms ',' term { $$ = append_list($1, $3); }
     |  term { $$ = create_singleton_list($1); }
     ;

term:   VARIABLE { $$ = new VariableTerm($1); }

...

Alternately, if you just want to print things out, you can have a rule that is reduced as soon as you see a function name:

function: funcname startfun endfun {cout << "Bison ending a function " << $1 << endl;}
        ;

funcname: NAME { cout << "Starting a function " << ($$ = $1) << endl; }
        | NEGNAME { cout << "Starting a negative function " << ($$ = $1) << endl; }
        ;