12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273(** Parsing of infix operators using the Pratter library.
The interface for the Pratter library can be seen at
@see <https://forge.tedomum.net/koizel/pratter>. *)openCommonopenCoreopenSyntaxmodulePratt:sigvalparse:Sig_state.t->Env.t->p_term->p_term(** [parse ss env t] Pratt parses term [t], unsugaring infix operators and
prefix operators using signature state [ss] and environment [env] to
determine which term is an operator, and to build new terms. Note that
it doesn't recurse into abstractions or implications and alike. *)end=structopenLplibopenPosmodulePratt_terms:Pratter.SUPPORTwithtypeterm=p_termandtypetable=Sig_state.t*Env.t=structtypeterm=p_termtypetable=Sig_state.t*Env.t(* Get properties of term [t] if its an operator. *)letget(tbl,env)t=matcht.eltwith|P_Iden({elt=(mp,s);_}asid,false)->letsym=try(* Look if [id] is in [env]... *)ifmp<>[]thenraiseNot_found;ignore(Env.findsenv);NonewithNot_found->(* ... or look into the signature *)Some(Sig_state.find_sym~prt:true~prv:truetblid)inletfsym=matchTerm.SymMap.find_optsymtbl.notationswith|Some(Infix(assoc,prio))->Some(Pratter.Infixassoc,prio)|Some(Prefix(prio))->Some(Pratter.Prefix,prio)|Some(Postfix(prio))->Some(Pratter.Postfix,prio)|Some(Zero|Succ|Quant)->None|None->NoneinOption.bindfsym|_->Noneletmake_appltu=Pos.make(Pos.catt.posu.pos)(P_Appl(t,u))end(* NOTE the term is converted from appl nodes to list in [Pratt.parse],
rebuilt into appl nodes by [Pratt.parse], and then decomposed again into a
list by [get_args]. We could make [Pratt.parse] return a list of terms
instead. *)letparse:Sig_state.t->Env.t->p_term->p_term=funstenvt->leth,args=Syntax.p_get_argstinletstrm=Stream.of_list(h::args)inletmoduleParse=Pratter.Make(Pratt_terms)inmatchParse.expression(st,env)strmwith|Oke->e|Error`TooFewArguments->Error.fatalt.pos"Malformed application in \"%a\""Pretty.termt|Error`OpConflict(t,u)->Error.fatalt.pos"Operator conflict between \"%a\" and \"%a\""Pretty.termtPretty.termu|Error`UnexpectedInfixt->Error.fatalt.pos"Unexpected infix operator \"%a\""Pretty.termt|Error`UnexpectedPostfixt->Error.fatalt.pos"Unexpected postfix operator \"%a\""Pretty.termtendincludePratt