質問
シフト/リデュースエラーを回避しています。ついに、自分の試合に出会ったと思います。
Int[] a
a[0] = 1
問題は、int []が次のように定義されていることです
Type OptSquareBrackets
a [0]は次のように定義されています
Var | Var '[' expr ']'
VarとTypeの両方は、有効な変数 [a-zA-Z] [a-zA-Z0-9 _]
であるVARとして定義されます。ダミートークン( ** Decl ** Type OptSquareBrackets
など)の追加とは別に、競合を起こさないようにこれを記述する方法はありますか?この1つのルールから、1つのshift / reduceと1つのreduce / reduce警告が表示されます。
解決
新しいトークンを定義できますか
VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[
したがって、宣言を定義
Type | VarLBracket ']';
そして割り当て対象を次のように定義します
Var | VarLBracket expr ']';
他のヒント
[]が宣言でのみ使用され、他のすべての場所で[var]が使用されるため、[]でLexルールを作成します
技術的には、この問題は、文法を実際に構文に違いのないセマンティックな意味に結び付けようとすることに起因します。
ISTMでは、型と式の両方を記述する単一の文法構成が必要です。特に実際には構文上の違いがない場合は、文法ではなくコードで区別してください。 Yaccはコンパイラジェネレーターと呼ばれますが、それは少なくとも真実ではありません。パーサーを作成するだけです。
とは言っても、 []
を終端記号として認識することは、問題を解決して物事を進める簡単な方法かもしれません。 Yaccは曖昧な文法が得意ではないため、どのパスに従うかを早期に決定する必要があります。
所属していません StackOverflow