我目前使用JavaCC实现JavaScript / ECMAScript 5.1解析器,并且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
应该清楚应该选择哪个选项-还是我误会了?此产品的正确
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
。通用前缀"function"
只是AssignmentExpression
可能的开始之一。 最佳答案
这是另一种方法。它的优点是无需使用任何语义操作即可识别哪些逗号表示未定义的元素。
void ArrayLiteral() : {} { "[" MoreArrayLiteral() }
void MoreArrayLiteral() : {} {
"]"
| "," /* undefined item */ MoreArrayLiteral()
| AssignmentExpression() ( "]" | "," MoreArrayLiteral() )
}
关于javascript - 用于JavaScript/ECMAScript数组文字生产的LOOKAHEADs,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26908705/