当我尝试sexplib时,它告诉我
Sexp.of_string " a";;
是正确的。
Sexp.of_string "a ";;
是错的。
sexp中是否禁止尾随空格?
为什么?
当我尝试sexplib时,它告诉我
Sexp.of_string " a";;
是正确的。
Sexp.of_string "a ";;
是错的。
sexp中是否禁止尾随空格?
为什么?
根据非正式的语法规范,应忽略原子两端的空格:
{2 S-表达式的语法规范}
{9 S-表达式的词法约定}
由空格、换行符、回车符、水平制表符和换页符组成的空格会被忽略,除非在 OCaml 字符串中,根据 OCaml 约定对其进行处理。分号引入注释。注释被忽略,并且范围直到下一个换行符。左括号打开一个新列表,右括号再次关闭它。列表可以为空。双引号表示遵循 OCaml 的词法约定的字符串的开头和结尾(有关详细信息,请参阅 OCaml 手册)。除双引号、左右括号和空格之外的所有字符都被视为连续字符串的一部分。
实际上,您可以从文件中读取带有尾随空格的原子而不会出现任何错误。
Pre_sexp.of_string_bigstring
如果解析器成功返回,但缓冲区中有一些内容,则从函数中抛出错误。所以主要的问题是为什么缓冲区中有一些东西。似乎存在多个解析器,并且文件和字符串使用不同的解析器进行解析。
我检查了在(所有位置都针对此提交parse_atom
)定义的规则,并发现当命中尾随空格时,将调用 。然后,如果堆栈上有东西,则位置指示符会递增并继续解析。否则,解析完成,但位置不增加。通过一个简单的补丁可以解决这个问题:pre_sexp.ml:699
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);