123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219openCommontypet=|Empty|Scalarofstring|Objectof(string*t)array|Arrayoftarrayletfold(y:t)(f1:'a)(f2:string->'a)(f3:(string*'a)array->'a)(f4:'aarray->'a):'a=letrecfld=function|Empty->f1|Scalars->f2s|Objectarr->f3@@Array.map(fun(s,y)->s,fldy)arr|Arrayarr->f4@@Array.mapfldarrinfldyletto_string(y:t):string=foldy"Empty"identity(funarr->"{"^String.concat";"(List.map(fun(key,v)->key^":"^v)(Array.to_listarr))^"}")(funarr->"["^String.concat","(Array.to_listarr)^"]")moduleParser=structtypet0=tmoduleP=Character_parser.Simple(structtypet=t0end)includePletscalar:stringt=wordChar.is_letter(func->Char.is_letterc||Char.is_digitc||c='_'||c='-')"atom"letwhitespace_char:chart=expect(func->c=' '||c='\n'||c='\t')"space, newline or tab"letwhite_space:intt=detached(skip_zero_or_more(map(fun_->())whitespace_char))letrecyaml():t0t=letkey_value=get_bounds>>=fun(lb,ub)->letopenPrintfinprintf"key_value lb %d"lb;(matchubwith|None->printf"\n"|Someub->printf", ub %d\n"ub);scalar>>=funkey->char':'>>=fun_->white_space>>=fun_->indented(yaml())>>=funv->white_space>>=fun_->return(key,v)anditem=char'-'>>=fun_->white_space>>=fun_->yaml()>>=funv->white_space>>=fun_->returnvinletscalar_or_object=scalar>>=funstr->(char':'>>=fun_->white_space>>=fun_->indented(yaml())>>=funv->white_space>>=fun_->zero_or_more(absolutekey_value)>>=funlst->return(Object(Array.of_list@@(str,v)::lst)))<|>return(Scalarstr)andlist=char'-'>>=fun_->white_space>>=fun_->indented(yaml())>>=funv->white_space>>=fun_->zero_or_more(absoluteitem)>>=funlst->return@@Array(Array.of_list@@v::lst)inabsolute@@(scalar_or_object<|>list<|>returnEmpty)letresult_string(p:parser):string=P.result_stringpto_stringletmake():parser=P.make(returnidentity|=yaml()|.expect_end)letrun(str:string):parser=P.run(returnidentity|=yaml()|.expect_end)strend(* ------------------------------------------------------------------
Unit Test
------------------------------------------------------------------ *)letstring_of_resultres=matchreswith|Oky->to_stringy|Error_->"ERROR"let_=string_of_result(*
let%test _ =
let open Parser in
let p = run "" in
Printf.printf "%s\n" (string_of_result (result p));
has_ended p
&& column p = 0
&& result p = Ok Empty
let%test _ =
let open Parser in
let p = run "hello" in
Printf.printf "%s\n" (result_string p);
has_ended p
&& column p = 5
&& result p = Ok (Scalar "hello")
let%test _ =
let open Parser in
let str = "a:x\nb:y\nc:z\n " in
let p = run str in
Printf.printf "string <%s>\n" (String.escaped str);
Printf.printf "line %d, column %d\n" (line p) (column p);
Printf.printf "%s\n" (result_string p);
Printf.printf "lookahead %s\n" (lookahead_string p);
has_ended p
let%test _ =
let open Parser in
let str = "a:x\nb:y\n c:z" in
let p = run str in
Printf.printf "string <%s>\n" (String.escaped str);
Printf.printf "line %d, column %d\n" (line p) (column p);
Printf.printf "%s\n" (result_string p);
Printf.printf "lookahead %s\n" (lookahead_string p);
has_ended p
let%test _ =
let open Parser in
let str = "a:x\nb:y\nc:\n -d\n -e" in
let p = run str in
Printf.printf "string <%s>\n" (String.escaped str);
Printf.printf "line %d, column %d\n" (line p) (column p);
Printf.printf "%s\n" (result_string p);
Printf.printf "lookahead %s\n" (lookahead_string p);
has_ended p
let%test _ =
let open Parser in
let str = "a:x\nb:y\nc:\n -b1\n -b2\nd: \n z" in
let p = run str in
Printf.printf "string <%s>\n" (String.escaped str);
Printf.printf "line %d, column %d\n" (line p) (column p);
Printf.printf "%s\n" (result_string p);
Printf.printf "lookahead %s\n" (lookahead_string p);
has_ended p
&& line p = 6
&& column p = 4
*)