gpt4 book ai didi

javascript - 使用 JISON 匹配但忽略嵌套括号

转载 作者:行者123 更新时间:2023-12-03 11:38:37 25 4
gpt4 key购买 nike

我正在研究模板系统的语法。我在构建中遇到了障碍,我不太清楚如何解决这个问题。我简化了测试用例,以最好地强调我正在做的事情。

示例字符串:

  • (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>"("规则就好了。它们在语法上看起来是相同的,为什么一个有效而另一个无效?

语法

%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;

最佳答案

我相信您的问题是您的语法不接受标记的序列。如果我将语法更改为此,那么我会得到一些可以处理您在问题中显示的字符串的东西:

%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 'WHATEVER';

/lex

%start expressions

%% /* language grammar */

expressions
: whateverSeq parenStart parenInteriorSeq parenEnd whateverSeq EOF { return $1 + $2 + $3 + $4 + $5; }
;

parenInteriorSeq
: parenInterior
| parenInteriorSeq parenInterior -> $1.concat($2)
;

whateverSeq
: -> "" // Empty sequence.
| whatevers // One or more WHATEVER tokens.
;

whatevers
: whatever
| whateverSeq WHATEVER -> $1.concat($2)
;

%%

parenCount = 0;

那么嵌套括号就没有问题了。

显着变化:

  1. INVALID 替换为 WHATEVER。添加了在开始和结束处添加 WHATEVER 标记序列的规则。这允许有诸如 blah (foo) blah 之类的东西。

  2. parenInterior 替换为 parenInteriorSeq,以便您可以在括号内包含 parenInterior 标记序列。这是必要的,因为在像 (foo()) 这样的字符串中,foo 是一个标记,下一个 ( 是另一个标记,下一个 ) 是另一个标记。因此,您必须接受 token 列表。

关于javascript - 使用 JISON 匹配但忽略嵌套括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26370901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com