1

我正在编写一个带有 flex 和 bison 的解析器,到目前为止,这些标记用于 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
        ;

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

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

4

1 回答 1

2

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

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; }
        ;
于 2012-04-17T18:06:51.553 回答