1

yacc / bison文法では、ルールの途中のアクション内からルールを完全に破棄する方法がありますが、エラー(およびyyerrorの呼び出し)がないため、他のオプションは引き続き有効です(「拒否」と同様)フレックス)?

'num'が整数値であると仮定すると、次のルールは偶数と奇数のプロダクションに対して異なる構文を定義します

rule :   num { if (($1 & 1) == 1) reject; } a b c 
       | num { if (($1 & 1) == 0) reject; } d e ;

どうも

4

2 に答える 2

2

Yaccは、flexとは異なり、バックトラックを実行しないため、実行時に他のオプションはありません。実行中のルールが正しいか、エラーが発生します。マクロを使用しYYREJECTてパーサーを完全に終了する(から1を返すyyparse)ことができますが、それはおそらくあなたが望むものではありません。

btyacc (バックトラッキングをサポート)を使用する場合YYERRORは、暫定的なアクションを呼び出すことで、やりたいことができます。これにより、バックトラックして別の代替案が試行され、代替案がない場合にのみ実際に構文エラーが発生します。

于 2012-05-15T17:49:32.217 に答える
1

中間ルールアクションを使用して、トークンを解析スタックにプッシュできます。その後、別のルールで評価できます。これにより、解析の結果に関してプログラムで選択できるようになります。

http://www.gnu.org/software/bison/manual/html_node/Mid_002dRule-Actions.html

ルールの途中のアクション自体は、ルールのコンポーネントの1つとしてカウントされます。これは、同じルールの後半に別のアクションがある場合(通常は最後に別のアクションがある場合)に違いがあります。$ nで使用するnの数を計算するときに、シンボルとともにアクションをカウントする必要があります。

ミッドルールアクションは、セマンティック値を持つこともできます。アクションは$$に割り当てて値を設定でき、ルールの後半のアクションは$nを使用して値を参照できます。アクションに名前を付ける記号がないため、値のデータ型を事前に宣言する方法がありません。したがって、参照するたびに「$<...>n」構文を使用してデータ型を指定する必要があります。この値。

したがって、そうすることは可能かもしれませんが、フレックスの場合とまったく同じ方法ではありません。あなたが本質的にしていることは文法の文脈自由な性質を破壊することなので、そうすることはおそらく少しハックです。

于 2012-05-15T13:53:34.623 に答える