{-# LANGUAGE DeriveDataTypeable #-}{-# OPTIONS_HADDOCK hide #-}moduleData.Parser.Grempa.Parser.Dynamic(mkDynamicParser,constrWrapper,idWrapper)whereimportqualifiedControl.ArrowasAimportData.ArrayimportData.DataimportData.FunctionimportqualifiedData.MapasMimportData.MaybeimportData.Parser.Grempa.Aux.AuximportData.Parser.Grempa.Parser.DriverimportData.Parser.Grempa.Parser.LALRimportData.Parser.Grempa.Parser.ResultimportData.Parser.Grempa.Parser.TableimportData.Parser.Grempa.Grammar.TokenimportqualifiedData.Parser.Grempa.Grammar.TypedasTimportData.Parser.Grempa.Grammar.Untyped-- | Convert an action table to a function (operating on an array)actToFun::Ordt=>ActionTablet->ActionFuntactToFuntablestt=fromMaybedef$M.lookuptstateTablewherea=listToArr(M.empty,Error[])table'(stateTable,def)=ifinRange(boundsa)stthena!stelse(M.empty,Error[])table'=map(A.second(A.firstM.fromList))table-- | Convert an goto table to a function (operating on an array)gotoToFun::GotoTablet->GotoFuntgotoToFuntablestrule=a!(st,rule)wherea=listToArr(-1)table-- | Generate and run a dynamic parser, returning the result reduction treedynamicRT::(Tokent',Tokent,Typeablea)=>(t->t')-- ^ Token wrapper->T.Grammarta-- ^ Language grammar->[t]-- ^ Input token string->T.GrammarStatet(ParseResultt'(ReductionTreet'),ProdFunTable)dynamicRTcginp=dog'<-T.augmentglet(unt,funs)=unTypecg'(at,gt,st)=lalruntres=driver(actToFunat,gotoToFungt,st)$mapcinpreturn(res,funs)-- | Make a parser at runtime given a grammarmkDynamicParser::(Tokent,Tokent',Typeablea)=>(t->t',t'->t)-- ^ Token wrapper and unwrapper->T.Grammarta-- ^ Language grammar->ParsertamkDynamicParser(c,unc)ginp=let(res,funs)=T.evalGrammar$dynamicRTcginpinresultDriveruncfunsgres-- | Wrapper type for representing tokens only caring about the constructor.-- The Eq and Ord instances for 'CTok' will only compare the constructors-- of its arguments.dataCToka=CTok{unCTok::a}deriving(Show,Data,Typeable)instanceTokena=>Eq(CToka)whereCTokx==CToky=((==)`on`toConstr)xyinstanceTokena=>Ord(CToka)whereCTokx`compare`CToky=case((==)`on`toConstr)xyofTrue->EQFalse->x`compare`y-- | Wrap the input tokens in the 'CTok' datatype, which has 'Eq' and 'Ord'-- instances which only look at the constructors of the input values.-- This is for use as an argument to 'mkDynamicParser'.---- Example, which will evaluate to @True@:---- > CTok (Just 1) == CTok (Just 2)---- This is useful when using a lexer that may give back a list of something-- like:---- > data Token = Ident String | Number Integer | LParen | RParen | Plus | ...---- If you want to specify a grammar that accepts any @Ident@ and any @Number@-- and not just specific ones, use 'constrWrapper'.constrWrapper::(t->CTokt,CTokt->t)constrWrapper=(CTok,unCTok)-- | Don't wrap the input tokens.-- This is for use as an argument to 'mkDynamicParser'.-- An example usage of 'idWrapper' is if the parser operates directly on-- 'String'.idWrapper::(t->t,t->t)idWrapper=(id,id)