fparsec 中的位置信息

发布于 2024-11-15 20:04:46 字数 111 浏览 5 评论 0原文

我的 AST 模型需要携带位置信息(文件名、行、索引)。有没有内置的方法来访问这些信息?从参考文档来看,流似乎带有位置,但我更希望不必实现虚拟解析器来保存位置,并将其添加到任何地方。

提前致谢

My AST model needs to carry location information (filename, line, index). Is there any built in way to access this information? From the reference docs, the stream seems to carry the position, but I'd prefer that I dont have to implement a dummy parser just to save the position, and add that everywhere.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傾城如夢未必闌珊 2024-11-22 20:04:46

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

Parser<_,_> is just CharStream<_> -> Reply<_>

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

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

并将位置信息附加到使用

position .>>. yourParser (*or tuple2 position yourParser*)

位置解析器解析的每个位,不会消耗任何输入,因此可以安全地以这种方式结合起来。

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

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     *)

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

Parsers are actually type abbreviations for functions from streams to replies:

Parser<_,_> is just CharStream<_> -> Reply<_>

Keeping that in mind, you can easily write a custom parser for positions:

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

and atttach position information to every bit you parse using

position .>>. yourParser (*or tuple2 position yourParser*)

position parser does not consume any input and thus it is safe to combine in that way.

You can keep the code change required restricted to a single line and avoid uncontrollable code spread:

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     *)

Update: FParsec has a predefined parser for positions:
http://www.quanttec.com/fparsec/reference/charparsers.html#members.getPosition

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文