Парсер приоритета оператора FParsec конфликтует со следующим парсером в последовательности - PullRequest
1 голос
/ 02 апреля 2019

У меня есть синтаксический анализатор присутствия операторов, который анализирует математические выражения, аналогично примеру калькулятора в хранилище 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, (-)))
...