Bal*_*nth 4 f# parser-combinators fparsec
我尝试解析类似 xml 的标签(但不是正确的 xml 文档..):目标是返回没有开头或结尾空格的“法兰宽度”,但带有内部空格。
open FParsec
let testParser =
pstring "<desc>" .>>. spaces
>>. manyCharsTill anyChar (spaces .>>. pstring "</desc>")
run testParser "<desc> Flange width </desc>"
Run Code Online (Sandbox Code Playgroud)
如果我理解解析器组合器的预期结果:
保持吞咽字符的 anyChar 解析器单元“直到”解析器,它寻找空格,然后是结束标记成功。
实际发生的情况是,“直到”解析器在“宽度”之前的空间上失败(应该如此),但会使 manyTill 解析器短路,而不是让 anyChar 吞下该空间并继续前进。
输出:
val it : ParserResult<string,unit> =
Failure:
Error in Ln: 1 Col: 15
<desc> Flange width </desc>
^
Expecting: '</desc>'
Run Code Online (Sandbox Code Playgroud)
我没有得到什么?或者这里的惯用解决方案是什么?
问题是spaces解析成功并将流移动到w. pstring "</desc>"然后失败。
最终结果是endp解析器失败了,但它改变了状态(我们已经移过了空格)。您希望解析器失败并且不更改状态(在空格之前)。的文档manyTill(由 引用manyCharsTill)解释了这一点:
只要失败,解析器就会
manyTill p endp重复应用解析器(不改变解析器状态)。pendp
您可以使用.>>.?运算符来做到这一点:
解析器的
p1 .>>.? p2行为类似于p1 .>>. p2,除了如果p2失败并出现非致命错误并且不更改解析器状态,即使p1已更改解析器状态,它将回溯到开头。
所以这个:
let testParser =
pstring "<desc>" .>>. spaces
>>. manyCharsTill anyChar (spaces .>>.? pstring "</desc>")
Run Code Online (Sandbox Code Playgroud)
有关工作演示,请参阅此小提琴。
| 归档时间: |
|
| 查看次数: |
107 次 |
| 最近记录: |