EN2      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  Safe-Inferred  Safe-InferredNone The data type 6 is used to represent the minimal length of a parser. \ Care should be taken in order to not evaluate the right hand side of the binary function  `nat-add` more than necesssary. The data type  A is the core data type around which the parsers are constructed. ~ It describes a tree structure of streams containing (in an interleaved way) both the online result of the parsing process, a and progress information. Recognising an input token should correspond to a certain amount of , : which tells how much of the input state was consumed.  The R is used to implement the breadth-first search process, in which alternatives are K examined in a more-or-less synchronised way. The meaning of the various  constructors is as follows:  C A token was succesfully recognised, and as a result the input was advanced by the distance  & The type of value represented by the  - changes by applying the function parameter.   A correcting step has to be made to the input; the first parameter contains information about what was expected in the input, b and the second parameter describes the various corrected alternatives, each with an associated   Y A small cost is inserted in the sequence, which is used to disambiguate. Use with care! The last two alternatives play a role in recognising ambigous non-terminals. For a full description see the technical report referred to from   Text.ParserCombinators.UU.README. The data type F contains three components, all being some form of primitive parser. 6 These components are used in various combinations, K depending on whether you are in the right and side operand of a monad, I whether you are interested in a result (if not, we use recognisers),  and whether you want to have the results in an online way (future parsers), or just prefer to be a bit faster (history parsers) c retrieves the correcting steps made since the last time the function was called. The result can, t by using it as the left hand side of a monadic bind, be used to control how to proceed with the parsing process.  The class  is used by the function ' which retrieves the generated 6 correction steps since the last time it was called. c retrieves the correcting steps made since the last time the function was called. The result can, X by using it in a monad, be used to control how to proceed with the parsing process. YThe input state may maintain a location which can be used in generating error messages. 6 Since we do not want to fix our input to be just a String we provide an interface | which can be used to advance this location by passing information about the part recognised. This function is typically  called in the  splitState functions.  The class  contains a function I which is used to check whether we have reached the end of the input and  deletAtEnd I should discard any unconsumed input at the end of a successful parse.  is the greedy version of #. If its left hand side parser can N make any progress then it commits to that alternative. Can be used to make M parsers faster, and even get a complete Parsec equivalent behaviour, with ) all its (dis)advantages. Intended use p <<|> q <<|> r <|> x <|> y <?> "string". Use with care! MThe parsers build a list of symbols which are expected at a specific point. ' This list is used to report errors. R Quite often it is more informative to get e.g. the name of the non-terminal .  The E combinator replaces this list of symbols by the string argument. $ checks whether its second argument P is a parser which can recognise the empty input. If so, an error message is J given using the String parameter. If not, then the third argument is T returned. This is useful in testing for illogical combinations. For its use see  the module !Text.ParserCombinators.UU.Derived.  is similar to , but can be O used in situations where we recognise a sequence of elements separated by P other elements. This does not make sense if both parsers can recognise the 9 empty string. Your grammar is then highly ambiguous. If p( can be recognized, the return value of p is used. Otherwise,  the value v is used. Note that  * by default is greedy. If you do not want  this use ...<|> pure v instead. Furthermore, p should not L recognise the empty string, since this would make the parser ambiguous!! ! In the class !j we assemble the basic properties we expect parsers to have. The class itself does not have any methods. 5 Most properties come directly from the standard  Control.Applicative module. The class < contains some extra methods we expect our parsers to have. ""0 retrieves the non-zero part from a descriptor. ##6 retrieves the possibly empty part from a descriptor. v combines the non-empty descriptor part and the empty descriptor part into a descriptor tupled with the parser triple $@The basic recognisers are written elsewhere (e.g. in our module )Text.ParserCombinataors.UU.BasicInstances;  they (i.e. the parameter  splitState) are lifted to our descriptors by the function $ which also takes = the minimal number of tokens recognised by the parameter  splitState and an Maybe, value describing the possibly empty value. %% inserts a I step into the sequence representing the progress the parser is making;  for its use see `(Text.ParserCombinators.UU.Demos.Examples` &#For the precise functioning of the &( combinators see the paper cited in the  Text.ParserCombinators.UU.README; e it converts an ambiguous parser into a parser which returns a list of all possible recognitions, ''E returns the error messages that were generated since its last call. ((% returns the current input position. ))! returns the current input state * The function *v should be called at the end of the parsing process. It deletes any unconsumed input, turning it into error messages. ++p takes the current state and modifies it to a different type of state to which its argument parser is applied.  The second component of the result is a function which converts the remaining state of this parser back into a value of the original type.  For the second argument to +/ (say split) we expect the following to hold: $ let (n,f) = split st in f n == st , The function ,3 shows the prototypical way of running a parser on  some specific input. K By default we use the future parser, since this gives us access to partal ; result; future parsers are expected to run in less space. - The function - behaves like , but using the history I parser. This parser does not give online results, but might run faster. ..= removes the progress information from a sequence of steps, , and constructs the value embedded in it. K If you are really desparate to see how your parsers are making progress I (e.g. when you have written an ambiguous parser, and you cannot find C the cause of the exponential blow-up of your parsing process), / you may switch on the trace in the function .2 (you will need to edit the library source code). J makes sure that the head of the sequence contains progress information. @ It does so by pushing information about the result (i.e. the  steps) backwards.  The function best compares two streams  getlength8 retrieves the length of the non-empty part of a parser l compares two minmal length and returns the shorter length. The second component indicates whether the left - operand is the smaller one; we cannot use Either5 since the first component may already be inspected 2 before we know which operand is finally chosen T The current position /The part which has been removed from the input  !"#$%&'()*+,-./v      !"#$%&'()*+,-./0123456789:;<=>?@ABCD  !"#$%&'()*+,-./0!   %&'()*+$,-#"/.=   !"#$%&'()*+,-./None 00& is defined for upwards compatibility 11; is defined for upwards compatibility, and is the unit for  | 22* greedily recognises its argument. If not Nothing is returned. 33) recognises either one of its arguments. 44 is the version of $$ which flips the function argument 55S parses an optional postfix element and applies its result to its left hand result 66 is equivalent to the  from Control.Applicative=. We want however all our parsers to start with a lower case p. 77 is equivalent to the  from Control.Applicative=. We want however all our parsers to start with a lower case p. 88` surrounds its third parser with the first and the second one, returning only the middle result NN+ recognises a specified number of elements RCount the number of times p has succeeded SGBuild a parser for each element in the argument list and try them all. $0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS$0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS$0123456789:;<=>?@ABCDEFGHIJKLMNOPQRS$0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSNoneTthe String' describes what is being inserted, the a5 parameter the value which is to be inserted and the cost the prices to be paid. ZA Z a b maps a [ a onto a [ b. [A [( is a parser that is prepared to accept  Data.Listlike input; hence we can deal with String's,  ByteString's, etc. \The data type \X holds the input data to be parsed, the current location, the error messages generated J and whether it is ok to delete elements from the input. Since an insert/delete action is  the same as a delete/.insert action we try to avoid the first one. # So: no deletes after an insert. ^!the unconsumed part of the input _the accumulated error messages `the current input position a,we want to avoid deletions after insertions bThe data type b^ describes the various kinds of errors which can be generated by the instances in this module c-the unconsumed part of the input was deleted dfor future use eString was deleted at pos-ition, where we expected Strings fString was inserted at pos-ition, where we expected Strings hhm initialises the input stream with the input data and the initial position. There are no error messages yet. ii} describes and elementary parsing step. Its first parameter check whether the head element of the input can be recognised, e and the second parameter how to proceed in case an element recognised by this parser is absent, \ and parsing may proceed by pretending such an element was present in the input anayway. jji recognises an element between a lower and an upper bound. Furthermore it can be specified what element N is to be inserted in case such an element is not at the head of the input. kk5 uses the information from the bounds to compute the T information. llN recognises a specific element. Furthermore it can be specified what element N is to be inserted in case such an element is not at the head of the input. mm` recognises a specific element. Furthermore it can be specified what element. Information about T is derived from the parameter. N is to be inserted in case such an element is not at the head of the input. nn recognises the longest prefix of the input for which the passed predicate holds. The message parameter is used when tracing has been switched on. ooT recognises the longest prefix of the input for which the passed predicate holds. pp6 succeeds if its parameter is a prefix of the input. +TUVWXYZ[\]^_`abcdefghijklmnopqEFGHIJKLMNOPQTUVWXYZ[\]^_`abcdefghijklmnopqbfedc\]^_`aTUXYVW[ZhgijklmqponTUVWXYZ[\]^_`abfedcghijklmnopqEFGHIJKLMNOPQNonessI forgets the computed minimal number of tokens recognised by this parser ] which makes a parser opaque for abstract interpretation; used when interleaving parsers - where we do not want to compare lengths. rsRSTrsrsrsRSTNone~MLexeme Parsers skip trailing whitespace (this terminology comes from Parsec) UNB - At present this is not a lexeme parser, hence we don't  support - 7.0, - 7, + 7.0 etc.  It'4s also currently private - ie local to this module.  eg [1,2,3]  eg (1,2,3) ,Converts a UU Parser into a read-style one. 9This is intended to facilitate migration from read-style  parsers to UU-based ones. 0The lower-level interface. Returns all errors. #The higher-level interface. (Calls V with a simplified error). S Runs the parser; if the complete input is accepted without problems return the 5 result else fail with reporting unconsumed tokens =WXYZ[\]^_`abctuvwxyz{|}~Ude-tuvwxyz{|}~-tuvwxyz{|}~1W cba`_^]\[ZYXtuvwxyz{|}~Ude None      !"#$%&'()*+,-./0123456789:;<=>?@ABCD  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSNoneRunning the function # should give the following output:  run pa "a" Result: "a" run pa "" Result: "a" Correcting steps: ; Inserted 'a' at position LineColPos 0 0 0 expecting 'a' run pa "b" Result: "a" Correcting steps: ; Deleted 'b' at position LineColPos 0 0 0 expecting 'a'; Inserted 'a' at position LineColPos 0 1 1 expecting 'a' run ((++) <$> pa <*> pa) "bbab" Result: "aa" Correcting steps: ; Deleted 'b' at position LineColPos 0 0 0 expecting 'a'; Deleted 'b' at position LineColPos 0 1 1 expecting 'a'; Deleted 'b' at position LineColPos 0 3 3 expecting 'a'; Inserted 'a' at position LineColPos 0 4 4 expecting 'a' run pa "ba" Result: "a" Correcting steps: ; Deleted 'b' at position LineColPos 0 0 0 expecting 'a' run pa "aa" Result: "a" Correcting steps: 9 The token 'a' was not consumed by the parsing process.$run (pCount pa :: Parser Int) "aaa" Result: 35run (do {l <- pCount pa; pExact l pb}) "aaacabbbbb" Result: ["b","b","b","b"] Correcting steps: I Deleted 'c' at position LineColPos 0 3 3 expecting one of ['b', 'a']9 The token 'b' was not consumed by the parsing process.Crun (amb ( (++) <$> pa2 <*> pa3 <|> (++) <$> pa3 <*> pa2)) "aaaaa" Result: ["aaaaa","aaaaa"]run (pList pLower) "doaitse" Result: "doaitse"run paz "abc2ez" Result: "abcez" Correcting steps: @ Deleted '2' at position LineColPos 0 3 3 expecting 'a'..'z'Drun (max <$> pParens ((+1) <$> wfp) <*> wfp `opt` 0) "((()))()(())" Result: 3%run (pa <|> pb <?> justamessage) "c" Result: "b" Correcting steps: D Deleted 'c' at position LineColPos 0 0 0 expecting justamessage; Inserted 'b' at position LineColPos 0 1 1 expecting 'b'>run (amb (pEither parseIntString pIntList)) "(123;456;789)"7 Result: [Left ["123","456","789"],Right [123,456,789]] The fuction r runs the parser and shows both the result, and the correcting steps which were taken during the parsing process. :Our first two parsers are simple; one recognises a single a& character and the other one a single b#. Since we will use them later we ) convert the recognised character into f! so they can be easily combined. VThe applicative style makes it very easy to merge recogition and computing a result. Q As an example we parse a sequence of nested well formed parentheses pairs and * compute the maximum nesting depth with : \It is very easy to recognise infix expressions with any number of priorities and operators:  L operators = [[('+', (+)), ('-', (-))], [('*' , (*))], [('^', (^))]] 9 same_prio ops = msum [ op <$ pSym c | (c, op) <- ops] \ expr = foldr pChainl ( pNatural <|> pParens expr) (map same_prio operators) -- which we can call:   run expr "15-3*5+2^5"   Result: 32 -Note that also here correction takes place:   run expr "2 + + 3 5"  Result: 37  Correcting steps: O Deleted ' ' at position 1 expecting one of ['0'..'9', '^', '*', '-', '+'] @ Deleted ' ' at position 3 expecting one of ['(', '0'..'9'] 2 Inserted '0' at position 4 expecting '0'..'9' @ Deleted ' ' at position 5 expecting one of ['(', '0'..'9'] O Deleted ' ' at position 7 expecting one of ['0'..'9', '^', '*', '-', '+'] UA common case where ambiguity arises is when we e.g. want to recognise identifiers, + but only those which are not keywords.  The combinator %3 inserts steps with a specfied cost in the result 4 of the parser which can be used to disambiguate:    ident :: Parser String ^ ident = ((:) <$> pSym ('a','z') <*> pMunch (\x -> 'a' <= x && x <= 'z') `micro` 2) <* spaces  idents = pList1 ident - pKey keyw = pToken keyw `micro` 1 <* spaces  spaces :: Parser String  spaces = pMunch (==' ') # takes_second_alt = pList ident G \<|> (\ c t e -> ["IfThenElse"] ++ c ++ t ++ e) 8 \<$ pKey "if" <*> pList_ng ident 7 \<* pKey "then" <*> pList_ng ident 9 \<* pKey "else" <*> pList_ng ident &A keyword is followed by a small cost 1, which makes sure that ] identifiers which have a keyword as a prefix win over the keyword. Identifiers are however  followed by a cost 26, with as result that in this case the keyword wins. g Note that a limitation of this approach is that keywords are only recognised as such when expected!  5 test13 = run takes_second_alt "if a then if else c" 6 test14 = run takes_second_alt "ifx a then if else c" with results for test13 and test14: % Result: ["IfThenElse","a","if","c"] - Result: ["ifx","a","then","if", "else","c"] {A mistake which is made quite often is to construct a parser which can recognise a sequence of elements using one of the  derived combinators (say >B), but where the argument parser can recognise the empty string. r The derived combinators check whether this is the case and terminate the parsing process with an error message:   run (pList spaces) "" - Result: *** Exception: The combinator pList @ requires that it's argument cannot recognise the empty string  run (pMaybe spaces) " " . Result: *** Exception: The combinator pMaybe ? requires that it's argument cannot recognise the empty string $$$$NoneThe  is to be pronounced as stop  The function  is to be pronounced as start gThe idea of the Idiom concept is that sequential composition operators can be inferred from the type  of the various operands =run (iI (+) '(' pNatural "plus" pNatural ')' Ii) "(2 plus 3" Result: 5 Correcting steps: \ Inserted ')' at position LineColPos 0 4 4 expecting one of [')', Whitespace, '0'..'9']ghijklghijklm    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^^__``abccdefghijklmnopqrstuvwxyz{|}~b        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkluu-parsinglib-2.8.1Text.ParserCombinators.UU.Core!Text.ParserCombinators.UU.Derived(Text.ParserCombinators.UU.BasicInstances%Text.ParserCombinators.UU.InterleavedText.ParserCombinators.UU.Utils'Text.ParserCombinators.UU.Demo.Examples Text.ParserCombinators.UU.Idioms Text.ParserCombinators.UU.README#Text.ParserCombinators.UU.CHANGELOGText.ParserCombinators.UUNatHole UnspecifiedInfiniteSuccZeroStringsProgressCostStepsEnd_fEnd_hMicroFailApplyStepP HasPositiongetPos StoresErrors getErrorsIsLocationUpdatedByadvanceEofeof deleteAtEndExtAlternative<<|>must_be_non_emptymust_be_non_emptiesoptIsParsergetOnePgetZeroPpSymExtmicroambpErrorspPospStatepEndpSwitchparseparse_heval addLengthpReturnpFailpMaybepEither<$$>pManypSomepPackedpFoldr pFoldr_ngpFoldr1 pFoldr1_nglist_algpListpList_ngpList1 pList1_ng pFoldrSep pFoldrSep_ng pFoldr1Sep pFoldr1Sep_ngpListSep pListSep_ng pList1Sep pList1Sep_ngpChainr pChainr_ngpChainl pChainl_ngpExactpBetweenpAtLeastpAtMostpCountpAny Insertion LineColPosLineCol ParserTrafoParserStrinputmsgsposdeleteOkError DeletedAtEndReplacedDeletedInsertedshow_expecting createStrpSatisfy pRangeInsertpRange pSymInsertpSympMunchLpMunch pTokenCostpTokenmkPdoNotInterpretpCRpLFpLowerpUpperpLetterpAsciipDigit pDigitAsNumpAnySympSpaceslexemepDotpCommapDQuotepLParenpRParen pLBracket pRBracketpLBracepRBracepSymbol pNaturalRaw pIntegerRaw pDoubleRaw pDoubleStrpNaturalpIntegerpDoublepPercentpEnumRawpEnum pEnumStrspParenspBraces pBrackets listParser tupleParserpTuple pDayMonthYearpDaypParentheticalString pQuotedStringparserReadsPrec execParser runParser justamessage show_demosrunrun'papbpclift<++>pa2pa3pazwfptest11 operators same_prioexprtest16identidentspKeyspacestakes_second_alttest13test14 pManyTill simpleCommentstringpVarIdpConIdpIdChar pAnyTokenpIntListparseIntStringdemo Idiomatic idiomaticIiString'fromStrORFIELSETHENIFiIpNatdummyTbaseControl.Applicative<|>mkParsernormbest getLengthnat_min.combineapplypush apply2fstnoAlts has_success applyFailbest' getCheapesttraverseshow' removeEnd_h removeEnd_f addLength'fromIntnat_addtrace'$fMonadP $fIsParserP$fExtAlternativeP$fAlternativeP$fApplicativeP $fFunctorP$fShowP$fAlternativeT$fApplicativeT $fFunctorT $fMonadPlusPGHC.Basefail>>=>>fmapreturn Control.MonadguardliftMMonadFunctor MonadPlus ApplicativeoptionalliftA3liftA2liftA<**><**><*>puremanysomeempty AlternativegetConstConst unwrapMonad WrapMonad WrappedMonad unwrapArrow WrapArrow WrappedArrow getZipListZipList Data.Functor<$>mfilterapliftM5liftM4liftM3liftM2unlesswhen replicateM_ replicateMfoldM_foldM zipWithM_zipWithM mapAndUnzipMjoinvoidforever<=<>=>msumforM_forMfilterMmapM_mapM sequence_sequence=<<mplusmzero<$ show_tokens show_munch show_symbol show_attempt$fHasPositionStrloc$fStoresErrorsStrError$fEofStr$fIsLocationUpdatedByloc[]#$fIsLocationUpdatedByLineColPosChar $fIsLocationUpdatedByLineColChar$fIsLocationUpdatedByIntWord8$fIsLocationUpdatedByIntChar $fShowError$fIsParserGram$fExtAlternativeGram $fSplittablePpSignGHC.ErrerrorMonthDecNovOctSepAugJulJunMayAprMarFebJan pPercentRaw pPctOrDblString$fIdiomaticst(->)(->)$fIdiomaticStrf(->)$fIdiomaticStrf(->)0$fIdiomaticst(->)(->)0$fIdiomaticst(->)(->)1$fIdiomaticstx(->)