在s表达式中是否禁止尾随空格?

时间:2014-05-15 15:04:02

标签: ocaml s-expression

当我尝试 sexplib 时,它会告诉我

Sexp.of_string " a";;是正确的。

Sexp.of_string "a ";;错了。


sexp中是否禁止尾随空格?

为什么?

1 个答案:

答案 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);