#f# #fparsec
#f# #fparsec
Вопрос:
У меня есть леворекурсивная грамматика. Мой AST выглядит примерно так:
...
and Expr = BinaryExpr of BinaryExpr
and BinaryExpr = Expr * BinaryOperator * Expr
and BinaryOperator = Plus
...
Я планировал использовать анализатор приоритета оператора для этого, например:
let exprOpp = new OperatorPrecedenceParser<Expr,unit,unit>()
let pBinaryExpr = exprOpp.ExpressionParser
exprOpp.TermParser <- pExpr
let consBinExpr op x y = (x, op, y) |> BinaryExpr
exprOpp.AddOperator(InfixOperator(" ", ws, 1, Associativity.Left, (consBinExpr Plus)))
где pExpr
— синтаксический анализатор для Expr
.
Левая рекурсия вызывает переполнение стека. Мне было интересно, существует ли конкретный FParsec-способ справиться с этим, все еще используя OperatorPrecedenceParser
?
Спасибо!
Редактировать:
Проблема может быть связана с тем, что pExpr
перенаправляет все вызовы другому анализатору pExprRef
.
let pExpr, pExprRef = createParserForwardedToRef()
и после синтаксического анализа с приоритетом оператора определяется ссылка:
do pExprRef :=
choice [pBinaryExpr, <other-parsers...>];
Комментарии:
1. Ваш пример никогда не завершится; вам понадобится другой параметр в
Expr
, который представляет единственное значение. Как бы то ни было, ваши примеры типов бесконечно рекурсивны.2. Спасибо. Я также избавился от,
createParserForwardedToRef
как кажетсяpExpr
, пересылки всех вызовов наTermParser