ほとんどの部分で機能する単純な文法がありますが、ある場所でエラーが報告され、バックトラッキングを使用して解決できるため、そうすべきではないと思います。
ここが問題の部分です。
command: object message_chain;
object: ID;
message_chain: unary_message_chain keyword_message?
| binary_message_chain keyword_message?
| keyword_message;
unary_message_chain: unary_message+;
binary_message_chain: binary_message+;
unary_message: ID;
binary_message: BINARY_OPERATOR object;
keyword_message: (ID ':' object)+;
これは単純化されたバージョンであり、オブジェクトはより複雑です (他のコマンドや生の値などの結果である可能性がありますが、その部分は正常に機能します)。問題はmessage_chain
、最初の選択肢にあります。入力のようなobj unary1 unary2
場合は正常に動作しますが、入力のような場合は単項メッセージとしてobj unary1 unary2 keyword1:obj2
一致しようとし、に達すると失敗します。この状況パーサーは、バックトラックして存在することを認識し、それがキーワード メッセージであることを認識すると思います。keyword1
:
:
キーワード メッセージを非オプションにすると正常に動作しますが、キーワード メッセージをオプションにする必要があります。
パーサーは、キーワード メッセージが 2 番目の選択肢 (binary_message) と 3 番目の選択肢 (keyword_message のみ) にある場合に検索します。したがって、次のようなものが良い結果をもたらします。1 + 2 + 3 Keyword1:Value
私は何が欠けていますか?バックトラッキングはオプションで true に設定されており、同じ文法の他のケースでは正常に機能します。
ありがとう。