我正在编写我的第一个解析器。它在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
答案 0 :(得分:1)
“{true和false”或“true”之类的输入会发生pline
适用,pexpression
尝试应用betweenParentheses exprParserLogic
。这成功并解析“(真与假)”。因此,由于解析成功,它永远不会尝试第二个选项exprParserLogic
,只返回pline
。 pline
然后应用eof
,但失败是因为输入中仍保留“或true”。
由于betweenParentheses exprParserLogic
已经是运算符解析器的术语解析器的一部分,因此您没有理由尝试在其自己的规则中解析它。您可以pline
调用exprParserLogic
并完全删除pexpression
(或定义let pexpression = oppLogic.ExpressionParser
并删除exprParserLogic
)。这将正确解析“(true和false)或true”。