1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495openCoreopenMParserletto_stringfromuntilbetween:string=from^(String.of_char_listbetween)^untilletanything_including_newlines~until=(many(not_followed_by(stringuntil)"">>=fun()->any_char_or_nl))letanything_excluding_newlines~until=(many(not_followed_by(stringuntil)"">>=fun()->any_char))(** a parser for comments with delimiters [from] and [until] that do not nest *)letnon_nested_commentfromuntils=(between(stringfrom)(stringuntil)(anything_including_newlines~until)|>>to_stringfromuntil)sletuntil_newlinestarts=(stringstart>>anything_excluding_newlines~until:"\n"|>>funl->start^(String.of_char_listl))sletany_newlinecomment_strings=(stringcomment_string>>anything_excluding_newlines~until:"\n"|>>funl->(comment_string^String.of_char_listl))sletis_notps=ifis_ok(ps)thenEmpty_failed(unknown_errors)elsematchread_charswith|Somec->Consumed_ok(c,advance_states1,No_error)|None->Empty_failed(unknown_errors)(** A nested comment parser *)letnested_commentfromuntils=letreserved=skip((stringfrom)<|>(stringuntil))inletrecgrammars=((comment_delimiters>>=funstring->returnstring)<|>(is_notreserved>>=func->return(Char.to_stringc)))sandcomment_delimiterss=(between(stringfrom)(stringuntil)((manygrammar)>>=funresult->return(String.concatresult)))sin(comment_delimiters|>>funcontent->from^content^until)s(** a parser for, e.g., /* ... */ style block comments. Non-nested. *)moduleMultiline=structmoduletypeS=sigvalleft:stringvalright:stringendmoduleMake(M:S)=structletcomments=non_nested_commentM.leftM.rightsendendmoduleUntil_newline=structmoduletypeS=sigvalstart:stringendmoduleMake(M:S)=structletcomments=until_newlineM.startsendendmoduleNested_multiline=structmoduletypeS=sigvalleft:stringvalright:stringendmoduleMake(M:S)=structletcomments=nested_commentM.leftM.rightsendend