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



当我尝试sexplib时,它告诉我

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

Sexp.of_string "a ";;是错误的。


在sexp中是否禁止尾随空格?

为什么?

根据非正式语法规范,应该忽略原子两端的空白:

{2 s表达式语法规范}

{9 S-expression的词法约定}

空格,由空格、换行符、回车、水平制表符和表单提要被忽略,除非在OCaml-string,根据ocaml -约定进行处理。的分号表示注释。注释将被忽略,范围为下一个换行符。左括号打开一个新列表,右括号再次关闭它。列表可以为空。的双引号表示字符串的开始和结束OCaml的词法约定(详见OCaml手册)。所有双引号、左括号和右括号以外的字符空格被认为是连续字符串的一部分。

实际上,您可以从文件中读取带有末尾空格的原子而不会出现任何错误。

在解析器成功返回的情况下,从函数Pre_sexp.of_string_bigstring抛出错误,但有些东西留在缓冲区中。所以主要的问题是为什么有些东西留在了缓冲中。似乎存在几个解析器,文件和字符串用不同的解析器解析。

我检查了在pre_sexp.ml:699中定义的parse_atom规则(所有位置都用于此提交),并发现当命中尾随空格时,将调用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);

最新更新