F# 解析if/else/if语句
我试图复制一个简单if语句的结构:F# 解析if/else/if语句,f#,fparsec,F#,Fparsec,我试图复制一个简单if语句的结构: if (paren) { block } [else ({ block } | rec if (paren)) ] let statement, stmtRef = createParserForwardedToRef() let ifStatement = pipe3 (keyword "if" >>. parenExp) statement (opt (keyword "else" >>. statement))
if (paren) { block } [else ({ block } | rec if (paren)) ]
let statement, stmtRef = createParserForwardedToRef()
let ifStatement =
pipe3 (keyword "if" >>. parenExp) statement (opt (keyword "else" >>. statement))
(fun cond stmt1 stmt2 -> Ast.If(cond, stmt1, stmt2))
stmtRef := choice [
simpleStatement
block
ifStatement
forLoop
//...
]
对于if(paren)块,我创建了一个ifast块节点。否则,它将递归地填充IfElseBlock节点
我试过好几种不同的结构
let parse_if =
suffixparen .>>. suffixblock |>> IfBlock
//>>? attempt (str "else" >>. ifParser) |>> IfElseBlock
//<|> preturn IfBlock
// .>>? attempt (str "else" >>. ifParser) |>> IfElseBlock
// suffixparen .>>. suffixblock |>> IfBlock
// <|> ifParser |>> IfElseBlock
let inlineIf = str_ws "if" >>. parse_if
do ifParserR := inlineIf
如果=
足印。suffixblock |>>IfBlock
//>>? 尝试(str“else”>>.ifParser)|>>IfElseBlock
//预烧IfBlock
// .>>? 尝试(str“else”>>.ifParser)|>>IfElseBlock
//足印。suffixblock |>>IfBlock
//ifParser |>>IfElseBlock
让inlineIf=str_ws“if”>>。解析_如果
do ifParserR:=inlineIf
建议?您看过我的GLSL解析器吗(它是一种类似C的语言)? 在代码示例中,以下是
if
语句的相关部分:
if (paren) { block } [else ({ block } | rec if (paren)) ]
let statement, stmtRef = createParserForwardedToRef()
let ifStatement =
pipe3 (keyword "if" >>. parenExp) statement (opt (keyword "else" >>. statement))
(fun cond stmt1 stmt2 -> Ast.If(cond, stmt1, stmt2))
stmtRef := choice [
simpleStatement
block
ifStatement
forLoop
//...
]
我认为您的问题在于您使用的是尝试
,而不是选择
opt
表示else
部分是可选的(如果不存在,则得到None
)<代码>尝试与此完全不同:
解析器尝试p
应用
解析器p
。如果p
在更改后失败
解析器状态或具有致命错误
错误,尝试p
将返回到
原始解析器状态并报告
非致命错误
当
尝试中的解析器失败时,仍然会出现错误,但不会使用输入(与
或选择
运算符组合使用时非常有用)。谢谢Laurent。对于记录,我还尝试将尝试和%None结合使用,但没有效果。