BIson以错误的顺序解析函数和参数

时间:2012-04-17 15:31:10

标签: parsing bison

我正在编写一个包含flex和bison的解析器,到目前为止还有这些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];}
. ;

这些野牛的解析规则是:

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
        ;

现在一切都很好,除了当它解析一个函数时,它首先解析参数 和parens然后给我最后的功能名称。我可以解决这个问题,但是由于我将函数存储为不相交的集合,因此我的生活更加困难,我需要保留一个参数列表,直到我可以获取函数的名称来创建根,然后将它们联合起来直接创建它。

有人能告诉我如何让Bison在参数前给我一个函数名吗?我已经尝试了一个多小时而没有运气。

1 个答案:

答案 0 :(得分:2)

“在参数前给我功能名称”是什么意思?目前,在看到endfun并减少功能规则之前,不会打印功能名称,这是在各种参数规则之后。通常的技术是让术语规则生成一个事物列表,然后可以在函数规则中使用:

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

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

...

或者,如果您只想打印出来的东西,只要看到一个功能名称,就可以减少规则:

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