У меня есть синтаксический анализатор присутствия операторов, который анализирует математические выражения, аналогично примеру калькулятора в хранилище FParsec.
Однако следующий анализатор в последовательности анализирует ->
, что вызывает конфликт с оператором вычитания.
Примерный код:
open FParsec
let ws = spaces
let str s = pstring s .>> ws
let number = pfloat .>> ws
let opp = new OperatorPrecedenceParser<float,unit,unit>()
let expr = opp.ExpressionParser
opp.TermParser <- number <|> between (str "(") (str ")") expr
opp.AddOperator(InfixOperator("+", ws, 1, Associativity.Left, (+)))
opp.AddOperator(InfixOperator("-", ws, 1, Associativity.Left, (-)))
opp.AddOperator(InfixOperator("*", ws, 2, Associativity.Left, (*)))
opp.AddOperator(InfixOperator("/", ws, 2, Associativity.Left, (/)))
opp.AddOperator(InfixOperator("^", ws, 3, Associativity.Right, fun x y -> System.Math.Pow(x, y)))
opp.AddOperator(PrefixOperator("-", ws, 4, true, fun x -> -x))
let completeExpression = expr .>> ws
let program =
pipe3 completeExpression (str "->") completeExpression <| fun e1 _ e2 ->
(e1, e2)
Что не работает, например, для 1+1 -> 1+2
.
Я знаю, что если я поменяю str "->"
на str "=>"
, то будет работать что-то вроде 1+1 => 1+2
.
Можно ли добавить предварительный просмотр в синтаксический анализатор приоритета оператора? Или есть другой способ обойти это?
Спасибо!
EDIT
Я отсортировал это, добавив notFollowedBy
в парсер после строки для оператора вычитания.
let after = (notFollowedBy (str ">")) >>. ws
opp.AddOperator(InfixOperator("-", after, 1, Associativity.Left, (-)))