我正在研究模板系统的语法。我在构建中遇到了障碍,我不太清楚如何解决这个问题。我已经简化了测试用例,以最好地强调我在做什么。
示例字符串:
(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;