Source

oni / cf / cf_llscan.mli

(*---------------------------------------------------------------------------*
  $Change$
  Copyright (C) 2011, james woodyatt
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  
    Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
    
    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  OF THE POSSIBILITY OF SUCH DAMAGE. 
 *---------------------------------------------------------------------------*)

(** Functional LL(x) parsing with monadic combinators. *)

(** This module implements function left-shift/left-reduce parser combinators
    using a state-exception monad over the input stream.  To evaluate a scanner
    monad is to parse an input stream.  The state monad is lifted into the
    exception monad to facilitate backtracking.  Scanners should signal errors
    in the input stream with ordinary Objective Caml exceptions.
*)

(** The scanner monad.  A function that parses a sequence of input tokens.
    Returns [None] if the parser does not recognize any symbols.  Otherwise
    returns the reduced output and the remainder of the input tokens.
*)
type ('s, 'r) t = 's Cf_seq.t -> ('r * 's Cf_seq.t) option

(** A scanner that never recognizes input, i.e. it always returns [None]. *)
val nil: ('s, 'r) t

(** The return scanner.  Use [ret x] to produce the result [x] without
    processing any more input.
*)
val ret: 'r -> ('s, 'r) t

(** The binding function.  Use [bind p f] to compose a scanner that passes the
    output of parser [p] to the bound function [f] which returns the scanner
    for the next symbol in a parsing rule.  This is normal function version of
    the [Op.( >>= )] infix operator.
*)
val bind: ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t

(** A scanner that produces the unit value when it recognizes the end of the
    input token sequence.
*)
val fin: ('s, unit) t

(** A scanner that recognizes, shifts and produces any input token. *)
val any: ('s, 's) t

(** Use [eq x] to compose a scanner that recognizes [x] in the input stream,
    shifts and returns it. *)
val eq: 's -> ('s, 's) t

(** Use [sat f] to create a scanner that recognizes, shifts and reduces input
    tokens for which the satisfier function [f] returns [true].
*)
val sat: ('s -> bool) -> ('s, 's) t

(** Use [tok f] to recognize and shift input tokens for which the tokenizer
    function [f] reduces an output value.
*)
val tok: ('s -> 'r option) -> ('s, 'r) t

(** Use [lit s obj] to obtain a parser on character input sequences that
    produces the output [obj] when it recognizes the literal [s] in the input.
*)
val lit: string -> 'r -> (char, 'r) t

(** The optional scanner composer.  Use [opt p] to create a scanner that
    recognizes an optional symbol in the input stream with the scanner [p].  If
    the symbol is recognized, its tokens are shifted and reduced as [Some obj],
    otherwise no tokens are shifted and the reduced value is [None].
    Scanner functions created with this operator {i always} return [Some r],
    where [r] is the reduced value, i.e. either [Some obj] or [None].  This is
    the normal function version of the [Op.( ?/ )] prefix operator.
*)
val opt: ('s, 'r) t -> ('s, 'r option) t

(** The list scanner composer.  Use [seq p] to create a scanner that
    recognizes zero or more symbols in the input stream with the scanner [p].
    The tokens of all the symbols recognized are shifted and reduced as a list
    of objects in the order of their appearance in the input stream.  Scanner
    functions created with this operator {i always} return [Some r], where [r]
    is the reduced list of symbols, which may be the empty list if there are no
    symbols recognized.  This is the normal function version of the [Op.( ?* )]
    prefix operator.
*)
val seq: ('s, 'r) t -> ('s, 'r list) t

(** The non-empty list scanner composer.  Use [seq1 p] to create a scanner that
    recognizes one or more symbols in the input stream with the scanner [p].
    If the symbols are recognized in the input stream, then their tokens are
    shifted and reduced into a list of objects in the order of their
    appearance in the input stream.  Otherwise, no tokens are shifted and
    no output is reduced.  This is the normal function version of the
    [Op.( ?+ )] prefix operator.
*)
val seq1: ('s, 'r) t -> ('s, 'r * 'r list) t

(** Use [alt ps] to create a scanner that produces the output from the first
    scanner in the list [ps] that recognizes a pattern in the input.  If no
    scanner in the list recognizes a pattern, then the scanner constructed by
    this function returns [None].  This is the normal function version of the
    [Op.( ?^ )] prefix operator.
*)
val alt: ('s, 'r) t list -> ('s, 'r) t

(** Use [altz ps] to create a scanner that produces the output from the first
    scanner in the lazy sequence [ps] that recognizes a pattern in the input.
    If no scanner in the sequence recognizes a pattern, then the scanner
    constructed by this function returns [None]. This is the normal function
    version of the [Op.( ?^~ )] prefix operator.
*)
val altz: ('s, 'r) t Cf_seq.t -> ('s, 'r) t

(** Generic parser error with no parameters. *)
exception Error

(** Use [err ?f ()] to compose scanner that applies the input token stream to
    the optional function [f] to obtain an Objective Caml exception, then
    raises the exception.  The default function simply raises [Error].
*)
val err: ?f:('s Cf_seq.t -> exn) -> unit -> ('s, 'r) t

(** Use [req f p] to create a scanner that requires the input stream to match
    the scanner [p] or it will be passed to the parser [err f] instead.
*)
val req: ?f:('s Cf_seq.t -> exn) -> ('s, 'r) t -> ('s, 'r) t

(** Use [unfold p i] to create a sequence of output values recognized by
    applying the input token sequence [i] to the parser [p] until no more
    input is recognized.
*)
val unfold: ('s, 'r) t -> 's Cf_seq.t -> 'r Cf_seq.t

(** Open this module to take the parser operators into the current scope. *)
module Op: sig
    (** The infix operator version of the [bind] composer. *)
    val ( >>= ): ('s, 'a) t -> ('a -> ('s, 'b) t) -> ('s, 'b) t
    
    (** The prefix operator version of the [eq] composer. *)
    val ( ?. ): 's -> ('s, 's) t
    
    (** The prefix operator version of the [opt] composer. *)
    val ( ?/ ): ('s, 'r) t -> ('s, 'r option) t
    
    (** The prefix operator version of the [seq1] composer. *)
    val ( ?+ ): ('s, 'r) t -> ('s, 'r * 'r list) t
    
    (** The prefix operator version of the [seq1] composer. *)
    val ( ?* ): ('s, 'r) t -> ('s, 'r list) t
    
    (** The prefix operator version of the [alt] composer. *)
    val ( ?^ ): ('s, 'r) t list -> ('s, 'r) t
    
    (** The prefix operator version of the [altz] composer. *)
    val ( ?^~ ): ('s, 'r) t Cf_seq.t -> ('s, 'r) t
end

(*--- $File$ ---*)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.