我正在使用 yojson
解析 OCaml 中的 JSON 文件,在验证输入文件时,我想为用户发出包含源代码信息的错误消息。
例如,如果我发现第 5492 行的给定值不在允许范围内,我想告诉用户:“Invalid value in line source.json:5492”。
我怎样才能得到这些信息?
(如果 yojson 无法提供此类信息,另一个拥有此类信息的 OCaml JSON 库可能会有用。)
最佳答案
在效率和交互性之间,Yojson
选择了第一个(更准确地说,Yojson
是真正为数据(反)序列化而设计的,所以计算机生成的 JSON 报错没有意义)。
它的杠杆文件:yojson/lib/read.mll
以确切的注释开头:
(*
We override Lexing.engine in order to avoid creating a new position
record each time a rule is matched.
This reduces total parsing time by about 31%.
*)
这些位置正是你需要报错的地方!
Jsonm
有你需要的:
val decoded_range : decoder -> (int * int) * (int * int)
decoded_range d is the range of characters spanning the last `Lexeme or `Error (or `White or `Comment for an Jsonm.Uncut.decode) decoded by d. A pair of line and column numbers respectively one and zero based.
但是 Jsonm
是专家库。
可悲的是,它的包装器 Ezjsonm
几乎做了一件好事,但在最后一秒失败了,并引发了 Ezjsonm.Parse_error
没有范围!
您可以在 https://github.com/mirage/ezjsonm/blob/master/lib/ezjsonm.ml 查看源代码作为做正确事情的灵感。 :json_of_src
完全满足您的需求,但是...由于未知原因...from_src
定义为
let from_src src =
match json_of_src src with
| `JSON t -> t
| `Error (_,e) -> parse_error `Null "JSON.of_buffer %s" (string_of_error e)
let from_string str = from_src (`String str)
降低范围!
关于json - 从源中的 JSON token 获取位置信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48422940/