Я создаю инструментарий JavaScript с помощью ANTLR, используя грамматику Патрика Хулсмейера EcmaScript 3 .
У меня проблема с анализом этой строки кода:
function(){}();
это прямой вызов выражения функции.
Синтаксический анализатор распознает инструкцию как объявление функции, а затем завершается ошибкой, когда находит скобки после тела функции. Причина в том, что объявления функций распознаются с наибольшим приоритетом, чтобы избежать двусмысленности с выражениями функций.
Вот как грамматика распознает объявления функций:
sourceElement
options
{
k = 1 ;
}
: { input.LA(1) == FUNCTION }? functionDeclaration
| statement
;
Я даже не уверен, что это допустимый оператор EcmaScript. Это так?
Я думаю, что правильнее было бы написать:
(function(){})();
, который на самом деле хорошо обрабатывается парсером.
Кстати, это не суть вопроса, потому что я не контролирую код для инструмента.
Я пытался исключить functionDeclaration
из производства sourceElement
и поместить его в statement
statementTail
производство:
statementTail
: variableStatement
| emptyStatement
| expressionStatement
| functionDeclaration
| ifStatement
| ...
;
Но возникает ошибка сборки:
[роковое] правило statementTail
имеет
не LL (*) решение из-за рекурсивного
правила вызова достижимы из Alts
3,4. Решить с помощью левого факторинга или
используя синтаксические предикаты или используя
backtrack=true
опция.
| --->: variableStatement
, поскольку производство variableStatement
содержит functionExpression
в качестве потомка, что приводит к неоднозначности. Парсер не может выбирать между functionDeclaration
и functionExpression
, потому что они почти равны:
functionDeclaration
: FUNCTION name=Identifier formalParameterList functionBody
-> ^( FUNCTIONDECL $name formalParameterList functionBody )
;
functionExpression
: FUNCTION name=Identifier? formalParameterList functionBody
-> ^( FUNCTIONEXPR $name? formalParameterList functionBody )
;
Примечание. Я изменил исходные правила перезаписи, используя разные узлы дерева (FUNCTIONDECL и FUNCTIONEXPR), потому что он мне нужен во время прогулки по AST.
Как мне решить эту двусмысленность?