簡単な文法があります。実際、私が使用している文法はもっと複雑ですが、これは私の質問を説明する最小のサブセットです。
Expr ::= Value Suffix
| "(" Expr ")" Suffix
Suffix ::= "->" Expr
| "<-" Expr
| Expr
| epsilon
Value
識別子、文字列、数字などに一致します。ルールは、Suffix
左再帰を排除するためにあります。これは、次のような式に一致します。
a -> b (c -> (d) (e))
つまり、とのa
両方に行き、とに行くグラフ。これらの式の抽象構文ツリーを作成しようとしていますが、すべての演算子が各側で任意の数のオペランドを受け入れることができるため、問題が発生しています。式を抽出するロジックを複製する必要がないため、再帰下降構文解析メソッド内でASTを生成するためのロジックを維持したいと思います。私の現在の戦略は次のとおりです。b
(c -> (d) (e))
c
d
e
が表示されたら、
Value
それを出力にプッシュします。From
またはが表示された場合To
:セパレータを出力します。
次を取得し
Expr
ます。ノードを作成し
Link
ます。Link
セパレータが表示されるまで、出力からのオペランドの最初のセットをポップします。検出されたセパレータを消去します。
オペランドの2番目のセットを
Link
区切り記号までポップします。を出力にプッシュし
Link
ます。
手順2.3〜2.7に従わずにこれを実行すると、値と区切り文字のリストが表示されます。上で引用した式の場合a -> b (c -> (d) (e))
、出力は次のようになります。
A sep_1 B sep_2 C sep_3 D E
To
ルールを適用すると、次のようになります。
A sep_1 B sep_2 (link from C to {D, E})
そしてその後:
(link from A to {B, (link from C to {D, E})})
注意すべき重要なことsep_2
は、2番目の左側のオペランドを区切るために重要なが->
表示されないため、パーサーは式が実際に記述されたと信じていることです。
a -> (b c -> (d) (e))
現在の戦略でこれを解決するには、隣接する式の間に区切り文字を作成する方法が必要ですが、現在の式が括弧で囲まれたFrom
または式である場合に限ります。To
それが可能であれば、私はそれを見ていません。答えは単純なはずです。ただし、これについてもっと良い方法がある場合は、お知らせください。