247 lines · 10.1 KB · Standard ML
RawDownload
(* Parsercomb -- parser combinators *) signature Parsercomb =sig    type 'elm stream    type ('elm, 'res) parser = 'elm stream -> ('res * 'elm stream) option           exception Parse of string     val stream     : ('src -> ('elm * 'src) option) -> 'src -> 'elm stream     val --         : ('a, 'b) parser * ('a, 'c) parser -> ('a, 'b * 'c) parser    val ||         : ('a, 'b) parser * ('a, 'b) parser -> ('a, 'b) parser    val >>         : ('a, 'b) parser * ('b -> 'c) -> ('a, 'c) parser    val >>*        : ('a, 'b) parser * ('b -> 'c option) -> ('a, 'c) parser    val >>=        : ('a, 'b) parser * ('b -> ('a, 'c) parser)                      -> ('a, 'c) parser	    val #--        : ('elm, 'a) parser * ('elm, 'b) parser -> ('elm, 'b) parser    val --#        : ('elm, 'a) parser * ('elm, 'b) parser -> ('elm, 'a) parser     val $--        : string * (char, 'a) parser -> (char, 'a) parser    val --$        : (char, 'a) parser * string -> (char, 'a) parser     val repeat0    : ('elm, 'res) parser -> ('elm, 'res list) parser    val repeat1    : ('elm, 'res) parser -> ('elm, 'res * 'res list) parser    val optional   : ('elm, 'res) parser -> ('elm, 'res option) parser      val getItem    : ('elm, 'elm) parser    val failure    : ('elm, 'res) parser    val success    : 'res -> ('elm, 'res) parser    val eof        : 'res -> ('elm, 'res) parser     val $#         : char   -> (char, char) parser    val $          : string -> (char, string) parser     val getLit     : ''elm -> (''elm, ''elm) parser     val getChar    : (char -> bool) -> (char, char) parser    val getChars0  : (char -> bool) -> (char, string) parser    val getChars1  : (char -> bool) -> (char, string) parser     val getElem    : ('elm -> bool) -> ('elm, 'elm) parser    val getElems0  : ('elm -> bool) -> ('elm, 'elm list) parser    val getElems1  : ('elm -> bool) -> ('elm, 'elm * 'elm list) parser     val commitChar : string -> (char, 'res) parser -> (char, 'res) parser    val commitElem : string -> ('elm -> string)                      -> ('elm, 'res) parser -> ('elm, 'res) parser     (* Applying a parser to a stream *)     val parse      : ('elm, 'res) parser -> 'elm stream -> 'res option     val scan       : (('a, 'a stream) StringCvt.reader -> 'a stream -> 'b)                     -> 'a stream -> 'b     val skipWS     : (char, 'res) parser -> (char, 'res) parser     val scanString : (char, 'res) parser -> string -> 'res option     val scanSubstr : (char, 'res) parser -> substring -> 'res option    val scanList   : ('elm, 'res) parser -> 'elm list -> 'res optionend (*    ['elm stream] is the type of a lazy streams (sequences) of 'elm values.    [('elm, 'res) parser] is the type of parsers that consume elements   from an 'elm stream to produce a result of type 'res.  The attempt   may succeed with a result of type 'res, in which case the parser   may have consumed elements of the stream, or it may fail, in which   case the 'elm stream remains unchanged.    Below we indicate those parsers that are guaranteed to consume from   the stream if they succeed.  Such parsers can be safely used as the   argument to e.g. the repeat0 and repeat1 parser-transformers.    [stream getc src] builds a stream from a reader getc and a stream   state src.    [par1 -- par2] succeeds with (r1, r2) if par1 succeeds with r1 and   then par2 succeeds with r2 on the remainder of the stream.    [par1 || par2] succeeds with r1 if par1 succeeds with r1 on stream;   otherwise succeeds with r2 if par2 succeeds with r2 on stream;   otherwise fails.    [par >> f] succeeds with f(r) if par succeeds with r on the stream.    [par >>* f] succeeds with y if par succeeds with r on the stream,   and f r = SOME y; fails otherwise.    [par1 >>= parf2] succeeds with r2 if par1 succeeds with r1 and then   (parf2 r1) succeeds with r2 on the remainder of the stream.    [par1 #-- par2] succeeds with r2 if par1 succeeds with r1 and   then par2 succeeds with r2 on the remainder of the stream.    [par1 --# par2] succeeds with r1 if par1 succeeds with r1 and   then par2 succeeds with r2 on the remainder of the stream.    [s $-- par] succeeds with r if the stream begins with the   characters of the string s, and par succeeds with r on the   remainder of the stream.    [par $-- s] succeeds with r if p succeeds with r, and then the   remainder of the stream begins with the characters of the string s.    Recommended fixities:         infix 6 $-- --$ #-- --#        infix 5 --        infix 3 >> >>*        infix 2 >>=        infix 0 ||    [repeat0 par] succeeds with [r1, r2, ..., rn] if par succeeds with   r1, and then par succeeds with r2 on the remainder of the stream,   and then par succeeds with r3 on the remainder, etc, for some n>=0.   May succeed without consuming from the stream, even if par must   consume from the stream to succeed.    [repeat1 par] succeeds with (r1, [r2, ..., rn]) if par succeeds   with r1, and then par succeeds with r2 on the remainder of the   stream, and then par succeeds with r3 on the remainder, etc, for   some n>=1.  Must consume from the stream to succeed, provided par   must consume from the stream to succeed.  Equivalent to         par -- repeat0 par    [optional par] succeeds with SOME(r) if par succeeds with r;   succeeds with NONE otherwise.  May succeed without consuming from   the stream.  Equivalent to         par || succeed NONE    [success v] always succeeds with v, consuming nothing from the stream.    [failure] always fails.    [getItem] succeeds with r if the stream is non-empty and its first   element is r; fails otherwise.  Must consume from the stream if it   succeeds.    [eof v] succeeds with v if the stream is empty (end of file); fails   otherwise.     [$# c] succeeds with c if the stream begins with character c.   Consumes from the stream if it succeeds.    [$ s] succeeds with s if the stream begins with string s.  Consumes   from the stream if it succeeds.    [getChar p] succeeds with c if the first character c of the   stream satisfies predicate p.  Consumes from the stream if it   succeeds.    [getChars0 p] always succeeds with s, where s is the longest prefix   of the stream all of whose characters satisfy predicate p.  May   succeed without consuming from the stream.  Equivalent to         repeat0 (getChar p) >> String.implode    [getChars1 p] succeeds with s, where s is the longest non-empty   prefix of the stream all of whose characters satisfy predicate p,   if such a prefix exists; fails if the first character of the stream   does not satisfy p.  Consumes from the stream if it succeeds.     Equivalent to        repeat1 (getChar p) >> op:: >> String.implode    [getLit elm] succeeds with elm if the first element of the stream   equals elm; fails otherwise.  Consumes from the stream if it   succeeds.    [getElem p] succeeds with elm if the first element elm of the   stream satisfies predicate p.  Consumes from the stream if it   succeeds.    [getElems0 p] always succeeds with elms, where elms is the longest   prefix of the stream all of whose elements satisfy predicate p.   May succeed without consuming from the stream.  Equivalent to         repeat0 (getElem pred) strm     [getElems1 p] succeeds with (elm1, elmr), where elm1::elmr is the   longest non-empty prefix of the stream all of whose elements   satisfy predicate p; fails if the first element of the stream does   not satisfy p.  Consumes from the stream if it succeeds.   Equivalent to         repeat1 (getElem pred) strm    [commitChar cexpd par] succeeds with r if par succeeds with r;   raises exception Parse otherwise.  The exception's string argument   will have the form      Expected <cexpd> but found <cfound> at character number n   where cfound is the first character of the stream to which   commitChar is applied, or the text "eof" if that stream is empty,   and n is the number of the stream character cfound counting from the   beginning of the stream.  The first character has number 0.    [commitElem eexpd showe par] succeeds with r if par succeeds with r;   raises exception Parse otherwise.  The exception's string argument   will have the form      Expected <eexpd> but found <efound> at element number n   where efound is the result of applying showe to the first element   of the stream, or the text "eof" if the stream is empty, and n is   the number of stream element efound counting from the beginning of   the stream.  The first element has number 0.    [parse par strm] applies the parser par to the stream strm.   Returns SOME(v) if the parser succeeds with v; returns NONE   otherwise.    [scan scfn] produces a parser corresponding to the scan function   scfn.  Typical examples are:         scan Bool.scan                  : (char, bool) parser        scan Date.scan                  : (char, Date.date) parser        scan Real.scan                  : (char, real) parser        scan Time.scan                  : (char, Time.time) parser        scan (Int.scan StringCvt.DEC)   : (char, int) parser        scan (Word.scan StringCvt.HEX)  : (char, Word.word) parser        scan (Word8.scan StringCvt.HEX) : (char, Word8.word) parser    For instance, one may produce a list of real numbers by parsing   space-separated real numerals from a string s:      scanString (repeat0 (getChars0 Char.isSpace #-- scan Real.scan)) s    [skipWS par] removes any leading whitespace from the stream and   then applies par to the remainder.    [scanSubstring par sus] applies the parser par to the stream of   characters taken from the substring sus.  Returns SOME v if par   succeeds with v; returns NONE otherwise.  Equivalent to         parse par (stream Substring.getc sus)    [scanString par s] applies the parser par to the stream of   characters taken from the string s.  Returns SOME v if par succeeds   with v; returns NONE otherwise.    Example: Parsing an integer numeral from the string "723984626junk":       val intphr = getChars1 Char.isDigit      val i : string option = scanString intphr "723984626junk"    [scanList phr xs] applies the parser par to the stream of elements   from the list xs.  Returns SOME v if par succeeds with v; returns    NONE otherwise.  Equivalent to         parse par (stream List.getItem cs)*)