次のような単純な文法があるとします。
X -> number
T -> X
T -> T + X
したがって、たとえば、次のよう3 + 4 + 5
に解析します。
+
/ \
+ 5
/ \
3 4
+
これには、文法に「組み込まれている」という左右の結合性があります。
自明なLR(1)ですが、手書きのトップダウン解析を実行したいとします。
それは再帰的に残されているので、私はそうすることができません。それで、左にそれを因数分解させましょう:
X -> number
T -> X T'
T' -> + X T'
T' -> e // empty
私が今それのためにパーサーを書くならば(疑似コード):
parse_X:
if lookahead is number
return pop_lookahead
parse_T:
return (parse_X, parse_T')
parse_T':
if lookahead is +
pop_lookahead
return (parse_X, parse_T')
else
return ();
parse_T
次に、の入力を呼び出すと、次の3 + 4 + 5
ようなトレースが返されます。
parse_T
(parse_X, parse_T')
(3, parse_T')
(3, (parse_X, parse_T'))
(3, (4, parse_T'))
(3, (4, (parse_X, parse_T')))
(3, (4, (5, ())))
解析がどのように「逆方向」であるかを確認してください。このような構文解析から「素朴に」構築されたツリーは、次のようになります。
+
/ \
3 +
/ \
4 5
これは間違った結合性を持っています。
誰かがこれを片付けることができますか?一般に、文法に組み込まれている関連性を保持する手書きのトップダウンパーサーを作成するにはどうすればよいですか?