Ironyを使用して小さなパーサーを作成しようとしています。残念ながら、「シフト削減の競合」が発生します。文法は私の得意分野ではなく、この 1 つの小さなことを完了するだけで済みます。エラーを生成する簡略化された文法は次のとおりです。
ExpressionTerm := "asd"
LogicalExpression :=
ExpressionTerm |
LogicalExpression "AND" LogicalExpression |
LogicalExpression "OR" LogicalExpression
「shift-reduce 競合」とは何を意味し、どうすれば解決できますか? それは私の文法があいまいであることを意味していると私は推測していますが、私は自分の論理を十分にひねってその方法を理解することはできません.
追加:明確にするために - 「asd」は単なるリテラル文字列「asd」です。したがって、次の式がこの文法によって解析されると予想されます。
asd
asd AND asd
asd AND asd OR asd
asd OR asd AND asd OR asd
追加 2:言い忘れましたが、文法の語根は ですLogicalExpression
。
追加 3:ああ、わかった! あいまいさは、
asd AND asd OR asd
次の 2 つの異なる方法で解釈できます。
(asd AND asd) OR asd
asd AND (asd OR asd)
しかし、どうすればこれを解決できますか?OK、AND または OR のどちらか一方を他方よりも強くすることができます (いずれにせよ意図していました)。しかし、オペレーターが 1 人しかいない場合でもエラーが表示されるようになりました。つまり、これも同じエラーを生成します。
LogicalExpression := "asd" | LogicalExpression "OR" LogicalExpression
この場合、私はこれが欲しい:
asd OR asd OR asd
これに解析されます:
(asd OR asd) OR asd
これを行うためのあいまいでない方法は何ですか?
追加 4:わかりました!
LogicalExpression1 := LogicalExpression1 "OR" LogicalExpression2 | LogicalExpression2
LogicalExpression2 := LogicalExpression2 "AND" LogicalExpression3 | LogicalExpression3
LogicalExpression3 := "NOT" LogicalExpression4 | LogicalExpression4
LogicalExpression4 := "asd" | "(" LogicalExpression1 ")"
これは、演算子の優先順位を NOT->AND->OR として、すべてのブール式を解析します。「asd」は、用語を意図した表現に置き換えることができます。