我目前正在执行一个 JavaScript/ECMAScript 5.1解析器与 JavaCC 有问题 ArrayLiteral生产。
ArrayLiteral :
[ Elision_opt ]
[ ElementList ]
[ ElementList , Elision_opt ]
ElementList :
Elision_opt AssignmentExpression
ElementList , Elision_opt AssignmentExpression
Elision :
,
Elision ,
我有三个问题,我会一一提问。
这是第二个。
我已将此产生式简化为以下形式:
ArrayLiteral:
"[" ("," | AssignmentExpression ",") * AssignmentExpression ? "]"
请看第一题是否正确:
How to simplify JavaScript/ECMAScript array literal production?
现在我尝试在 JavaCC 中实现如下:
void ArrayLiteral() :
{
}
{
"["
(
","
| AssignmentExpression()
","
) *
(
AssignmentExpression()
) ?
"]"
}
JavaCC 提示模棱两可 ,
或 AssignmentExpression
(其内容)。显然,一个 LOOKAHEAD
规范是必需的。我花了很多时间试图计算 LOOKAHEAD
出来了,尝试了不同的东西,比如
-
LOOKAHEAD (AssignmentExpression() ",")
在(...)*
-
LOOKAHEAD (AssignmentExpression() "]")
在(...)?
和一些其他变体,但我无法摆脱 JavaCC 警告。
我不明白为什么这不起作用:
void ArrayLiteral() :
{
}
{
"["
(
LOOKAHEAD ("," | AssignmentExpression() ",")
","
| AssignmentExpression()
","
) *
(
LOOKAHEAD (AssignmentExpression() "]")
AssignmentExpression()
) ?
"]"
}
好的,AssignmentExpression()
本身是模棱两可的,但尾随 ","
或 "]"
在LOOKAHEAD
s 应该明确应该采取哪些选择 - 或者我在这里弄错了吗?
什么是正确的 LOOKAHEAD
这个产品的规范是什么样的?
更新
不幸的是,这没有用:
void ArrayLiteral() :
{
}
{
"["
(
","
|
LOOKAHEAD (AssignmentExpression() ",")
AssignmentExpression()
","
) *
(
AssignmentExpression()
) ?
"]"
}
警告:
Warning: Choice conflict in (...)* construct at line 6, column 5.
Expansion nested within construct and expansion following construct
have common prefixes, one of which is: "function"
Consider using a lookahead of 2 or more for nested expansion.
第 6 行是 (
在第一个之前 LOOKAHEAD
.公共(public)前缀 "function"
只是 AssignmentExpression
的可能开始之一.
最佳答案
JavaCC 生成自上而下的解析器。顺便说一句,我不是自上而下的解析器生成器的粉丝,所以我不是 JavaCC 专家,也没有方便的测试。
(编辑:我认为其他方法会起作用,但后来我意识到我不明白 JavaCC 如何将先行附加到实际选择;在 ( A | B ) 的情况下* C
,其实有A、B、C三种可能的选择,我以为它会考虑这三个,但有可能一次只考虑两个。所以下面是另一种猜测。 )
话虽如此,我认为以下内容可行,但它涉及对几乎每个 AssignmentExpression()
进行两次解析。
{
"["
(
","
|
AssignmentExpression()
","
) *
(
LOOKAHEAD (AssignmentExpression() "]")
AssignmentExpression()
) ?
"]"
}
正如我在 the linked question 中指出的那样,更好的解决方案是以不同方式重写产生式:
"[" AssignmentExpression ? ("," AssignmentExpression ?) * "]"
这会导致单标记先行语法,因此您不需要 LOOKAHEAD
声明来处理它。
关于javascript - 用于 JavaScript/ECMAScript 数组文字生成的 LOOKAHEAD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26908705/