位置信息在fparsec中

ham*_*ett 5 f# fparsec

我的AST模型需要携带位置信息(文件名,行,索引).有没有内置的方式来访问这些信息?从参考文档来看,流似乎具有这个位置,但我更喜欢我不需要实现一个虚拟解析器来保存位置,并在任何地方添加它.

提前致谢

Cet*_*ert 8

解析器实际上是从流到回复的函数的类型缩写:

Parser<_,_> is just CharStream<_> -> Reply<_>
Run Code Online (Sandbox Code Playgroud)

牢记这一点,您可以轻松地为职位编写自定义解析器:

let position : CharStream<_> -> Reply<Position> = fun stream -> Reply(stream.Position)
(* OR *)
let position : Parser<_,_> = fun stream -> Reply stream.Position
Run Code Online (Sandbox Code Playgroud)

并将位置信息附加到您使用的每个位解析

position .>>. yourParser (*or tuple2 position yourParser*)
Run Code Online (Sandbox Code Playgroud)

位置解析器不消耗任何输入,因此以这种方式组合是安全的.

可以将所需的代码更改限制为一行,并避免无法控制的代码传播:

type AST = Slash of int64
         | Hash  of int64

let slash : Parser<AST,_> = char '/' >>. pint64 |>> Slash
let hash  : Parser<AST,_> = char '#' >>. pint64 |>> Hash
let ast   : Parser<AST,_> = slash <|> hash

(*if this is the final parser used for parsing lists of your ASTs*)
let manyAst  : Parser<            AST  list,_> = many                (ast  .>> spaces)

let manyAstP : Parser<(Position * AST) list,_> = many ((position .>>. ast) .>> spaces)
(*you can opt in to parse position information for every bit
  you parse just by modifiying only the combined parser     *)
Run Code Online (Sandbox Code Playgroud)

更新:FParsec有一个预定义的位置解析器:http://www.quanttec.com/fparsec/reference/charparsers.html#members.getPosition

  • 您实际上不需要自己定义位置解析器:http://www.quanttec.com/fparsec/reference/charparsers.html#members.getPosition (2认同)