Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 带括号的FParsec解析表达式_Parsing_Compilation_F#_Functional Programming_Fparsec - Fatal编程技术网

Parsing 带括号的FParsec解析表达式

Parsing 带括号的FParsec解析表达式,parsing,compilation,f#,functional-programming,fparsec,Parsing,Compilation,F#,Functional Programming,Fparsec,我正在编写我的第一个解析器。它在F#中,我与FParsec一起使用 我的解析器解析像真与假,(真与假或真),真,((真与假或真))等,这是正确的 但是当它像(true和false)或true时,它不会解析。当文本中间有括号时失败。 我怎样才能解决它 示例代码: let private infixOperator (opp: OperatorPrecedenceParser<_,_,_>) op prec map = opp.AddOperator(InfixOperator

我正在编写我的第一个解析器。它在F#中,我与FParsec一起使用

我的解析器解析像
真与假
(真与假或真)
((真与假或真))等,这是正确的

但是当它像
(true和false)或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
让专用infixOperator(opp:OperatorReceidenceParser)操作预映射=
opp.AddOperator(InfixOperator(op,ws,prec,Associativity.Left,map))
let private oppLogic=new operatorreceidenceparser()
infixOperator oppLogic“是”1(乐趣x y->比较(x,相等,y))
infixOperator oppLogic“不是”1(乐趣x y->比较(x,NotEqual,y))
infixOperator oppLogic“或”2(乐趣x y->Logic(x,或,y))
infixOperator oppLogic“和”3(乐趣x y->Logic(x,和,y))
让私有exprParserLogic=oppLogic.ExpressionParser
让私人之间的租金p=
在(str)之间
oppLogic.TermParser。表达
.>>eof

对于像“(真与假)或“真”这样的输入所发生的情况是
pline
应用,而
pexpression
尝试在exprParserLogic
之间应用
。这将成功并解析“(true和false)”。因此,由于解析成功,它从不尝试第二个选项
exprParserLogic
,而是简单地返回到
pline
pline
然后应用
eof
,该操作失败,因为输入中仍保留“或true”

因为
betweenParentheses exprParserLogic
已经是操作符解析器的术语解析器的一部分,所以您没有理由尝试用它自己的规则来解析它。您可以让
pline
调用
exprParserLogic
并删除
pexpression
(或者定义
让peexpression=oppLogic.ExpressionParser
并删除
exprParserLogic
)。这将正确解析“(true和false)或true”