当我尝试 sexplib 时,它会告诉我
Sexp.of_string " a";;
是正确的。
Sexp.of_string "a ";;
错了。
sexp中是否禁止尾随空格?
为什么?
答案 0 :(得分:0)
根据非正式语法规范,原子的两端应该忽略空格:
{2 S表达式的语法规范}
{9 S-expression的词汇惯例}
空白,包括空格,换行符,回车, 水平制表符和换页符将被忽略,除非在 OCaml-string,根据OCaml-conventions进行处理。该 分号引入了评论。注释被忽略,范围可达 下一个换行符。左括号打开一个新列表, 右括号再次关闭它。列表可以是空的。该 double quote表示后面的字符串的开头和结尾 OCaml的词汇约定(详见OCaml-manual)。所有 双引号,左括号和右括号以外的字符 空格被认为是连续字符串的一部分。
实际上,您可以从文件中读取带有尾随空格的原子而没有任何错误。
在解析器成功返回的情况下,从函数Pre_sexp.of_string_bigstring
抛出错误,但是某些内容留在缓冲区中。所以主要的问题是为什么在缓冲区中留下了一些东西。似乎存在多个解析器,并且使用不同的解析器解析文件和字符串。
我检查了在parse_atom
定义的pre_sexp.ml:699
规则(所有位置都是this commit),并发现当命中尾随空格时,会调用bump_found_atom
。然后,如果某些东西在堆栈上,则位置指示符会递增并继续解析。否则,解析完成,但位置不会增加。使用简单的补丁可以修复:
diff --git a/lib/pre_sexp.ml b/lib/pre_sexp.ml
index 86603f3..9690c0f 100644
--- a/lib/pre_sexp.ml
+++ b/lib/pre_sexp.ml
@@ -502,7 +502,7 @@ let mk_cont_parser cont_parse = (); fun _state str ~max_pos ~pos ->
let pbuf_str = Buffer.contents pbuf in \
let atom = MK_ATOM in \
match GET_PSTACK with \
- | [] -> Done (atom, mk_parse_pos state pos) \
+ | [] -> Done (atom, mk_parse_pos state (pos + 1)) \
| rev_sexp_lst :: sexp_stack -> \
Buffer.clear pbuf; \
let pstack = (atom :: rev_sexp_lst) :: sexp_stack in \
在此修补程序之后,以下代码生成预期的'a', 'a', 'a'
输出:
let s1 = Sexp.of_string " a" in
let s2 = Sexp.of_string "a " in
let s3 = Sexp.of_string " a " in
printf "'%s', '%s', '%s'\n"
(Sexp.to_string s1)
(Sexp.to_string s2)
(Sexp.to_string s3);