Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file generic_parser.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522openModule_typesmoduletypeERROR=sigtypettypesemantictypeexpectvalis_semantic:t->boolvalsemantic:t->semanticvalexpectations:t->expectlistvalmake_semantic:semantic->tvalmake_expectations:expectlist->tendmoduleError(Expect:ANY)(Semantic:ANY)=structtypeexpect=Expect.ttypesemantic=Semantic.ttypet=|SyntaxofExpect.tlist|SemanticofSemantic.tletto_string(e:t)(f:Expect.t->string)(g:Semantic.t->string):string=matchewith|Syntaxlst->"["^String.concat", "(List.rev_mapflst)^"]"|Semanticsem->gsemletinit:t=Syntax[]letadd_expected(exp:Expect.t)(e:t):t=matchewith|Syntaxlst->Syntax(exp::lst)|_->Syntax[exp]letmake_semantic(sem:Semantic.t):t=Semanticsemletmake_expectations(lst:Expect.tlist):t=Syntax(List.revlst)letis_semantic(e:t):bool=matchewith|Syntax_->false|_->trueletsemantic(e:t):Semantic.t=matchewith|Syntax_->assertfalse(* Illegal call! *)|Semanticsem->semletexpectations(e:t):Expect.tlist=matchewith|Syntaxes->List.reves|Semantic_->assertfalse(* Illegal call! *)endmoduletypeCOMBINATORS=sigtype'attypesemanticvalreturn:'a->'atvalsucceed:'a->'atvalfail:semantic->'atvalconsumer:'at->'atvalmap:('a->'b)->'at->'btval(>>=):'at->('a->'bt)->'btval(<|>):'at->'at->'atvaloptional:'at->'aoptiontvalone_of:'atlist->'atvalzero_or_more:'at->'alisttvalone_or_more:'at->'alisttvalone_or_more_separated:'at->_t->'alisttvalzero_or_more_separated:'at->_t->'alisttvalskip_zero_or_more:'at->inttvalskip_one_or_more:'at->inttval(|=):('a->'b)t->'at->'btval(|.):'at->_t->'atendmoduleBuffer(S:ANY)(T:ANY)(Expect:ANY)(Semantic:ANY)=structtypestate=S.ttypetoken=T.tmoduleError=Error(Expect)(Semantic)typeerror=Error.ttypet={state:state;has_consumed:bool;error:error;la_ptr:int;(* position of first lookahead token *)is_buffering:bool;toks:tokenarray}letinit(st:state):t={state=st;has_consumed=false;error=Error.init;la_ptr=0;is_buffering=false;toks=[||]}letstate(b:t):state=b.stateleterror(b:t):error=b.errorletcount_toks(b:t):int=Array.lengthb.tokslethas_lookahead(b:t):bool=b.la_ptr<count_toksbletlookahead_toks(b:t):tokenarray=letlen=count_toksb-b.la_ptrinArray.subb.toksb.la_ptrlenletlookahead(b:t):tokenlist=Array.(to_list(lookahead_toksb))letlookahead_token(b:t):token=assert(has_lookaheadb);b.toks.(b.la_ptr)letpush_token(t:token)(b:t):t=ifnotb.is_buffering&&b.la_ptr=count_toksbthen{bwithla_ptr=0;toks=[|t|]}else{bwithtoks=Array.pushtb.toks}letupdate(f:state->state)(b:t):t={bwithstate=fb.state}letadd_expected(e:Expect.t)(b:t):t={bwitherror=Error.add_expectedeb.error}letput_error(e:Semantic.t)(b:t):t={bwitherror=Error.make_semantice}letclear_errors(b:t):t={bwitherror=Error.init}letconsume(state:state)(b:t):t=assert(has_lookaheadb);{bwithstate;has_consumed=true;error=Error.init;la_ptr=1+b.la_ptr}letreject(e:Expect.t)(b:t):t=add_expectedebletstart_new_consumer(b:t):t={bwithhas_consumed=false}lethas_consumed(b:t):bool=b.has_consumedletend_new_consumer(b0:t)(b:t):t={bwithhas_consumed=b0.has_consumed||b.has_consumed}letstart_alternatives(b:t):t={bwithhas_consumed=false}letend_failed_alternatives(e:Expect.t)(b0:t)(b:t):t=ifb.has_consumedthenbelse{bwithhas_consumed=b0.has_consumed;error=Error.add_expectedeb0.error}letend_succeeded_alternatives(b0:t)(b:t):t=ifb.has_consumedthenbelse{bwithhas_consumed=b0.has_consumed;error=b0.error}letstart_backtrack(b:t):t={bwithis_buffering=true}letend_backtrack_success(b0:t)(b:t):t=ifb0.is_bufferingthenbelse{bwithis_buffering=false;toks=lookahead_toksb;(* only lookahead token *)la_ptr=0}letend_backtrack_fail(e:Expect.toption)(b0:t)(b:t):t={b0withtoks=b.toks;error=matchewith|None->b0.error|Somee->Error.add_expectedeb0.error}endmoduleMake(T:ANY)(S:ANY)(Expect:ANY)(Semantic:ANY)(F:ANY)=structtypetoken=T.tmoduleError=Error(Expect)(Semantic)typestate=S.ttypefinal=F.ttypeexpect=Expect.ttypesemantic=Semantic.tmoduleB=Buffer(S)(T)(Expect)(Semantic)typeparser=|MoreofB.t*(B.t->parser)|FinalofB.t*finaloptionletneeds_more(p:parser):bool=matchpwith|More_->true|Final_->falselethas_ended(p:parser):bool=not(needs_morep)letput_token(p:parser)(t:token):parser=letpush_tokentp=matchpwith|More(b,f)->More(B.push_tokentb,f)|Final(b,res)->Final(B.push_tokentb,res)inletrecprocess_lookaheadp=matchpwith|More(b,f)whenB.has_lookaheadb->process_lookahead(fb)|_->pinprocess_lookahead(push_tokentp)letstate(p:parser):state=matchpwith|More(b,_)|Final(b,_)->B.statebletresult(p:parser):finaloption=matchpwith|Final(_,r)->r|_->assertfalse(* Illegal call! *)leterror(p:parser):Error.t=matchpwith|Final(b,_)|More(b,_)->B.errorbleterror_string(p:parser)(f:Expect.t->string)(g:Semantic.t->string):string=Error.to_string(errorp)fgletlookahead(p:parser):tokenlist=matchpwith|Final(b,_)->B.lookaheadb|_->assertfalse(* Illegal call! *)lethas_succeeded(p:parser):bool=matchpwith|Final(_,Some_)->true|_->falselethas_failed(p:parser):bool=not(has_succeededp)type'acont='aoption->B.t->parsertype'at=B.t->'acont->parserletmake_parser(s:state)(p:finalt):parser=p(B.inits)(funresb->Final(b,res))letupdate(f:state->state)(b:B.t)(k:unitcont):parser=k(Some())(B.updatefb)letget(b:B.t)(k:statecont):parser=k(Some(B.stateb))bletget_and_update(f:state->state)(b:B.t)(k:statecont):parser=letst=B.statebink(Somest)(B.updatefb)(* Basic Combinators *)letreturn(a:'a)(b:B.t)(k:'acont):parser=k(Somea)bletsucceed(a:'a)(b:B.t)(k:'acont):parser=k(Somea)(B.clear_errorsb)letfail(e:Semantic.t):'at=funbk->kNone(B.put_erroreb)letunexpected(exp:expect):'at=funbk->kNone(B.add_expectedexpb)lettoken(f:state->token->('a*state,Expect.t)result)(b:B.t)(k:'acont):parser=More(b,funb->matchf(B.stateb)(B.lookahead_tokenb)with|Ok(a,s1)->k(Somea)(B.consumes1b)|Errore->kNone(B.rejecteb))letmap(f:'a->'b)(p:'at)(b:B.t)(k:'bcont):parser=pb(funob->matchowith|None->kNoneb|Somea->k(Some(fa))b)letconsumer(p:'at):'at=funb0k->p(B.start_new_consumerb0)(funresb->letconsumed=B.has_consumedbinassert(res=None||consumed);kres(B.end_new_consumerb0b))let(>>=)(p:'at)(f:'a->'bt)(b:B.t)(k:'bcont):parser=pb(funob->matchowith|Somea->fabk|None->kNoneb)let(<|>)(p:'at)(q:'at):'at=funb0k->p(B.start_new_consumerb0)(funresb->letconsumed=B.has_consumedbinletb=B.end_new_consumerb0binmatchreswith|Nonewhennotconsumed->(* p failed and did not consume tokens *)qbk|_->kresb)let(<?>)(p:'at)(e:Expect.t):'at=funb0k->p(B.start_alternativesb0)(funresb->matchreswith|None->kNone(B.end_failed_alternativeseb0b)|Somea->k(Somea)(B.end_succeeded_alternativesb0b))letbacktrackable(p:'at)(e:Expect.t):'at=funb0k->p(B.start_backtrackb0)(funresb->kres(matchreswith|None->B.end_backtrack_fail(Somee)b0b|Some_->B.end_backtrack_successb0b))letnot_followed_by(p:'at)(exp:expect):unitt=funb0k->p(B.start_backtrackb0)(funresb->matchreswith|None->k(Some())(B.end_backtrack_failNoneb0b)|Some_->kNone(B.end_backtrack_fail(Someexp)b0b))(* Advanced Combinators *)let(|=)(p:('a->'b)t)(q:'at):'bt=p>>=funf->mapfqlet(|.)(p:'at)(q:_t):'at=p>>=funa->q>>=fun_->returnaletoptional(p:'at):'aoptiont=(map(funa->Somea)p)<|>returnNoneletrecone_of(l:'atlist):'at=matchlwith|[]->assertfalse(* Illegal call *)|[p]->p|p::ps->p<|>one_ofpsletzero_or_more(p:'at):'alistt=letrecmanyl=(consumerp>>=funa->many(a::l))<|>return(List.revl)inmany[]letone_or_more(p:'at):'alistt=p>>=funa->zero_or_morep>>=funl->return(a::l)letskip_zero_or_more(p:'at):intt=letrecmanyi=(consumerp>>=fun_->many(i+1))<|>returniinmany0letskip_one_or_more(p:'at):intt=return(funn->n+1)|.p|=skip_zero_or_morepletone_or_more_separated(p:'at)(sep:_t):'alistt=return(funal->a::l)|=p|=zero_or_more(sep>>=fun_->p)letzero_or_more_separated(p:'at)(sep:_t):'alistt=one_or_more_separatedpsep<|>return[]end(* Make *)