(* $Id$ * ---------------------------------------------------------------------- * *) open Parser open Ast (* Overall scheme: * * The rules are translated to: * * let rec parse_ ... = ... * and parse_ ... = ... * and ... * and parse_ ... = ... * in * * Every rule has at least two arguments: 'current' and 'get_next'. * 'current()' is the token that should match the first symbol of the * rule. 'get_next()' returns the next token. * * The rules may have further user arguments; these are the next arguments * in turn. * * The rules return the user value. After they have returned to the caller * the current token is the token that follows the sequence of tokens * matching the rule. * * The rules will raise: * - Not_found if the first token does not match * - Parsing.Parse_error if the rest does not match. * * Rule scheme: * * rule(arg1,arg2,...): * (l1:x1) * {{ let-CODE }} * (l2:y2(name1,...)) y3 ... * {{ CODE }} * ? {{ ?-CODE }} * | x2 ... * | ... * | xN * * let parse_ current get_next arg1 arg2 ... = * match current() with * S(x1) -> ... * | S(x2) -> ... * | ... * | S(xN) -> ... * | _ -> raise Not_found * * Here, S(xi) denotes the set of tokens matched by xi without all tokens * already matched by x1 to x(i-1). (If S(xi) = empty, a warning is printed, * and this branch of the rule is omitted.) * * S(xi) may be a set because xi may be a reference to another rule. In this * case, S(xi) bases on the set of tokens that match the first symbol of * the other rule. (In general, S(xi) must be computed recursively.) * * If the "?" clause is present, every branch is embraced by the following: * * let position = ref "