F# 让FParsec拒绝不匹配的开始-结束标记?
编写自己的XML解析器来学习FParsec,我需要测试XML开始和结束标记是否匹配,或者让解析器失败 在下面的代码片段中F# 让FParsec拒绝不匹配的开始-结束标记?,f#,fparsec,F#,Fparsec,编写自己的XML解析器来学习FParsec,我需要测试XML开始和结束标记是否匹配,或者让解析器失败 在下面的代码片段中 解析器xStartTag和xKey返回我想要匹配的strings 解析器xContent\u untlclosetag只返回标记之间的内容 ws跳过空格和str(“>”)跳过一个'>' PipeN.pipe10函数是标准FParsec原语pipe5的扩展,用于将10个解析器的结果输入到函数中 所有这些解析器都编译并工作 当开始标记和结束标记不匹配时,如何使以下类型为par
- 解析器
和xStartTag
返回我想要匹配的xKey
sstring
- 解析器
只返回标记之间的内容xContent\u untlclosetag
跳过空格和ws
跳过一个'>'str(“>”)
函数是标准FParsec原语PipeN.pipe10
的扩展,用于将10个解析器的结果输入到函数中pipe5
parser
的解析器构建类型XELEMENT\u CONTENT
失败
00 let xElement_Content : Parser<XELEMENT, USER_STATE> =
01 (PipeN.pipe10 ws xStartTag ws xContent_UntilCloseTag ws xKey ws (str ">") ws
02 (fun stream -> getUserState stream)
03 (fun x1 x2_startTag x3 x4_content x5 x6_closeTag x7 x8 x9 userState ->
04 if x2_startTag.head = x6_closeTag
05 then
06 (userState.Deeper(x2_startTag.head), x2_startTag, x4_content)
07 else Reply(FatalError, messageError ("in xElementContent: head tag (%s) does not match close tag (%s)", x2_startTag.head, x6_closeTag))
08 ) |>> C_XELEMENT_CONTENT
09 )
我已经详细查看了(特别是)但是可能遗漏了什么?我认为您不需要维护用户状态来匹配XML标记。下面是一个非常简单的解析器,可以正确地检测不匹配(但不处理嵌套标记):
打开FParsec
让它打开=
pstring“”
让我关上=
pstring“”
让语法分析器输入=
parseTagOpen
.>>. (manySatisfy(fun c->c)你是对的,用户状态用于跟踪嵌套深度,这与此问题无关。请注意,“failfailly”内部发生了什么?我认为这是实际的答案-谢谢!这是一个内置解析器,只返回致命错误。请参见相同的错误:-(失败的的返回时间是解析器,它不符合预期的返回类型XELEMENT\u CONTENT
。if
的两个分支都需要返回相同的类型。啊,好的。如果您试图理解代码为什么不编译,请注意,我代码中if语句的另一个分支调用pre转动
,而不是返回原始元组。这是必要的,因为整个函数实际上是一个解析器,通过bind调用(>=
),而不是pipeN
。这允许解析器在标记不匹配时正常失败。另一方面,一旦pipeN
调用10参数函数,就无法正常失败。您确实需要绑定(或使用parse
计算表达式)。
type USER_STATE =
{
tag : string
depth : int
}
type XELEMENT_CONTENT = USER_STATE * XHEADandATTRIBUTES_RECORD * string
type XELEMENT_EMPTY = XHEADandATTRIBUTES_RECORD
type XELEMENT =
| C_XELEMENT_CONTENT of XELEMENT_CONTENT
| C_XELEMENT_NESTED of USER_STATE * XHEADandATTRIBUTES_RECORD * (XELEMENT list)
| C_XELEMENT_EMPTY of XELEMENT_EMPTY
type XELEMENT_NESTED = XHEADandATTRIBUTES_RECORD * (XELEMENT list)