テンプレートシステムの文法に取り組んでいます。ビルドで問題が発生しましたが、この問題を解決する方法がわかりません。私が行っていることを正確に強調するために、テスト ケースを簡略化しました。
文字列の例:
(foo)
-作品(foo())
- 失敗Expecting 'parenEnd', got 'parenInterior'
foo (foo) bar
foo (foo(function() { console.log('stuff'); })) bar
foo (foo.bar.baz("stuff")) bar
ルールは、括弧内には何でも、どんな文字でも入れるというものです。検証する必要はありません。また、それらが適切な形式に一致していることを確認する必要もありません。一方、私の理解では、パーサーが機能するためには、開始と終了(
を追跡する必要があり)
ます。そうしないと、レクサーは、括弧内のステートメントがどこで始まり、別のステートメントがどこで終わるかを知ることができません(foo()) (bar)
。それを追跡するために、私はparen
開始条件を使用しています。この開始条件は、paren ステートメント内で括弧がヒットするたびに値をインクリメントし、閉じ括弧の場合は値を削除します。
問題は、それが機能していないことです。主な原因は、私のルールにまったく当てはまらないように見えるにも<paren>")"
かかわらず、<paren>"("
うまくルールに当てはまっていることです。構文的には同じように見えますが、一方が機能し、もう一方が機能しないのはなぜですか?
文法
%lex
%x paren
%%
\s+ /* skip whitespace */
<INITIAL>"(" { this.begin("paren"); parenCount = 1; return "parenStart"; };
<paren>"(" { console.log("parenStart", parenCount); parenCount++; return "parenInterior"; };
<paren>")" { console.log("parenEnd", parenCount); parenCount--; if (parenCount === 0) { this.popState(); return "parenEnd"; } else { return "parenInterior"; } };
<paren>[^\)\(]+ { console.log(this); return "parenInterior"; };
<<EOF>> return 'EOF';
. return 'INVALID';
/lex
%start expressions
%% /* language grammar */
expressions
: parenStart parenInterior parenEnd { return $1 + $2 + $3; }
;
%%
parenCount = 0;