パーサーのサイズは深刻な問題ではありません (ほとんどの場合)。
ランタイム スタック サイズが問題になる場合があります。問題は、右の再帰規則では、パーサーがシーケンスの最後に到達するまでスタックを減らすことができないことを意味するのに対し、左の再帰規則では、文法が に遭遇するたびseq item
に、スタック上のアイテムの数を減らすことができることです。 .
従来、トークンのスタックは固定され、サイズが制限されていました。したがって、次のような正しい再帰規則を処理します。
IF <cond> THEN
<stmt-list>
ELSIF <cond> THEN
<stmt-list>
ELSIF <cond> THEN
<stmt-list>
ELSE
<stmt-list>
ENDIF
文法が受け入れることができる ELIF 句のチェーン内の用語の数を制限します。
仮説文法:
if_stmt: if_clause opt_elif_clause_list opt_else_clause ENDIF
;
if_clause: IF condition THEN stmt_list
;
opt_elif_clause_list: /* Nothing */
| elif_clause opt_elif_clause_list /* RR */
;
elif_clause: ELIF condition THEN stmt_list
;
opt_else_clause: /* Nothing */
| ELSE stmt_list
;
stmt_list: stmt
| stmt_list stmt /* LR */
;
私はかなり前 (10 年以上前) にこれについていくつかのテストを行ったことを覚えているようですが、当時私が使用していた Yacc は、上記と同様の言語文法と組み合わせて、約 300 秒後にELIF句、パーサーが停止しました(スペースの枯渇に気づかずにクラッシュするのではなく、スペースが不足していることを認識して、制御下で停止したと思います)。