В настоящее время я реализую парсер 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 ? "]"
Пожалуйста, посмотрите первый вопрос о том, правильно это или нет:
Как упростить буквальное создание массива JavaScript/ECMAScript?
Теперь я попытался реализовать его в JavaCC следующим образом:
void ArrayLiteral() :
{
}
{
"["
(
","
| AssignmentExpression()
","
) *
(
AssignmentExpression()
) ?
"]"
}
JavaCC жалуется на неоднозначное ,
или AssignmentExpression
(его содержимое). Очевидно, что требуется спецификация LOOKAHEAD
. Я потратил много времени, пытаясь понять LOOKAHEAD
, пробовал разные вещи, такие как
LOOKAHEAD (AssignmentExpression() ",")
in(...)*
LOOKAHEAD (AssignmentExpression() "]")
in(...)?
и несколько других вариантов, но мне не удалось избавиться от предупреждения 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
. Общий префикс "function"
— это просто одно из возможных начал AssignmentExpression
.