1

次のBisonファイルがあります-

%union
{
    int integer_value;
    double double_value;
    char* string_value;
}

%token <integer_value> INTEGER
%token <string_value> VAR
%token <string_value> INTEGER_DECLARATION
%token <double_value> DOUBLE
%token <string_value> DOUBLE_DECLARATION


%%

program:
        program statement '\n'
        |
        ;

statement:
        | INTEGER_DECLARATION VAR '=' INTEGER {//implementation} 

        | INTEGER_DECLARATION VAR '='  DOUBLE {//implementation as above}                            

%%

INTEGER_DECLARATION VAR '=' INTEGERとの実装は同じなので、bwと文の構造で条件INTEGER_DECLARATION VAR '=' DOUBLEを作ることはできますか?ORINTEGERDOUBLE

試してみINTEGER_DECLARATION VAR '=' INTEGER|DOUBLEましたが、プロンプトが表示され warning: rule useless in parser due to conflicts: statement: DOUBLE、実際に参照DOUBLEは無視されました。

4

1 に答える 1

1

あなたが投稿したメインのコード スニペットは、可能な限り簡潔です。は、は のみで構成できるstatement: INTEGER_DECLARATION VAR '=' INTEGER|DOUBLEと言おうとしています。statementDOUBLE

あなたはこれを書くことができます:

program:
      program statement '\n'
    |
    ;

statement:
      decl_part INTEGER {//implementation uses info in $1} 
    | decl_part DOUBLE {//implementation as above}                            
    ;

decl_part:
      INTEGER_DECLARATION VAR '=' {//partial implementation passes some info via $$}
    ;

しかし、それがあなたがすでに持っているものを改善するかどうかは議論の余地があります.

または、次のように書くこともできます。

program:
      program statement '\n'
    |
    ;

statement:
      INTEGER_DECLARATION VAR '=' number
    ;

number:
      INTEGER
    | DOUBLE
    ;

この手法には、後で言語を拡張する場合 (たとえば、16 進定数をサポートする場合) に利点があります。

もう 1 つの注意: のプロダクションで最初の代替記号は必要ないと思いますstatement。あなたがそれを持っている方法は、両方ともprogramイプシロンstatement(空)になる可能性があり、これがパーサーの競合につながると私は信じています。

于 2012-12-04T14:54:15.847 に答える