50

このファイルで Bison を実行します。

%{
    #include <iostream>
    int yylex();
    void yyerror(const char*);
%}


%union
{
    char    name[100];
    int     val;
}

%token NUM ID
%right '='
%left '+' '-'
%left '*'

%%

exp :   NUM     {$$.val = $1.val;}
    | ID        {$$.val = vars[$1.name];}
    | exp '+' exp   {$$.val = $1.val + $3.val;}
    | ID '=' exp    {$$.val = vars[$1.name] = $3.val;}
;

%%

次のような警告が表示されます。

警告: 'exp' の $$ には宣言された型がありません。

それはどういう意味ですか、どうすれば解決できますか?

4

2 に答える 2

48

定義された共用体 (%union) は、直接使用するためのものではありません。むしろ、共用体のどのメンバーがどの式で使用されているかを Bison に伝える必要があります。

これは%type ディレクティブで行います。

コードの修正バージョンは次のとおりです。

%{
    #include <iostream>
    int yylex();
    void yyerror(const char*);
%}


%union
{
    char    name[100];
    int     val;
}

%token NUM ID
%right '='
%left '+' '-'
%left '*'

%type<val> exp NUM
%type<name> ID

%%

exp :   NUM     {$$ = $1;}
    | ID        {$$ = vars[$1];}
    | exp '+' exp   {$$ = $1 + $3;}
    | ID '=' exp    {$$ = vars[$1] = $3;}
;

%%
于 2009-06-18T19:08:34.710 に答える
8

さらに考えてみると、削減をより明確にしたい場合(ASTアノテーションを実行している場合、これは便利です)、スタック値ポインターを作成してから、タイプ値を自分で処理できます。スカラー型とよく似ています。

struct myScalar {
    union {
        int num;
        char *id;
        char *float_lexeme;
    }payload;

    enum {
        TYPE_NUM,
        TYPE_IDENTIFIER,
        TYPE_FLOAT_CHAR
    } type;
    char *orig_lexeme;
};

そして、typedefとscalar_val *valスタック用を持っています。

より複雑なコンパイラフロントエンドに移行すると、このようなASTを構築するのに役立ちます。これにより、ツリーをトラバースするときに、より優れたメタデータが得られ、プレセマンティックタイプの変換で変換を拡張することもできます。次に、IDなどのリーフプロダクションに要約して、語彙素を適切なスカラーペイロードにシャッフルします。

完全な説明ではありませんが、あなたはその考えを理解します。

これが将来のBison/Lexフロントエンドに役立つことを願っています...

幸運を

于 2009-06-18T19:41:30.467 に答える