1

私はシフト/リデュースエラーを遠ざけています。ついに私は自分の試合に出会ったと思います。

Int[] a
a[0] = 1

問題は、int[]が次のように定義されていることです。

Type OptSquareBrackets

一方、a[0]は次のように定義されます

Var | Var '[' expr ']'

VarとTypeはどちらも、有効な変数であるVARとして定義されています[a-zA-Z][a-zA-Z0-9_]。ダミートークン(**Decl** Type OptSquareBrackets代わりになど)を追加する以外に、競合が発生しないようにこれを書き込む方法はありますか?この1つのルールから、1つのシフト/削減と1つの削減/削減の警告が表示されます。

4

3 に答える 3

1

新しいトークンを定義していただけませんか

VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[

したがって、宣言を定義します

Type | VarLBracket ']';

割り当てターゲットを次のように定義します

Var | VarLBracket expr ']';
于 2009-12-01T01:04:19.033 に答える
1

技術的には、この問題は、文法を実際には構文が異ならない意味論に結び付けようとすることに起因します。

型と式の両方を記述する単一の文法構造が必要なだけのISTM。特に構文上の違いが実際にない場合は、文法ではなくコードで区別してください。Yaccはコンパイラジェネレータと呼ばれますが、それは少なくとも少し真実ではありません。パーサーを作成するだけです。

そうは言っても、終端記号として認識[]することは、問題を解決して問題を解決するためのより簡単な方法かもしれません。Yaccはあいまいな文法があまり得意ではないため、どのパスをたどるかを早期に決定する必要があります。

于 2009-12-01T21:01:39.143 に答える
1

[]は宣言でのみ使用され、他のすべての場所では[var]が使用されるため、[]を使用してLexルールを作成します。

于 2009-12-02T00:48:28.020 に答える