123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227letsplit_pos{Lexing.pos_lnum;pos_bol;pos_cnum;_}=pos_lnum,pos_cnum-pos_bolletrev_filter~fxs=letrecauxfacc=function|x::xswhenfx->auxf(x::acc)xs|_::xs->auxfaccxs|[]->accinauxf[]xsletrecrev_scan_leftacc~f~init=function|[]->acc|x::xs->letinit=finitxinrev_scan_left(init::acc)~f~initxsmoduleMake(Parser:MenhirLib.IncrementalEngine.EVERYTHING)(Recovery:sigvaldefault_value:Location.t->'aParser.symbol->'atypeaction=|Abort|Rofint|S:'aParser.symbol->action|Subofactionlisttypedecision=|Nothing|Oneofactionlist|Selectof(int->actionlist)valdepth:intarrayvalrecover:int->decisionvalguide:'aParser.symbol->boolvaltoken_of_terminal:'aParser.terminal->'a->Parser.tokenvalnullable:'aParser.nonterminal->boolend)=structtype'acandidate={line:int;min_col:int;max_col:int;env:'aParser.env}type'acandidates={shifted:Parser.xsymboloption;final:'aoption;candidates:'acandidatelist}moduleT=struct[@@@ocaml.warning"-37"]type'acheckpoint=|InputNeededof'aParser.env|Shiftingof'aParser.env*'aParser.env*bool|AboutToReduceof'aParser.env*Parser.production|HandlingErrorof'aParser.env|Acceptedof'a|Rejectedexternalinj:'acheckpoint->'aParser.checkpoint="%identity"endletfeed_token~allow_reductiontokenenv=letrecauxallow_reduction=function|Parser.HandlingError_|Parser.Rejected->`Fail|Parser.AboutToReduce_whennotallow_reduction->`Fail|Parser.Acceptedv->`Acceptv|(Parser.Shifting_|Parser.AboutToReduce_)ascheckpoint->auxtrue(Parser.resumecheckpoint)|Parser.InputNeededenvascheckpoint->`Recovered(checkpoint,env)inauxallow_reduction(Parser.offer(T.inj(T.InputNeededenv))token)letrecfollow_guidecolenv=matchParser.topenvwith|None->col|Some(Parser.Element(state,_,pos,_))->ifRecovery.guide(Parser.incoming_symbolstate)thenmatchParser.popenvwith|None->col|Someenv->follow_guide(snd(split_pospos))envelsecolletcandidateenv=letline,min_col,max_col=matchParser.topenvwith|None->1,0,0|Some(Parser.Element(state,_,pos,_))->letdepth=Recovery.depth.(Parser.numberstate)inletline,col=split_posposinifdepth=0thenline,col,colelseletcol'=matchParser.pop_manydepthenvwith|None->max_int|Someenv->(matchParser.topenvwith|None->max_int|Some(Parser.Element(_,_,pos,_))->follow_guide(snd(split_pospos))env)inline,mincolcol',maxcolcol'in{line;min_col;max_col;env}letattemptrtoken=let_,startp,_=tokeninletline,col=split_posstartpinletmore_indentedcandidate=line<>candidate.line&&candidate.min_col>colinletrecoveries=letrecaux=function|x::xswhenmore_indentedx->auxxs|xs->xsinauxr.candidatesinletsame_indentedcandidate=line=candidate.line||(candidate.min_col<=col&&col<=candidate.max_col)inletrecoveries=letrecaux=function|x::xswhensame_indentedx->x::auxxs|_->[]inauxrecoveriesinletrecaux=function|[]->`Fail|x::xs->(matchfeed_token~allow_reduction:truetokenx.envwith|`Fail->auxxs|`Recovered(checkpoint,_)->`Ok(checkpoint,x.env)|`Acceptv->(matchauxxswith`Fail->`Acceptv|x->x))inauxrecoveriesletdecideenv=letrecnth_stateenvn=ifn=0thenmatchParser.topenvwith|None->-1(*allow giving up recovery on empty files*)|Some(Parser.Element(state,_,_,_))->Parser.numberstateelsematchParser.popenvwith|None->assert(n=1);-1|Someenv->nth_stateenv(n-1)inletst=nth_stateenv0inmatchRecovery.recoverstwith|Recovery.Nothing->[]|Recovery.Oneactions->actions|Recovery.Selectf->f(nth_stateenvRecovery.depth.(st))letgenerate(typea)(env:aParser.env)=letmoduleE=structexceptionResultofaendinletshifted=refNoneinletrecauxaccenv=matchParser.topenvwith|None->None,acc|Some(Parser.Element(_state,_,_startp,endp))->letactions=decideenvinletcandidate0=candidateenvinletreceval(env:aParser.env):Recovery.action->aParser.env=function|Recovery.Abort->raiseNot_found|Recovery.Rprod->letprod=Parser.find_productionprodinParser.force_reductionprodenv|Recovery.S(Parser.Nnassym)->letxsym=Parser.Xsyminif!shifted=None&¬(Recovery.nullablen)thenshifted:=Somexsym;letloc={Location.loc_start=endp;loc_end=endp;loc_ghost=true}inletv=Recovery.default_valuelocsyminParser.feedsymendpvendpenv|Recovery.S(Parser.Ttassym)->letxsym=Parser.Xsyminif!shifted=Nonethenshifted:=Somexsym;letloc={Location.loc_start=endp;loc_end=endp;loc_ghost=true}inletv=Recovery.default_valuelocsyminlettoken=Recovery.token_of_terminaltv,endp,endpin(matchfeed_token~allow_reduction:truetokenenvwith|`Fail->assertfalse|`Acceptv->raise(E.Resultv)|`Recovered(_,env)->env)|Recovery.Subactions->List.fold_leftevalenvactionsin(matchrev_scan_left[]~f:eval~init:envactions|>List.map(funenv->{candidate0withenv})with|exceptionNot_found->None,acc|exceptionE.Resultv->Somev,acc|[]->None,acc|candidate::_ascandidates->aux(candidates@acc)candidate.env)inletfinal,candidates=aux[]envin!shifted,final,candidatesletgenerateenv=letshifted,final,candidates=generateenvinletcandidates=rev_filtercandidates~f:(funt->not(Parser.env_has_default_reductiont.env))in{shifted;final;candidates=candidateenv::candidates}end