1

OK、これはちょっと変わった質問です。私がやっていることは、ラムダ計算式のパーサーを書くことです。したがって、式は次の 4 つのいずれかになります。

  • 変数
  • 絶え間ない
  • (表情表現)
  • (ラムダ変数.式)

ご覧のとおり、最後の 2 つの式には式が含まれています。私がやろうとしていたのは、それがどのタイプであるかを報告できるように、全体的な式を決定することでした. たとえば、式 ((lambda x.(f1 x)) 100) は全体として組み合わせです。私の考えは、ファイルの終わりに達したときに flex から END トークンを返すことでした。私のコードは次のようになります。

overallexpr: combo END { printf(" The overall expression is a combination\n"); } |
         constant END { printf(" The overall expression is a constant\n"); } |
         VARIABLE END { printf(" The overall expression is a variable\n"); } |
         l_expr END { printf(" The overall expression is a lambda expression\n"); }
;

expr: combo | constant | VARIABLE | l_expr
;

combo: LPARENS expr expr RPARENS
;

constant: FUNCTION | NUMBER
;

l_expr: LPARENS LAMBDA VARIABLE DOT expr RPARENS
;

その END トークンを、単純なコンボではなくコンボ END のように全体的な式の 4 つの可能性の後に配置すると、機能しません。しかし、END トークンはパーサーによって受信されます。各トークンを読み取ったときに (変数、関数、および数値を使用して) 印刷すると、次のようになります。

LPARENS  LPARENS  LAMBDA  VARIABLE x  DOT  LPARENS  FUNCTION f1  VARIABLE x  RPARENS  RPARENS  NUMBER 100  RPARENS  END Sorry, Charlie

わかりにくいかもしれませんが、これでうまくいくはずです。組み合わせは RPARENS で終了し、その直後に END トークンがあります。しかし、それは全体的な表現として評価されません。ただし、ENDトークンを取り出すと、毎回機能するようです。全体的なexprとexprの生成はまったく同じですが、常に全体的なメッセージが出力されます。出力は、END トークンの前に「全体的な式は組み合わせです」と表示されていることを除いて、最後のものと同じです。だから私の質問はなぜですか?bison は常に最初に初期の作品を試すだけですか? また、END がなくても機能するのに、END がないと機能しないのはなぜですか? 特に、組み合わせだと言った直後に END トークンが表示されるためです。私は、Bison がどのように機能するかをよりよく理解しようとしています。

4

1 に答える 1

1

あなたのコードを見ずにここで何が起こっているのかを伝えるのは少し難しいです (とにかく、私は本当にそれを通り抜けたくありません)、私は推測を危険にさらします: 私の推測では、あなたは標準の yylex EOF を置き換えているということですEND トークンを使用して指示します (つまり、0 を返します)。Bison パーサーが EOF を認識しない場合、解析は完了しません。

事実上、bison は独自の特別な作品を作成します。

__parse__: __start__ $;

parseは(実際には名前のない)プロダクションであり、__start__宣言したものです%start(または明示的に宣言しない場合は最初の非ターミナル)。あなたの場合、私はそれだと思いますoverallexpr$EOFマークを示すために従来から使用されている記号です。

では、bison パーサーのアクションはいつ発生するのでしょうか。場合によっては、発生すると思われる場所 (つまり、プロダクションの最後のトークンの直後) で発生する可能性がありますが、通常は、パーサーが次のトークンを覗くまで発生しません。それは許されています。それがパーサーと呼ばれる理由ですLALR(1)。パーサー1は、既に取得したものをどうするかを正確に決定する前に、見ることができる将来のトークンの数です。ほとんどの場合、この情報が必要であり、あなたや私にはそうではないように見えても、多くの場合、そうであるかのように機能します。

したがって、パーサーは、ファイルの終わりマーカーが次のトークンであることを確信するまで、実際にはoverallexprリダクションを実行しません。つまり、ルールに関連付けられたアクションを実行しません。overallexpr.

ここで、ENDトークンをルールから除外し、レクサーが実際に EOF を返した場合、bison は EOF を確認したときにリダクションを行います。

于 2012-11-02T06:13:13.863 に答える