FParsec 解析带括号的表达式
FParsec parse expressions with parentheses
我正在编写我的第一个解析器。它在 F# 中,我正在使用 FParsec。
我的解析器解析了 true and false
、(true and false or true)
、true
、(((true and false or true)))
等内容,这是正确的。
但是当它像(true and false) or true
时它不解析。当文本中间有括号时失败。
我该如何解决?
示例代码:
let private infixOperator (opp: OperatorPrecedenceParser<_,_,_>) op prec map =
opp.AddOperator(InfixOperator (op, ws, prec, Associativity.Left, map))
let private oppLogic = new OperatorPrecedenceParser<_,_,_>()
infixOperator oppLogic "is" 1 (fun x y -> Comparison (x, Equal, y))
infixOperator oppLogic "isnt" 1 (fun x y -> Comparison (x, NotEqual, y))
infixOperator oppLogic "or" 2 (fun x y -> Logic (x, Or, y))
infixOperator oppLogic "and" 3 (fun x y -> Logic (x, And, y))
let private exprParserLogic = oppLogic.ExpressionParser
let private betweenParentheses p =
between (str "(") (str ")") p
oppLogic.TermParser <- choice [
betweenParentheses exprParserLogic
pboolean
]
let pexpression =
choice [
attempt <| betweenParentheses exprParserLogic
exprParserLogic
]
let private pline =
ws
>>. pexpression
.>> eof
对于“(true and false)或 true”这样的输入,发生的情况是 pline
适用,pexpression
尝试应用 betweenParentheses exprParserLogic
。这会成功并解析“(true and false)”。因此,由于解析成功,它永远不会尝试第二个选项 exprParserLogic
,而只是 returns 到 pline
。 pline
然后应用 eof
,它失败了,因为 "or true" 仍然留在输入中。
由于 betweenParentheses exprParserLogic
已经是运算符解析器的术语解析器的一部分,您没有理由尝试在它自己的规则中解析它。您可以只让 pline
调用 exprParserLogic
并完全删除 pexpression
(或定义 let pexpression = oppLogic.ExpressionParser
并删除 exprParserLogic
)。这将正确解析“(true and false) or true”。
我正在编写我的第一个解析器。它在 F# 中,我正在使用 FParsec。
我的解析器解析了 true and false
、(true and false or true)
、true
、(((true and false or true)))
等内容,这是正确的。
但是当它像(true and false) or true
时它不解析。当文本中间有括号时失败。
我该如何解决?
示例代码:
let private infixOperator (opp: OperatorPrecedenceParser<_,_,_>) op prec map =
opp.AddOperator(InfixOperator (op, ws, prec, Associativity.Left, map))
let private oppLogic = new OperatorPrecedenceParser<_,_,_>()
infixOperator oppLogic "is" 1 (fun x y -> Comparison (x, Equal, y))
infixOperator oppLogic "isnt" 1 (fun x y -> Comparison (x, NotEqual, y))
infixOperator oppLogic "or" 2 (fun x y -> Logic (x, Or, y))
infixOperator oppLogic "and" 3 (fun x y -> Logic (x, And, y))
let private exprParserLogic = oppLogic.ExpressionParser
let private betweenParentheses p =
between (str "(") (str ")") p
oppLogic.TermParser <- choice [
betweenParentheses exprParserLogic
pboolean
]
let pexpression =
choice [
attempt <| betweenParentheses exprParserLogic
exprParserLogic
]
let private pline =
ws
>>. pexpression
.>> eof
对于“(true and false)或 true”这样的输入,发生的情况是 pline
适用,pexpression
尝试应用 betweenParentheses exprParserLogic
。这会成功并解析“(true and false)”。因此,由于解析成功,它永远不会尝试第二个选项 exprParserLogic
,而只是 returns 到 pline
。 pline
然后应用 eof
,它失败了,因为 "or true" 仍然留在输入中。
由于 betweenParentheses exprParserLogic
已经是运算符解析器的术语解析器的一部分,您没有理由尝试在它自己的规则中解析它。您可以只让 pline
调用 exprParserLogic
并完全删除 pexpression
(或定义 let pexpression = oppLogic.ExpressionParser
并删除 exprParserLogic
)。这将正确解析“(true and false) or true”。