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

これらの bison の解析規則は次のとおりです。

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に関数名を与える方法を教えてもらえますか? 私は運がなくても1時間以上試しています。

4

1 に答える 1

2

「パラメータの前に関数名を教えてください」とはどういう意味ですか? endfun現在、さまざまなパラメーター ルールの後にある関数ルールを確認して縮小するまで、関数名を出力しません。通常のテクニックは、terms ルールが関数ルールで使用できるもののリストを生成するようにすることです。

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 に答える