如何使用 FParsec 解析固定字符串

How to parse a fixed string with FParsec

提问人:Roald 提问时间:11/8/2021 更新时间:11/8/2021 访问量:148

问:

我正在尝试使用 FParsec 解析固定字符串。例如,从文档中解析 null

open FParsec

type Json = JNull
let jnull : Parser<_>  = stringReturn "null" JNull

然后运行给出预期的结果jnull"null"

> run jnull "null";;
val it : ParserResult<Json,unit> = Success: JNull

但是如果我在上面运行它,它也会成功"nulls"

> run jnull "nulls";;
val it : ParserResult<Json,unit> = Success: JNull

然后我尝试添加一个空格后跟的要求:null

let jnull : Parser<_>  = stringReturn "null" JNull >>. spaces

但是,这给了我和以前一样的结果。

我还尝试使用:manyMinMaxSatisfyL

let jnull: Parser<_> =
        manyMinMaxSatisfyL 4 4 isLower "should be null"
        >>. pstring "null"
        >>. spaces

这个失败了,但也应该失败:"nulls""null"

> run jnull "nulls";;
val it : ParserResult<unit,unit> =
  Failure:
Error in Ln: 1 Col: 5
nulls
    ^
Expecting: 'null'

> run jnull "null";; 
val it : ParserResult<unit,unit> =
  Failure:
Error in Ln: 1 Col: 5
null
    ^
Note: The error occurred at the end of the input stream.
Expecting: 'null'

我在这里做错了什么?还是我完全误解了解析?

解析 f# fparsec

评论


答:

3赞 Tomas Petricek 11/8/2021 #1

通常,解析器总是使用一些输入,生成结果,并将其余输入留给以后处理。这使得组合它们成为可能,但这意味着编写一个消耗整个输入的解析器是很棘手的。

做你想做的事的一种方法是像这样使用:notFollowedBy anyChar

let jnull : Parser<_,unit> = 
  (stringReturn "null" JNull) >>. notFollowedBy anyChar 

run jnull "null"  // Success
run jnull "nulls" // Error

如果无法使用作为参数给出的解析器解析其余输入,则解析器将成功。在这里,这意味着只有当其余部分无法使用 解析时,它才会成功,即它是空的。notFollowedBynotFollowedBy anyCharanyChar

评论

0赞 Brian Berns 11/8/2021
一种稍微简单的方法是改用,它只在输入结束时成功。eof