From 77a2fd4244ccf35d44d514b372206550d1153515 Mon Sep 17 00:00:00 2001 From: Sebastian Graf Date: Sat, 19 Oct 2024 11:01:33 +0200 Subject: [PATCH] Resurrect the `%errorhandlertype` directive for back-compat (#320) Fixes #320. --- ChangeLog.md | 10 + doc/syntax.rst | 91 +++++++- doc/using.rst | 57 +---- happy.cabal | 4 +- .../src/Happy/Backend/GLR/ProduceCode.lhs | 8 +- .../src/Happy/Backend/LALR/ProduceCode.lhs | 46 ++-- lib/data/HappyTemplate.hs | 1 + lib/frontend/boot-src/Parser.ly | 2 + lib/frontend/src/Happy/Frontend/AbsSyn.lhs | 23 +- .../src/Happy/Frontend/AttrGrammar/Parser.hs | 99 ++++---- lib/frontend/src/Happy/Frontend/Lexer.lhs | 3 + lib/frontend/src/Happy/Frontend/Mangler.lhs | 9 +- lib/frontend/src/Happy/Frontend/Parser.hs | 220 +++++++++--------- lib/grammar/src/Happy/Grammar.lhs | 15 +- lib/happy-lib.cabal | 2 +- tests/monaderror-explist.y | 8 +- tests/monaderror-lexer-explist.y | 79 +++++++ tests/monaderror-newexplist.y | 84 +++++++ 18 files changed, 499 insertions(+), 262 deletions(-) create mode 100644 tests/monaderror-lexer-explist.y create mode 100644 tests/monaderror-newexplist.y diff --git a/ChangeLog.md b/ChangeLog.md index f0690683..3b35ec45 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,10 +1,20 @@ # Revision history for Happy +## 2.1.1 + +This release fixes two breaking changes: + +* Properly qualify all uses of Prelude functions, fixing #131 +* Bring back the old `%errorhandlertype` directive, the use of which is + discouraged in favour of the "Reporting expected tokens" mechanism + in Happy 2.1, accesible via `%error.expected`. + ## 2.1 * Added `--numeric-version` CLI flag. * Documented and implemented the new feature "Resumptive parsing with ``catch``" * Documented (and reimplemented) the "Reporting expected tokens" feature + (which turned to cause a breaking change in this release: #320) ## 2.0.2 diff --git a/doc/syntax.rst b/doc/syntax.rst index 1b2c3128..4d37e36f 100644 --- a/doc/syntax.rst +++ b/doc/syntax.rst @@ -273,10 +273,34 @@ Error declaration %error { } + %error { } { } + .. index:: ``%error`` -Specifies the function to be called in the event of a parse error. -The type of ```` varies depending on the presence of ``%lexer`` (see :ref:`Summary `) and ``%errorhandlertype`` (see the following). +(optional) +Specifies the functions to be called in the event of a parse error. + +The first, one-action form specifies a single function (often referred to as +``parseError``) that reports the error and aborts the parse (in the sense of +early return). +When ``%error`` is not specified, the function is assumed to be called ``happyError``. + +The type of ``parseError`` varies depending on the presence of ``%lexer`` +(see :ref:`Summary `) and +the :ref:``presence of `%error.expected`` `. + +The second, two-action form specifies a pair of functions ``abort`` and +``report`` which are necessary to handle multiple parse errors during +:ref:`resumptive parsing using the ``catch`` mechanism `. +In this case, ``report`` is called for every parse error and additionally +receives a continuation for resuming the parse as the last argument. +When Happy is unable to resume the parse after a parse error, it calls +``abort``, which is *not* supposed to report an error as well. + +To illustrate the correspondence between the two forms: +In a non-resumptive parser (i.e. one that does not use ``catch``), +the one-action form ``%error { \\ tks -> report tks abort }`` is equivalent to +the two-action form ``%error { abort } { report }``. .. _sec-errorhandlertype-directive: @@ -289,6 +313,69 @@ Additional error information .. index:: ``%errorhandlertype`` +(deprecated) +Happy 2.1 overhauled and superseded this directive in favour of the simple, +optional flag directive ``%error.expected``. See . + +.. _sec-error-expected-directive: + +Reporting expected tokens +------------------------- + +.. index:: ``%error.expected`` + +(optional) +Often, it is useful to present users with suggestions as to which kind of tokens +where expected at the site of a syntax error. +To this end, when the ``%error.expected`` directive is specified, happy assumes that +the error handling function (resp. ``report`` function when using the binary +form of the ``%error`` directive) takes a ``[String]`` argument (the argument +*after* the token stream, in case of a non-threaded lexer) listing all the +stringified tokens that could be shifted at the site of the syntax error. +The strings in this list are derived from the ``%token`` directive. + +Here is an example, inspired by test case ``monaderror-explist``: + +.. code-block:: none + + %tokentype { Token } + %error { handleErrorExpList } + %error.expected + + %monad { ParseM } { (>>=) } { return } + + %token + 'S' { TokenSucc } + 'Z' { TokenZero } + 'T' { TokenTest } + + %% + + Exp : 'Z' { 0 } + | 'T' 'Z' Exp { $3 + 1 } + | 'S' Exp { $2 + 1 } + + %% + + type ParseM = ... + + handleErrorExpList :: [Token] -> [String] -> ParseM a + handleErrorExpList ts explist = throwError $ ParseError $ explist + + ... + + +Additional error information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + %error.expected + +.. index:: ``%error.expected`` + +Deprecated in favour of the simple, optional flag directive ``%error.expected``. + (optional) The expected type of the user-supplied error handling can be applied with additional information. By default, no information is added, for compatibility with previous versions. diff --git a/doc/using.rst b/doc/using.rst index e19ac3e0..ba62e6c9 100644 --- a/doc/using.rst +++ b/doc/using.rst @@ -1053,7 +1053,8 @@ simple non-threaded lexer): ... Note the use of ``catch`` in the second ``Exp`` rule and -the use of the binary form of the ``%error`` directive. +the use of the two-action form of the ``%error`` directive +(see :ref:`the documentation for ``%error`` `). The directive specifies a pair of functions ``abort`` and ``report`` which are necessary to handle multiple parse errors. @@ -1110,15 +1111,9 @@ A couple of notes: Similarly, ``abort`` must always throw an exception and cannot return a syntax tree at all. It should *not* report a parse error as well. - To illustrate how the new binary ``%error`` decomposition corresponds to - the regular unary one, consider the definition - ``myError tks = report tks abort``. - This definition could be used in ``%error { myError }``; in this case, the - parser would always abort after the first error. - * Whether or not the ``abort`` and ``report`` functions get passed the list of tokens is subject to the :ref:`same decision logic as for ``parseError`` `. - When using :ref:`the ``%error.expected`` directive `, + When using :ref:`the ``%error.expected`` directive `, the list of expected tokens is passed to ``report`` only, between ``tks`` and ``resume``. @@ -1127,52 +1122,6 @@ to the user of happy; the example above simply emitted the string ``catch`` whenever it stands-in an for an errorneous AST node. A more reasonable implementation would be similar to typed holes in GHC. -.. _sec-expected-list: - -Reporting expected tokens -------------------------- - -.. index:: expected tokens - -Often, it is useful to present users with suggestions as to which kind of tokens -where expected at the site of a syntax error. -To this end, when ``%error.expected`` directive is specified, happy assumes that -the error handling function (resp. ``report`` function when using the binary -form of the ``%error`` directive) takes a ``[String]`` argument (the argument -*after* the token stream, in case of a non-threaded lexer) listing all the -stringified tokens that were expected at the site of the syntax error. -The strings in this list are derived from the ``%token`` directive. - -Here is an example, inspired by test case ``monaderror-explist``: - -.. code-block:: none - - %tokentype { Token } - %error { handleErrorExpList } - %error.expected - - %monad { ParseM } { (>>=) } { return } - - %token - 'S' { TokenSucc } - 'Z' { TokenZero } - 'T' { TokenTest } - - %% - - Exp : 'Z' { 0 } - | 'T' 'Z' Exp { $3 + 1 } - | 'S' Exp { $2 + 1 } - - %% - - type ParseM = ... - - handleErrorExpList :: [Token] -> [String] -> ParseM a - handleErrorExpList ts explist = throwError $ ParseError $ explist - - ... - .. _sec-multiple-parsers: Generating Multiple Parsers From a Single Grammar diff --git a/happy.cabal b/happy.cabal index 73d1b792..71722452 100644 --- a/happy.cabal +++ b/happy.cabal @@ -1,5 +1,5 @@ name: happy -version: 2.1 +version: 2.1.1 license: BSD2 license-file: LICENSE copyright: (c) Andy Gill, Simon Marlow @@ -139,7 +139,7 @@ executable happy array, containers >= 0.4.2, mtl >= 2.2.1, - happy-lib == 2.1 + happy-lib == 2.1.1 default-language: Haskell98 default-extensions: CPP, MagicHash, FlexibleContexts, NamedFieldPuns diff --git a/lib/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs b/lib/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs index 282f26a9..49801305 100644 --- a/lib/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs +++ b/lib/backend-glr/src/Happy/Backend/GLR/ProduceCode.lhs @@ -91,7 +91,7 @@ the driver and data strs (large template). > -> Maybe String -- User-defined stuff (token DT, lexer etc.) > -> (DebugMode,Options) -- selecting code-gen style > -> Grammar String -- Happy Grammar -> -> Pragmas -- Pragmas in the .y-file +> -> Directives -- Directives in the .y-file > -> (String -- data > ,String) -- parser > @@ -372,7 +372,7 @@ Do the same with the Happy goto table. %----------------------------------------------------------------------------- Create the 'GSymbol' ADT for the symbols in the grammar -> mkGSymbols :: Grammar String -> Pragmas -> ShowS +> mkGSymbols :: Grammar String -> Directives -> ShowS > mkGSymbols g pragmas > = str dec > . str eof @@ -423,7 +423,7 @@ Creating a type for storing semantic rules > type SemInfo > = [(String, String, [Int], [((Int, Int), ([(Int, TokenSpec)], String), [Int])])] -> mkGSemType :: Options -> Grammar String -> Pragmas -> (ShowS, SemInfo) +> mkGSemType :: Options -> Grammar String -> Directives -> (ShowS, SemInfo) > mkGSemType (TreeDecode,_,_) g pragmas > = (def, map snd syms) > where @@ -673,7 +673,7 @@ only unpacked when needed. Using classes here to manage the unpacking. This selects the info used for monadic parser generation > type MonadInfo = Maybe (String,String,String) -> monad_sub :: Pragmas -> MonadInfo +> monad_sub :: Directives -> MonadInfo > monad_sub pragmas > = case monad pragmas of > (True, _, ty,bd,ret) -> Just (ty,bd,ret) diff --git a/lib/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs b/lib/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs index 20e6e957..2e5abf06 100644 --- a/lib/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs +++ b/lib/backend-lalr/src/Happy/Backend/LALR/ProduceCode.lhs @@ -30,7 +30,7 @@ Produce the complete output file. > produceParser :: Grammar String -- grammar info > -> Maybe AttributeGrammarExtras -> -> Pragmas -- pragmas supplied in the .y-file +> -> Directives -- directives supplied in the .y-file > -> ActionTable -- action table > -> GotoTable -- goto table > -> [String] -- language extensions @@ -53,7 +53,7 @@ Produce the complete output file. > , starts = starts' > }) > mAg -> (Pragmas +> (Directives > { lexer = lexer' > , imported_identity = imported_identity' > , monad = (use_monad,monad_context,monad_tycon,monad_then,monad_return) @@ -365,19 +365,16 @@ happyMonadReduce to get polymorphic recursion. Sigh. The token conversion function. > produceTokenConverter -> = case lexer' of { -> -> Nothing -> -> str "happyTerminalToTok term = case term of {\n" . indent +> = str "happyTerminalToTok term = case term of {\n" . indent +> . (case lexer' of Just (_, eof') -> str eof' . str " -> " . eofTok . str ";\n" . indent; _ -> id) > . interleave (";\n" ++ indentStr) (map doToken token_rep) -> . str "_ -> -1#;\n" . indent . str "}\n" -- -1# signals an invalid token +> . str "_ -> -1#;\n" . indent . str "}\n" -- token number -1# (INVALID_TOK) signals an invalid token > . str "{-# NOINLINE happyTerminalToTok #-}\n" -> . str "\n" -> . str "happyLex kend _kmore [] = kend notHappyAtAll []\n" -> . str "happyLex _kend kmore (tk:tks)\n" -> . str " | Happy_GHC_Exts.tagToEnum# (i Happy_GHC_Exts.==# -1#) = happyReport' (tk:tks) [] happyAbort\n" -- invalid token (-1#); lexer error. -> . str " | Prelude.otherwise = kmore i tk tks\n" -> . str " where i = happyTerminalToTok tk\n" +> . str "\n" . +> (case lexer' of { +> Nothing -> +> str "happyLex kend _kmore [] = kend notHappyAtAll []\n" +> . str "happyLex _kend kmore (tk:tks) = kmore (happyTerminalToTok tk) tk tks\n" > . str "{-# INLINE happyLex #-}\n" > . str "\n" > . str "happyNewToken action sts stk = happyLex (\\tk -> " . eofAction "notHappyAtAll" . str ") (" @@ -390,13 +387,7 @@ The token conversion function. > . str "\n"; > Just (lexer'',eof') -> -> str "happyTerminalToTok term = case term of {\n" . indent -> . str eof' . str " -> " . eofTok . str ";\n" . indent -> . interleave (";\n" ++ indentStr) (map doToken token_rep) -> . str "_ -> Prelude.error \"Encountered a token that was not declared to happy\"\n" . indent . str "}\n" -> . str "{-# NOINLINE happyTerminalToTok #-}\n" -> . str "\n" -> . str "happyLex kend kmore = " . str lexer'' . str " (\\tk -> case tk of {\n" . indent +> str "happyLex kend kmore = " . str lexer'' . str " (\\tk -> case tk of {\n" . indent > . str eof' . str " -> kend tk;\n" . indent > . str "_ -> kmore (happyTerminalToTok tk) tk })\n" > . str "{-# INLINE happyLex #-}\n" @@ -409,7 +400,7 @@ The token conversion function. > -- superfluous pattern match needed to force happyReport to > -- have the correct type. > . str "\n"; -> } +> }) > where @@ -729,16 +720,21 @@ in the presence of the %error.expected directive. The last argument is the "resumption", a continuation that tries to find an item on the stack taking a @catch@ terminal where parsing may resume, in the presence of the two-argument form of the %error directive. +In order to support the legacy %errorhandlertype directive, we retain +have a special code path for `OldExpected`. > callReportError = -- this one wraps around report_error_handler to expose a unified interface > str "(\\tokens expected resume -> " . > (if use_monad then str "" > else str "HappyIdentity Prelude.$ ") . > report_error_handler . -> (case (error_handler', lexer') of (DefaultErrorHandler, Just _) -> id -> _ -> str " tokens") . -> (if error_expected' then str " expected" -> else id) . +> (case error_expected' of +> OldExpected -> str " (tokens, expected)" -- back-compat for %errorhandlertype +> _ -> +> (case (error_handler', lexer') of (DefaultErrorHandler, Just _) -> id +> _ -> str " tokens") . +> (case error_expected' of NewExpected -> str " expected" +> NoExpected -> id)) . > (case error_handler' of ResumptiveErrorHandler{} -> str " resume" > _ -> id) . > str ")" diff --git a/lib/data/HappyTemplate.hs b/lib/data/HappyTemplate.hs index 464bb141..ef8e239b 100644 --- a/lib/data/HappyTemplate.hs +++ b/lib/data/HappyTemplate.hs @@ -19,6 +19,7 @@ type Happy_Int = Happy_GHC_Exts.Int# data Happy_IntList = HappyCons Happy_Int Happy_IntList +#define INVALID_TOK -1# #define ERROR_TOK 0# #define CATCH_TOK 1# diff --git a/lib/frontend/boot-src/Parser.ly b/lib/frontend/boot-src/Parser.ly index 69880a9e..96fec2cb 100644 --- a/lib/frontend/boot-src/Parser.ly +++ b/lib/frontend/boot-src/Parser.ly @@ -34,6 +34,7 @@ The parser. > spec_expect { TokenKW TokSpecId_Expect } > spec_error { TokenKW TokSpecId_Error } > spec_errorexpected { TokenKW TokSpecId_ErrorExpected } +> spec_errorhandlertype { TokenKW TokSpecId_ErrorHandlerType } > spec_attribute { TokenKW TokSpecId_Attribute } > spec_attributetype { TokenKW TokSpecId_Attributetype } > code { TokenInfo $$ TokCodeQuote } @@ -125,6 +126,7 @@ The parser. > | spec_expect int { TokenExpect $2 } > | spec_error code optCode { TokenError $2 $3 } > | spec_errorexpected { TokenErrorExpected } +> | spec_errorhandlertype id { TokenErrorHandlerType $2 } > | spec_attributetype code { TokenAttributetype $2 } > | spec_attribute id code { TokenAttribute $2 $3 } diff --git a/lib/frontend/src/Happy/Frontend/AbsSyn.lhs b/lib/frontend/src/Happy/Frontend/AbsSyn.lhs index f842a83e..32d1122a 100644 --- a/lib/frontend/src/Happy/Frontend/AbsSyn.lhs +++ b/lib/frontend/src/Happy/Frontend/AbsSyn.lhs @@ -11,7 +11,7 @@ Here is the abstract syntax of the language we parse. > AbsSyn(..), Directive(..), > getTokenType, getTokenSpec, getParserNames, getLexer, > getImportedIdentity, getMonad, ErrorHandlerInfo(..), getError, -> getPrios, getPrioNames, getExpect, getErrorHandlerExpectedList, +> getPrios, getPrioNames, getExpect, getErrorExpectedMode, > getAttributes, getAttributetype, getAttributeGrammarExtras, > parseTokenSpec, > Rule(..), Prod(..), Term(..), Prec(..), @@ -20,10 +20,6 @@ Here is the abstract syntax of the language we parse. > import Data.Char (isAlphaNum) > import Happy.Grammar -> ( ErrorHandlerInfo(..) -> , TokenSpec(..) -> , AttributeGrammarExtras(..) -> ) > import Happy.Grammar.ExpressionWithHole > data BookendedAbsSyn @@ -82,6 +78,7 @@ generate some error messages. > | TokenExpect Int -- %expect > | TokenError String (Maybe String) -- %error > | TokenErrorExpected -- %error.expected +> | TokenErrorHandlerType String -- %errorhandlertype > | TokenAttributetype String -- %attributetype > | TokenAttribute String String -- %attribute > deriving (Eq, Show) @@ -150,9 +147,19 @@ generate some error messages. > [(abort,Just addMessage)] -> ResumptiveErrorHandler abort addMessage > _ -> error "multiple error directives" -> getErrorHandlerExpectedList :: Eq t => [Directive t] -> Bool -> getErrorHandlerExpectedList ds -> = TokenErrorExpected `elem` ds + +> getErrorExpectedMode :: Eq t => [Directive t] -> ErrorExpectedMode +> getErrorExpectedMode ds +> | ["explist"] <- old_directive +> = OldExpected +> | TokenErrorExpected `elem` ds +> = NewExpected +> | length old_directive > 1 +> = error "multiple errorhandlertype directives" +> | otherwise +> = NoExpected +> where +> old_directive = [ a | (TokenErrorHandlerType a) <- ds ] > getAttributes :: [Directive t] -> [(String, String)] > getAttributes ds diff --git a/lib/frontend/src/Happy/Frontend/AttrGrammar/Parser.hs b/lib/frontend/src/Happy/Frontend/AttrGrammar/Parser.hs index b1ec1d74..ec111c4e 100644 --- a/lib/frontend/src/Happy/Frontend/AttrGrammar/Parser.hs +++ b/lib/frontend/src/Happy/Frontend/AttrGrammar/Parser.hs @@ -23,7 +23,7 @@ import qualified GHC.Exts as Happy_GHC_Exts import Control.Applicative(Applicative(..)) import Control.Monad (ap) --- parser produced by Happy Version 2.0.2 +-- parser produced by Happy Version 3.0 newtype HappyAbsSyn = HappyAbsSyn HappyAny #if __GLASGOW_HASKELL__ >= 607 @@ -121,7 +121,7 @@ happyReduceArr = Happy_Data_Array.array (1, 23) [ happyRuleArr :: HappyAddr happyRuleArr = HappyA# "\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"# -happyCatchStates :: [Int] +happyCatchStates :: [Prelude.Int] happyCatchStates = [] happy_n_terms = 12 :: Prelude.Int @@ -367,7 +367,7 @@ happyTerminalToTok term = case term of { AgTok_SubRef _ -> 8#; AgTok_RightmostRef _ -> 9#; AgTok_Unknown _ -> 10#; - _ -> error "Encountered a token that was not declared to happy" + _ -> -1#; } {-# NOINLINE happyTerminalToTok #-} @@ -403,7 +403,7 @@ happyReport' :: () => (AgToken) -> [Prelude.String] -> (P a) -> (P a) happyReport' = (\tokens expected resume -> happyError) happyAbort :: () => (P a) -happyAbort = error "Called abort handler in non-resumptive parser" +happyAbort = Prelude.error "Called abort handler in non-resumptive parser" agParser = happySomeParser where happySomeParser = happyThen (happyParse 0#) (\x -> happyReturn (let {(HappyWrap5 x') = happyOut5 x} in x')) @@ -435,6 +435,7 @@ happyError = failP (\l -> show l ++ ": Parse error\n") type Happy_Int = Happy_GHC_Exts.Int# data Happy_IntList = HappyCons Happy_Int Happy_IntList +#define INVALID_TOK -1# #define ERROR_TOK 0# #define CATCH_TOK 1# @@ -449,10 +450,10 @@ data Happy_IntList = HappyCons Happy_Int Happy_IntList #endif #if defined(HAPPY_DEBUG) -# define DEBUG_TRACE(s) (happyTrace (s)) $ -happyTrace string expr = Happy_System_IO_Unsafe.unsafePerformIO $ do +# define DEBUG_TRACE(s) (happyTrace (s)) Prelude.$ +happyTrace string expr = Happy_System_IO_Unsafe.unsafePerformIO Prelude.$ do Happy_System_IO.hPutStr Happy_System_IO.stderr string - return expr + Prelude.return expr #else # define DEBUG_TRACE(s) {- nothing -} #endif @@ -480,23 +481,23 @@ happyAccept j tk st sts (HappyStk ans _) = -- Arrays only: do the next action happyDoAction i tk st = - DEBUG_TRACE("state: " ++ show (Happy_GHC_Exts.I# st) ++ - ",\ttoken: " ++ show (Happy_GHC_Exts.I# i) ++ + DEBUG_TRACE("state: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ + ",\ttoken: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ ",\taction: ") case happyDecodeAction (happyNextAction i st) of HappyFail -> DEBUG_TRACE("failing.\n") happyFail i tk st HappyAccept -> DEBUG_TRACE("accept.\n") happyAccept i tk st - HappyReduce rule -> DEBUG_TRACE("reduce (rule " ++ show (Happy_GHC_Exts.I# rule) ++ ")") + HappyReduce rule -> DEBUG_TRACE("reduce (rule " Prelude.++ Prelude.show (Happy_GHC_Exts.I# rule) Prelude.++ ")") (happyReduceArr Happy_Data_Array.! (Happy_GHC_Exts.I# rule)) i tk st - HappyShift new_state -> DEBUG_TRACE("shift, enter state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") + HappyShift new_state -> DEBUG_TRACE("shift, enter state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") happyShift new_state i tk st {-# INLINE happyNextAction #-} happyNextAction i st = case happyIndexActionTable i st of - Just (Happy_GHC_Exts.I# act) -> act - Nothing -> happyIndexOffAddr happyDefActions st + Prelude.Just (Happy_GHC_Exts.I# act) -> act + Prelude.Nothing -> happyIndexOffAddr happyDefActions st {-# INLINE happyIndexActionTable #-} happyIndexActionTable i st @@ -505,7 +506,7 @@ happyIndexActionTable i st -- off >= 0: Otherwise it's a default action -- equality check: Ensure that the entry in the compressed array is owned by st = Prelude.Just (Happy_GHC_Exts.I# (happyIndexOffAddr happyTable off)) - | otherwise + | Prelude.otherwise = Prelude.Nothing where off = PLUS(happyIndexOffAddr happyActOffsets st, i) @@ -515,14 +516,14 @@ data HappyAction | HappyAccept | HappyReduce Happy_Int -- rule number | HappyShift Happy_Int -- new state - deriving Show + deriving Prelude.Show {-# INLINE happyDecodeAction #-} happyDecodeAction :: Happy_Int -> HappyAction happyDecodeAction 0# = HappyFail happyDecodeAction -1# = HappyAccept happyDecodeAction action | LT(action, 0#) = HappyReduce NEGATE(PLUS(action, 1#)) - | otherwise = HappyShift MINUS(action, 1#) + | Prelude.otherwise = HappyShift MINUS(action, 1#) {-# INLINE happyIndexGotoTable #-} happyIndexGotoTable nt st = happyIndexOffAddr happyTable off @@ -621,7 +622,7 @@ happyDropStk n (x `HappyStk` xs) = happyDropStk MINUS(n,(1#::Happy_Int)) xs -- Moving to a new state after a reduction happyGoto nt j tk st = - DEBUG_TRACE(", goto state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") + DEBUG_TRACE(", goto state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") happyDoAction j tk new_state where new_state = happyIndexGotoTable nt st @@ -671,8 +672,8 @@ It is best understood by example. Consider Exp :: { String } Exp : '1' { "1" } | catch { "catch" } - | Exp '+' Exp %shift { $1 ++ " + " ++ $3 } -- %shift: associate 1 + 1 + 1 to the right - | '(' Exp ')' { "(" ++ $2 ++ ")" } + | Exp '+' Exp %shift { $1 Prelude.++ " + " Prelude.++ $3 } -- %shift: associate 1 + 1 + 1 to the right + | '(' Exp ')' { "(" Prelude.++ $2 Prelude.++ ")" } The idea of the use of `catch` here is that upon encountering a parse error during expression parsing, we can gracefully degrade using the `catch` rule, @@ -749,7 +750,7 @@ In general, we pick the catch frame for resumption that discards the least amount of input for a successful shift, preferring the topmost such catch frame. -} --- happyFail :: Happy_Int -> _ -> Happy_Int -> _ +-- happyFail :: Happy_Int -> Token -> Happy_Int -> _ -- This function triggers Note [Error recovery]. -- If the current token is ERROR_TOK, phase (1) has failed and we might try -- phase (2). @@ -775,72 +776,72 @@ happyFixupFailed tk st sts (x `HappyStk` stk) = expected = happyExpectedTokens st sts in happyReport i tk expected resume --- happyResume :: Happy_Int -> _ -> Happy_Int -> _ +-- happyResume :: Happy_Int -> Token -> Happy_Int -> _ -- See Note [happyResume] happyResume i tk st sts stk = pop_items [] st sts stk where !(Happy_GHC_Exts.I# n_starts) = happy_n_starts -- this is to test whether we have a start token - !(Happy_GHC_Exts.I# eof_i) = happy_n_terms - 1 -- this is the token number of the EOF token - happy_list_to_list :: Happy_IntList -> [Int] + !(Happy_GHC_Exts.I# eof_i) = happy_n_terms Prelude.- 1 -- this is the token number of the EOF token + happy_list_to_list :: Happy_IntList -> [Prelude.Int] happy_list_to_list (HappyCons st sts) | LT(st, n_starts) = [(Happy_GHC_Exts.I# st)] - | otherwise + | Prelude.otherwise = (Happy_GHC_Exts.I# st) : happy_list_to_list sts -- See (1) of Note [happyResume] pop_items catch_frames st sts stk | LT(st, n_starts) - = DEBUG_TRACE("reached start state " ++ show (Happy_GHC_Exts.I# st) ++ ", ") - if null catch_frames_new + = DEBUG_TRACE("reached start state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", ") + if Prelude.null catch_frames_new then DEBUG_TRACE("no resumption.\n") happyAbort - else DEBUG_TRACE("now discard input, trying to anchor in states (reverse " ++ show (map (happy_list_to_list . fst) catch_frames_new) ++ ").\n") - discard_input_until_exp i tk (reverse catch_frames_new) + else DEBUG_TRACE("now discard input, trying to anchor in states " Prelude.++ Prelude.show (Prelude.map (happy_list_to_list . Prelude.fst) (Prelude.reverse catch_frames_new)) Prelude.++ ".\n") + discard_input_until_exp i tk (Prelude.reverse catch_frames_new) | (HappyCons st1 sts1) <- sts, _ `HappyStk` stk1 <- stk = pop_items catch_frames_new st1 sts1 stk1 where !catch_frames_new | HappyShift new_state <- happyDecodeAction (happyNextAction CATCH_TOK st) - , DEBUG_TRACE("can shift catch token in state " ++ show (Happy_GHC_Exts.I# st) ++ ", into state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") - null (filter (\(HappyCons _ (HappyCons h _),_) -> EQ(st,h)) catch_frames) + , DEBUG_TRACE("can shift catch token in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", into state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") + Prelude.null (Prelude.filter (\(HappyCons _ (HappyCons h _),_) -> EQ(st,h)) catch_frames) = (HappyCons new_state (HappyCons st sts), MK_ERROR_TOKEN(i) `HappyStk` stk):catch_frames -- MK_ERROR_TOKEN(i) is just some dummy that should not be accessed by user code - | otherwise - = DEBUG_TRACE("already shifted or can't shift catch in " ++ show (Happy_GHC_Exts.I# st) ++ "\n") + | Prelude.otherwise + = DEBUG_TRACE("already shifted or can't shift catch in " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ "\n") catch_frames -- See (2) of Note [happyResume] discard_input_until_exp i tk catch_frames - | Just (HappyCons st (HappyCons catch_st sts), catch_frame) <- some_catch_state_shifts i catch_frames - = DEBUG_TRACE("found expected token in state " ++ show (Happy_GHC_Exts.I# st) ++ " after shifting from " ++ show (Happy_GHC_Exts.I# catch_st) ++ ": " ++ show (Happy_GHC_Exts.I# i) ++ "\n") + | Prelude.Just (HappyCons st (HappyCons catch_st sts), catch_frame) <- some_catch_state_shifts i catch_frames + = DEBUG_TRACE("found expected token in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ " after shifting from " Prelude.++ Prelude.show (Happy_GHC_Exts.I# catch_st) Prelude.++ ": " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ "\n") happyDoAction i tk st (HappyCons catch_st sts) catch_frame | EQ(i,eof_i) -- is i EOF? = DEBUG_TRACE("reached EOF, cannot resume. abort parse :(\n") happyAbort - | otherwise - = DEBUG_TRACE("discard token " ++ show (Happy_GHC_Exts.I# i) ++ "\n") + | Prelude.otherwise + = DEBUG_TRACE("discard token " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ "\n") happyLex (\eof_tk -> discard_input_until_exp eof_i eof_tk catch_frames) -- eof (\i tk -> discard_input_until_exp i tk catch_frames) -- not eof - some_catch_state_shifts _ [] = DEBUG_TRACE("no catch state could shift.\n") Nothing + some_catch_state_shifts _ [] = DEBUG_TRACE("no catch state could shift.\n") Prelude.Nothing some_catch_state_shifts i catch_frames@(((HappyCons st sts),_):_) = try_head i st sts catch_frames where try_head i st sts catch_frames = -- PRECONDITION: head catch_frames = (HappyCons st sts) - DEBUG_TRACE("trying token " ++ show (Happy_GHC_Exts.I# i) ++ " in state " ++ show (Happy_GHC_Exts.I# st) ++ ": ") + DEBUG_TRACE("trying token " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ " in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ": ") case happyDecodeAction (happyNextAction i st) of - HappyFail -> DEBUG_TRACE("fail.\n") some_catch_state_shifts i (tail catch_frames) - HappyAccept -> DEBUG_TRACE("accept.\n") Just (head catch_frames) - HappyShift _ -> DEBUG_TRACE("shift.\n") Just (head catch_frames) + HappyFail -> DEBUG_TRACE("fail.\n") some_catch_state_shifts i (Prelude.tail catch_frames) + HappyAccept -> DEBUG_TRACE("accept.\n") Prelude.Just (Prelude.head catch_frames) + HappyShift _ -> DEBUG_TRACE("shift.\n") Prelude.Just (Prelude.head catch_frames) HappyReduce r -> case happySimulateReduce r st sts of (HappyCons st1 sts1) -> try_head i st1 sts1 catch_frames happySimulateReduce r st sts = - DEBUG_TRACE("simulate reduction of rule " ++ show (Happy_GHC_Exts.I# r) ++ ", ") + DEBUG_TRACE("simulate reduction of rule " Prelude.++ Prelude.show (Happy_GHC_Exts.I# r) Prelude.++ ", ") let (# nt, len #) = happyIndexRuleArr r in - DEBUG_TRACE("nt " ++ show (Happy_GHC_Exts.I# nt) ++ ", len: " ++ show (Happy_GHC_Exts.I# len) ++ ", new_st ") + DEBUG_TRACE("nt " Prelude.++ Prelude.show (Happy_GHC_Exts.I# nt) Prelude.++ ", len: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# len) Prelude.++ ", new_st ") let !(sts1@(HappyCons st1 _)) = happyDrop len (HappyCons st sts) new_st = happyIndexGotoTable nt st1 in - DEBUG_TRACE(show (Happy_GHC_Exts.I# new_st) ++ ".\n") + DEBUG_TRACE(Prelude.show (Happy_GHC_Exts.I# new_st) Prelude.++ ".\n") (HappyCons new_st sts1) happyTokenToString :: Prelude.Int -> Prelude.String @@ -857,11 +858,11 @@ happyExpectedTokens :: Happy_Int -> Happy_IntList -> [Prelude.String] -- returned. happyExpectedTokens st sts = DEBUG_TRACE("constructing expected tokens.\n") - map happyTokenToString $ search_shifts st sts [] + Prelude.map happyTokenToString (search_shifts st sts []) where - search_shifts st sts shifts = foldr (add_action st sts) shifts (distinct_actions st) + search_shifts st sts shifts = Prelude.foldr (add_action st sts) shifts (distinct_actions st) add_action st sts (Happy_GHC_Exts.I# i, Happy_GHC_Exts.I# act) shifts = - DEBUG_TRACE("found action in state " ++ show (Happy_GHC_Exts.I# st) ++ ", input " ++ show (Happy_GHC_Exts.I# i) ++ ", " ++ show (happyDecodeAction act) ++ "\n") + DEBUG_TRACE("found action in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", input " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ ", " Prelude.++ Prelude.show (happyDecodeAction act) Prelude.++ "\n") case happyDecodeAction act of HappyFail -> shifts HappyAccept -> shifts -- This would always be %eof or error... Not helpful @@ -880,7 +881,7 @@ happyExpectedTokens st sts = , GTE(off_i,0#) , EQ(happyIndexOffAddr happyCheck off_i,i) = [(Happy_GHC_Exts.I# (happyIndexOffAddr happyTable off_i))] - | otherwise + | Prelude.otherwise = [] -- Internal happy errors: @@ -898,7 +899,7 @@ happyTcHack x y = y ----------------------------------------------------------------------------- -- Seq-ing. If the --strict flag is given, then Happy emits -- happySeq = happyDoSeq --- otherwise it emits +-- Prelude.otherwise it emits -- happySeq = happyDontSeq happyDoSeq, happyDontSeq :: a -> b -> b diff --git a/lib/frontend/src/Happy/Frontend/Lexer.lhs b/lib/frontend/src/Happy/Frontend/Lexer.lhs index d51060db..de32d425 100644 --- a/lib/frontend/src/Happy/Frontend/Lexer.lhs +++ b/lib/frontend/src/Happy/Frontend/Lexer.lhs @@ -48,6 +48,7 @@ The lexer. > | TokSpecId_Expect -- %expect > | TokSpecId_Error -- %error > | TokSpecId_ErrorExpected -- %error.expected +> | TokSpecId_ErrorHandlerType -- %errorhandlertype > | TokSpecId_Attributetype -- %attributetype > | TokSpecId_Attribute -- %attribute > | TokCodeQuote -- stuff inside { .. } @@ -131,6 +132,8 @@ followed by a special identifier. > cont (TokenKW TokSpecId_Expect) rest > 'e':'r':'r':'o':'r':'.':'e':'x':'p':'e':'c':'t':'e':'d':rest | end_of_id rest -> > cont (TokenKW TokSpecId_ErrorExpected) rest +> 'e':'r':'r':'o':'r':'h':'a':'n':'d':'l':'e':'r':'t':'y':'p':'e':rest | end_of_id rest -> +> cont (TokenKW TokSpecId_ErrorHandlerType) rest > 'e':'r':'r':'o':'r':rest | end_of_id rest -> > cont (TokenKW TokSpecId_Error) rest > 'a':'t':'t':'r':'i':'b':'u':'t':'e':'t':'y':'p':'e':rest | end_of_id rest -> diff --git a/lib/frontend/src/Happy/Frontend/Mangler.lhs b/lib/frontend/src/Happy/Frontend/Mangler.lhs index bbda6dbe..b2062eb3 100644 --- a/lib/frontend/src/Happy/Frontend/Mangler.lhs +++ b/lib/frontend/src/Happy/Frontend/Mangler.lhs @@ -29,7 +29,7 @@ Mangler converts AbsSyn to Grammar This bit is a real mess, mainly because of the error message support. -> mangler :: FilePath -> AbsSyn String -> Either [ErrMsg] (Grammar String, Maybe AttributeGrammarExtras, Pragmas) +> mangler :: FilePath -> AbsSyn String -> Either [ErrMsg] (Grammar String, Maybe AttributeGrammarExtras, Directives) > mangler file abssyn@(AbsSyn dirs _) > | null errs = Right (gd, mAg, ps) > | otherwise = Left errs @@ -56,7 +56,7 @@ go do special processing. If not, pass on to the regular processing routine > -> CodeChecker e > -> FilePath > -> AbsSyn e -> -> M (Grammar e, Pragmas) +> -> M (Grammar e, Directives) > manglerM noCode checkCode file (AbsSyn dirs rules') = > -- add filename to all error messages > mapWriter (\(a,e) -> (a, map (\s -> file ++ ": " ++ s) e)) $ do @@ -241,7 +241,6 @@ Get the token specs in terms of Names. > > productions' = start_prods ++ concat rules2 > prod_array = listArray (0,length productions' - 1) productions' -> -- in > return (Grammar { > productions = productions', @@ -260,12 +259,12 @@ Get the token specs in terms of Names. > eof_term = last terminal_names, > priorities = prios > }, -> Pragmas { +> Directives { > imported_identity = getImportedIdentity dirs, > monad = getMonad dirs, > lexer = getLexer dirs, > error_handler = getError dirs, -> error_expected = getErrorHandlerExpectedList dirs, +> error_expected = getErrorExpectedMode dirs, > token_type = getTokenType dirs, > expect = getExpect dirs > }) diff --git a/lib/frontend/src/Happy/Frontend/Parser.hs b/lib/frontend/src/Happy/Frontend/Parser.hs index cc2013bc..4084e40a 100644 --- a/lib/frontend/src/Happy/Frontend/Parser.hs +++ b/lib/frontend/src/Happy/Frontend/Parser.hs @@ -24,7 +24,7 @@ import qualified GHC.Exts as Happy_GHC_Exts import Control.Applicative(Applicative(..)) import Control.Monad (ap) --- parser produced by Happy Version 2.0.2 +-- parser produced by Happy Version 3.0 newtype HappyAbsSyn = HappyAbsSyn HappyAny #if __GLASGOW_HASKELL__ >= 607 @@ -181,24 +181,24 @@ happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x {-# NOINLINE happyTokenStrings #-} -happyTokenStrings = ["id","spec_tokentype","spec_token","spec_name","spec_partial","spec_lexer","spec_imported_identity","spec_monad","spec_nonassoc","spec_left","spec_right","spec_prec","spec_shift","spec_expect","spec_error","spec_errorexpected","spec_attribute","spec_attributetype","code","int","\":\"","\";\"","\"::\"","\"%%\"","\"|\"","\"(\"","\")\"","\",\"","%eof"] +happyTokenStrings = ["id","spec_tokentype","spec_token","spec_name","spec_partial","spec_lexer","spec_imported_identity","spec_monad","spec_nonassoc","spec_left","spec_right","spec_prec","spec_shift","spec_expect","spec_error","spec_errorexpected","spec_errorhandlertype","spec_attribute","spec_attributetype","code","int","\":\"","\";\"","\"::\"","\"%%\"","\"|\"","\"(\"","\")\"","\",\"","%eof"] happyActOffsets :: HappyAddr -happyActOffsets = HappyA# "\x02\x00\x00\x00\x02\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\xf6\xff\xff\xff\x35\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x3b\x00\x00\x00\x4c\x00\x00\x00\x4e\x00\x00\x00\x4f\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x52\x00\x00\x00\x52\x00\x00\x00\x52\x00\x00\x00\x40\x00\x00\x00\x42\x00\x00\x00\x00\x00\x00\x00\x55\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x45\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x49\x00\x00\x00\x5c\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\xfd\xff\xff\xff\x61\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x64\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\x00\x00\x38\x00\x00\x00\x66\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\x67\x00\x00\x00\x00\x00\x00\x00\x68\x00\x00\x00\x00\x00\x00\x00\x57\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x00\x00\x5a\x00\x00\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x71\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# +happyActOffsets = HappyA# "\x2f\x00\x00\x00\x2f\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x3b\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x3d\x00\x00\x00\x4f\x00\x00\x00\x51\x00\x00\x00\x52\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x41\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x55\x00\x00\x00\x16\x00\x00\x00\x43\x00\x00\x00\x00\x00\x00\x00\x57\x00\x00\x00\x58\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x4b\x00\x00\x00\x5f\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x00\x00\x00\x00\x00\x00\x00\x62\x00\x00\x00\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x2c\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x65\x00\x00\x00\x56\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x68\x00\x00\x00\x5a\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00\x00\x6b\x00\x00\x00\x00\x00\x00\x00\x5b\x00\x00\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x5c\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyGotoOffsets :: HappyAddr -happyGotoOffsets = HappyA# "\x12\x00\x00\x00\x62\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x69\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x6e\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x74\x00\x00\x00\x75\x00\x00\x00\x00\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# +happyGotoOffsets = HappyA# "\x0c\x00\x00\x00\x66\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x00\x00\x00\x69\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x6e\x00\x00\x00\x71\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00\x79\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x00\x00\x00\x78\x00\x00\x00\x00\x00\x00\x00\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x33\x00\x00\x00\x00\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr -happyDefActions = HappyA# "\xc8\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc9\xff\xff\xff\x00\x00\x00\x00\xc8\xff\xff\xff\x00\x00\x00\x00\xe3\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xff\xff\xff\x00\x00\x00\x00\xca\xff\xff\xff\xca\xff\xff\xff\xca\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd2\xff\xff\xff\x00\x00\x00\x00\xc8\xff\xff\xff\xd5\xff\xff\xff\xd7\xff\xff\xff\xca\xff\xff\xff\xd6\xff\xff\xff\xd8\xff\xff\xff\xdc\xff\xff\xff\x00\x00\x00\x00\xcf\xff\xff\xff\xcf\xff\xff\xff\xe1\xff\xff\xff\xcd\xff\xff\xff\x00\x00\x00\x00\xe2\xff\xff\xff\xe4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\xfd\xff\xff\xff\xfb\xff\xff\xff\xf6\xff\xff\xff\xcc\xff\xff\xff\xce\xff\xff\xff\xe0\xff\xff\xff\xd0\xff\xff\xff\xdf\xff\xff\xff\xdd\xff\xff\xff\xdb\xff\xff\xff\xcb\xff\xff\xff\xd4\xff\xff\xff\xd1\xff\xff\xff\xda\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xff\xff\xff\x00\x00\x00\x00\xf5\xff\xff\xff\xec\xff\xff\xff\x00\x00\x00\x00\xd9\xff\xff\xff\x00\x00\x00\x00\xf8\xff\xff\xff\xf2\xff\xff\xff\xeb\xff\xff\xff\xe5\xff\xff\xff\xed\xff\xff\xff\xef\xff\xff\xff\xf7\xff\xff\xff\x00\x00\x00\x00\xf4\xff\xff\xff\x00\x00\x00\x00\xea\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xff\xff\xff\xec\xff\xff\xff\x00\x00\x00\x00\xec\xff\xff\xff\xfa\xff\xff\xff\xec\xff\xff\xff\xf3\xff\xff\xff\xe7\xff\xff\xff\xf0\xff\xff\xff\xe9\xff\xff\xff\x00\x00\x00\x00\xee\xff\xff\xff\x00\x00\x00\x00\xf1\xff\xff\xff\xf9\xff\xff\xff\xe8\xff\xff\xff"# +happyDefActions = HappyA# "\xc7\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc8\xff\xff\xff\x00\x00\x00\x00\xc7\xff\xff\xff\x00\x00\x00\x00\xe3\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xff\xff\xff\x00\x00\x00\x00\xc9\xff\xff\xff\xc9\xff\xff\xff\xc9\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xff\xff\x00\x00\x00\x00\xd2\xff\xff\xff\xc7\xff\xff\xff\xd5\xff\xff\xff\xd7\xff\xff\xff\xc9\xff\xff\xff\xd6\xff\xff\xff\xd8\xff\xff\xff\xdc\xff\xff\xff\x00\x00\x00\x00\xce\xff\xff\xff\xce\xff\xff\xff\xe1\xff\xff\xff\xcc\xff\xff\xff\x00\x00\x00\x00\xe2\xff\xff\xff\xe4\xff\xff\xff\x00\x00\x00\x00\xfe\xff\xff\xff\xfd\xff\xff\xff\xfb\xff\xff\xff\xf6\xff\xff\xff\xcb\xff\xff\xff\xcd\xff\xff\xff\xe0\xff\xff\xff\xcf\xff\xff\xff\xdf\xff\xff\xff\xdd\xff\xff\xff\xdb\xff\xff\xff\xca\xff\xff\xff\xd4\xff\xff\xff\xd0\xff\xff\xff\xda\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xff\xff\xff\x00\x00\x00\x00\xf5\xff\xff\xff\xec\xff\xff\xff\x00\x00\x00\x00\xd9\xff\xff\xff\x00\x00\x00\x00\xf8\xff\xff\xff\xf2\xff\xff\xff\xeb\xff\xff\xff\xe5\xff\xff\xff\xed\xff\xff\xff\xef\xff\xff\xff\xf7\xff\xff\xff\x00\x00\x00\x00\xf4\xff\xff\xff\x00\x00\x00\x00\xea\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xff\xff\xff\xec\xff\xff\xff\x00\x00\x00\x00\xec\xff\xff\xff\xfa\xff\xff\xff\xec\xff\xff\xff\xf3\xff\xff\xff\xe7\xff\xff\xff\xf0\xff\xff\xff\xe9\xff\xff\xff\x00\x00\x00\x00\xee\xff\xff\xff\x00\x00\x00\x00\xf1\xff\xff\xff\xf9\xff\xff\xff\xe8\xff\xff\xff"# happyCheck :: HappyAddr -happyCheck = HappyA# "\xff\xff\xff\xff\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x1e\x00\x00\x00\x18\x00\x00\x00\x14\x00\x00\x00\x19\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x16\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x13\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x08\x00\x00\x00\x1c\x00\x00\x00\x1d\x00\x00\x00\x0b\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x1c\x00\x00\x00\x1d\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x1b\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x1a\x00\x00\x00\x02\x00\x00\x00\x16\x00\x00\x00\x1b\x00\x00\x00\x17\x00\x00\x00\x02\x00\x00\x00\xff\xff\xff\xff\x13\x00\x00\x00\x13\x00\x00\x00\x0e\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x08\x00\x00\x00\x04\x00\x00\x00\xff\xff\xff\xff\x05\x00\x00\x00\x12\x00\x00\x00\x0c\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x12\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x08\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# +happyCheck = HappyA# "\xff\xff\xff\xff\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x1a\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x1f\x00\x00\x00\x13\x00\x00\x00\x17\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x16\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x1d\x00\x00\x00\x1e\x00\x00\x00\x0b\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x17\x00\x00\x00\x15\x00\x00\x00\x19\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x1d\x00\x00\x00\x1e\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x15\x00\x00\x00\x15\x00\x00\x00\x15\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x1c\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x1b\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x17\x00\x00\x00\x02\x00\x00\x00\x18\x00\x00\x00\x1c\x00\x00\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\xff\xff\xff\xff\x12\x00\x00\x00\xff\xff\xff\xff\x12\x00\x00\x00\xff\xff\xff\xff\x08\x00\x00\x00\x12\x00\x00\x00\x08\x00\x00\x00\x0f\x00\x00\x00\x13\x00\x00\x00\x12\x00\x00\x00\x0f\x00\x00\x00\x0c\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# happyTable :: HappyAddr -happyTable = HappyA# "\x00\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x51\x00\x00\x00\x05\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\x04\x00\x00\x00\x3e\x00\x00\x00\xff\xff\xff\xff\x3f\x00\x00\x00\x04\x00\x00\x00\x29\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x41\x00\x00\x00\x42\x00\x00\x00\x43\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x52\x00\x00\x00\x54\x00\x00\x00\x42\x00\x00\x00\x43\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x02\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x23\x00\x00\x00\x24\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\x52\x00\x00\x00\x42\x00\x00\x00\x43\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x5c\x00\x00\x00\x42\x00\x00\x00\x43\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x57\x00\x00\x00\x48\x00\x00\x00\x49\x00\x00\x00\x58\x00\x00\x00\x4e\x00\x00\x00\x4f\x00\x00\x00\x5a\x00\x00\x00\x5b\x00\x00\x00\x04\x00\x00\x00\x2e\x00\x00\x00\x24\x00\x00\x00\x2a\x00\x00\x00\x2b\x00\x00\x00\x26\x00\x00\x00\x27\x00\x00\x00\x23\x00\x00\x00\x22\x00\x00\x00\x21\x00\x00\x00\x20\x00\x00\x00\x1d\x00\x00\x00\x1b\x00\x00\x00\x1a\x00\x00\x00\x19\x00\x00\x00\x18\x00\x00\x00\x37\x00\x00\x00\x04\x00\x00\x00\x1d\x00\x00\x00\x34\x00\x00\x00\x33\x00\x00\x00\x31\x00\x00\x00\x26\x00\x00\x00\x2d\x00\x00\x00\x2e\x00\x00\x00\x3a\x00\x00\x00\x3d\x00\x00\x00\x38\x00\x00\x00\x40\x00\x00\x00\x47\x00\x00\x00\x41\x00\x00\x00\x47\x00\x00\x00\x4a\x00\x00\x00\x47\x00\x00\x00\x57\x00\x00\x00\x56\x00\x00\x00\x47\x00\x00\x00\x50\x00\x00\x00\x47\x00\x00\x00\x54\x00\x00\x00\x4b\x00\x00\x00\x5c\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x27\x00\x00\x00\x35\x00\x00\x00\x3a\x00\x00\x00\x4b\x00\x00\x00\x38\x00\x00\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x1e\x00\x00\x00\x4c\x00\x00\x00\x1d\x00\x00\x00\x1b\x00\x00\x00\x34\x00\x00\x00\x31\x00\x00\x00\x2f\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# +happyTable = HappyA# "\x00\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x53\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\x18\x00\x00\x00\x43\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x00\x00\x47\x00\x00\x00\x2b\x00\x00\x00\x56\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x00\x00\x47\x00\x00\x00\xff\xff\xff\xff\x02\x00\x00\x00\x54\x00\x00\x00\x09\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x05\x00\x00\x00\x1d\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\x18\x00\x00\x00\x59\x00\x00\x00\x4a\x00\x00\x00\x4b\x00\x00\x00\x5a\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x54\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x00\x00\x47\x00\x00\x00\x5e\x00\x00\x00\x44\x00\x00\x00\x45\x00\x00\x00\x46\x00\x00\x00\x47\x00\x00\x00\x40\x00\x00\x00\x04\x00\x00\x00\x41\x00\x00\x00\x50\x00\x00\x00\x51\x00\x00\x00\x2c\x00\x00\x00\x2d\x00\x00\x00\x5c\x00\x00\x00\x5d\x00\x00\x00\x25\x00\x00\x00\x26\x00\x00\x00\x30\x00\x00\x00\x26\x00\x00\x00\x04\x00\x00\x00\x28\x00\x00\x00\x29\x00\x00\x00\x25\x00\x00\x00\x24\x00\x00\x00\x23\x00\x00\x00\x22\x00\x00\x00\x1f\x00\x00\x00\x1c\x00\x00\x00\x1b\x00\x00\x00\x1a\x00\x00\x00\x1f\x00\x00\x00\x19\x00\x00\x00\x39\x00\x00\x00\x04\x00\x00\x00\x36\x00\x00\x00\x35\x00\x00\x00\x33\x00\x00\x00\x28\x00\x00\x00\x30\x00\x00\x00\x2f\x00\x00\x00\x3a\x00\x00\x00\x3f\x00\x00\x00\x49\x00\x00\x00\x3c\x00\x00\x00\x42\x00\x00\x00\x49\x00\x00\x00\x43\x00\x00\x00\x4c\x00\x00\x00\x49\x00\x00\x00\x52\x00\x00\x00\x58\x00\x00\x00\x59\x00\x00\x00\x49\x00\x00\x00\x49\x00\x00\x00\x56\x00\x00\x00\x49\x00\x00\x00\x5e\x00\x00\x00\x4d\x00\x00\x00\x29\x00\x00\x00\x3a\x00\x00\x00\x02\x00\x00\x00\x2b\x00\x00\x00\x3c\x00\x00\x00\x3d\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x00\x00\x1d\x00\x00\x00\x5f\x00\x00\x00\x33\x00\x00\x00\x37\x00\x00\x00\x36\x00\x00\x00\x31\x00\x00\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# -happyReduceArr = Happy_Data_Array.array (1, 55) [ +happyReduceArr = Happy_Data_Array.array (1, 56) [ (1 , happyReduce_1), (2 , happyReduce_2), (3 , happyReduce_3), @@ -253,16 +253,17 @@ happyReduceArr = Happy_Data_Array.array (1, 55) [ (52 , happyReduce_52), (53 , happyReduce_53), (54 , happyReduce_54), - (55 , happyReduce_55) + (55 , happyReduce_55), + (56 , happyReduce_56) ] happyRuleArr :: HappyAddr -happyRuleArr = HappyA# "\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x03\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x03\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x02\x00\x00\x00\x0d\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x0e\x00\x00\x00\x05\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x11\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00"# +happyRuleArr = HappyA# "\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x07\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x03\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x03\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x0c\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x02\x00\x00\x00\x0d\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x0e\x00\x00\x00\x05\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0e\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x02\x00\x00\x00\x0e\x00\x00\x00\x03\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x11\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x01\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00"# -happyCatchStates :: [Int] +happyCatchStates :: [Prelude.Int] happyCatchStates = [] -happy_n_terms = 31 :: Prelude.Int +happy_n_terms = 32 :: Prelude.Int happy_n_nonterms = 20 :: Prelude.Int happy_n_starts = 1 :: Prelude.Int @@ -713,15 +714,24 @@ happyReduction_44 happy_x_1 happyReduce_45 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) happyReduce_45 = happySpecReduce_2 14# happyReduction_45 happyReduction_45 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_2 of { (TokenInfo happy_var_2 TokId) -> + happyIn19 + (TokenErrorHandlerType happy_var_2 + )} + +happyReduce_46 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_46 = happySpecReduce_2 14# happyReduction_46 +happyReduction_46 happy_x_2 happy_x_1 = case happyOutTok happy_x_2 of { (TokenInfo happy_var_2 TokCodeQuote) -> happyIn19 (TokenAttributetype happy_var_2 )} -happyReduce_46 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_46 = happySpecReduce_3 14# happyReduction_46 -happyReduction_46 happy_x_3 +happyReduce_47 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_47 = happySpecReduce_3 14# happyReduction_47 +happyReduction_47 happy_x_3 happy_x_2 happy_x_1 = case happyOutTok happy_x_2 of { (TokenInfo happy_var_2 TokId) -> @@ -730,23 +740,23 @@ happyReduction_46 happy_x_3 (TokenAttribute happy_var_2 happy_var_3 )}} -happyReduce_47 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_47 = happySpecReduce_1 15# happyReduction_47 -happyReduction_47 happy_x_1 +happyReduce_48 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_48 = happySpecReduce_1 15# happyReduction_48 +happyReduction_48 happy_x_1 = case happyOutTok happy_x_1 of { (TokenInfo happy_var_1 TokId) -> happyIn20 (Just happy_var_1 )} -happyReduce_48 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_48 = happySpecReduce_0 15# happyReduction_48 -happyReduction_48 = happyIn20 +happyReduce_49 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_49 = happySpecReduce_0 15# happyReduction_49 +happyReduction_49 = happyIn20 (Nothing ) -happyReduce_49 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_49 = happySpecReduce_2 16# happyReduction_49 -happyReduction_49 happy_x_2 +happyReduce_50 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_50 = happySpecReduce_2 16# happyReduction_50 +happyReduction_50 happy_x_2 happy_x_1 = case happyOut22 happy_x_1 of { (HappyWrap22 happy_var_1) -> case happyOut21 happy_x_2 of { (HappyWrap21 happy_var_2) -> @@ -754,17 +764,17 @@ happyReduction_49 happy_x_2 (happy_var_1:happy_var_2 )}} -happyReduce_50 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_50 = happySpecReduce_1 16# happyReduction_50 -happyReduction_50 happy_x_1 +happyReduce_51 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_51 = happySpecReduce_1 16# happyReduction_51 +happyReduction_51 happy_x_1 = case happyOut22 happy_x_1 of { (HappyWrap22 happy_var_1) -> happyIn21 ([happy_var_1] )} -happyReduce_51 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_51 = happySpecReduce_2 17# happyReduction_51 -happyReduction_51 happy_x_2 +happyReduce_52 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_52 = happySpecReduce_2 17# happyReduction_52 +happyReduction_52 happy_x_2 happy_x_1 = case happyOutTok happy_x_1 of { (TokenInfo happy_var_1 TokId) -> case happyOutTok happy_x_2 of { (TokenInfo happy_var_2 TokCodeQuote) -> @@ -772,9 +782,9 @@ happyReduction_51 happy_x_2 ((happy_var_1, parseTokenSpec happy_var_2) )}} -happyReduce_52 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_52 = happySpecReduce_2 18# happyReduction_52 -happyReduction_52 happy_x_2 +happyReduce_53 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_53 = happySpecReduce_2 18# happyReduction_53 +happyReduction_53 happy_x_2 happy_x_1 = case happyOutTok happy_x_1 of { (TokenInfo happy_var_1 TokId) -> case happyOut23 happy_x_2 of { (HappyWrap23 happy_var_2) -> @@ -782,28 +792,28 @@ happyReduction_52 happy_x_2 (happy_var_1 : happy_var_2 )}} -happyReduce_53 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_53 = happySpecReduce_0 18# happyReduction_53 -happyReduction_53 = happyIn23 +happyReduce_54 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_54 = happySpecReduce_0 18# happyReduction_54 +happyReduction_54 = happyIn23 ([] ) -happyReduce_54 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_54 = happySpecReduce_1 19# happyReduction_54 -happyReduction_54 happy_x_1 +happyReduce_55 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_55 = happySpecReduce_1 19# happyReduction_55 +happyReduction_55 happy_x_1 = case happyOutTok happy_x_1 of { (TokenInfo happy_var_1 TokCodeQuote) -> happyIn24 (Just happy_var_1 )} -happyReduce_55 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) -happyReduce_55 = happySpecReduce_0 19# happyReduction_55 -happyReduction_55 = happyIn24 +happyReduce_56 :: () => Happy_GHC_Exts.Int# -> Token -> Happy_GHC_Exts.Int# -> Happy_IntList -> HappyStk (HappyAbsSyn ) -> P (HappyAbsSyn ) +happyReduce_56 = happySpecReduce_0 19# happyReduction_56 +happyReduction_56 = happyIn24 (Nothing ) happyTerminalToTok term = case term of { - TokenEOF -> 30#; + TokenEOF -> 31#; TokenInfo happy_dollar_dollar TokId -> 2#; TokenKW TokSpecId_TokenType -> 3#; TokenKW TokSpecId_Token -> 4#; @@ -820,19 +830,20 @@ happyTerminalToTok term = case term of { TokenKW TokSpecId_Expect -> 15#; TokenKW TokSpecId_Error -> 16#; TokenKW TokSpecId_ErrorExpected -> 17#; - TokenKW TokSpecId_Attribute -> 18#; - TokenKW TokSpecId_Attributetype -> 19#; - TokenInfo happy_dollar_dollar TokCodeQuote -> 20#; - TokenNum happy_dollar_dollar TokNum -> 21#; - TokenKW TokColon -> 22#; - TokenKW TokSemiColon -> 23#; - TokenKW TokDoubleColon -> 24#; - TokenKW TokDoublePercent -> 25#; - TokenKW TokBar -> 26#; - TokenKW TokParenL -> 27#; - TokenKW TokParenR -> 28#; - TokenKW TokComma -> 29#; - _ -> error "Encountered a token that was not declared to happy" + TokenKW TokSpecId_ErrorHandlerType -> 18#; + TokenKW TokSpecId_Attribute -> 19#; + TokenKW TokSpecId_Attributetype -> 20#; + TokenInfo happy_dollar_dollar TokCodeQuote -> 21#; + TokenNum happy_dollar_dollar TokNum -> 22#; + TokenKW TokColon -> 23#; + TokenKW TokSemiColon -> 24#; + TokenKW TokDoubleColon -> 25#; + TokenKW TokDoublePercent -> 26#; + TokenKW TokBar -> 27#; + TokenKW TokParenL -> 28#; + TokenKW TokParenR -> 29#; + TokenKW TokComma -> 30#; + _ -> -1#; } {-# NOINLINE happyTerminalToTok #-} @@ -841,9 +852,9 @@ happyLex kend kmore = lexTokenP (\tk -> case tk of { _ -> kmore (happyTerminalToTok tk) tk }) {-# INLINE happyLex #-} -happyNewToken action sts stk = happyLex (\tk -> happyDoAction 30# tk action sts stk) (\i tk -> happyDoAction i tk action sts stk) +happyNewToken action sts stk = happyLex (\tk -> happyDoAction 31# tk action sts stk) (\i tk -> happyDoAction i tk action sts stk) -happyReport 30# = happyReport' +happyReport 31# = happyReport' happyReport _ = happyReport' @@ -868,7 +879,7 @@ happyReport' :: () => (Token) -> [Prelude.String] -> (P a) -> (P a) happyReport' = (\tokens expected resume -> happyError) happyAbort :: () => (P a) -happyAbort = error "Called abort handler in non-resumptive parser" +happyAbort = Prelude.error "Called abort handler in non-resumptive parser" ourParser = happySomeParser where happySomeParser = happyThen (happyParse 0#) (\x -> happyReturn (let {(HappyWrap5 x') = happyOut5 x} in x')) @@ -900,6 +911,7 @@ happyError = failP (\l -> show l ++ ": Parse error\n") type Happy_Int = Happy_GHC_Exts.Int# data Happy_IntList = HappyCons Happy_Int Happy_IntList +#define INVALID_TOK -1# #define ERROR_TOK 0# #define CATCH_TOK 1# @@ -914,10 +926,10 @@ data Happy_IntList = HappyCons Happy_Int Happy_IntList #endif #if defined(HAPPY_DEBUG) -# define DEBUG_TRACE(s) (happyTrace (s)) $ -happyTrace string expr = Happy_System_IO_Unsafe.unsafePerformIO $ do +# define DEBUG_TRACE(s) (happyTrace (s)) Prelude.$ +happyTrace string expr = Happy_System_IO_Unsafe.unsafePerformIO Prelude.$ do Happy_System_IO.hPutStr Happy_System_IO.stderr string - return expr + Prelude.return expr #else # define DEBUG_TRACE(s) {- nothing -} #endif @@ -945,23 +957,23 @@ happyAccept j tk st sts (HappyStk ans _) = -- Arrays only: do the next action happyDoAction i tk st = - DEBUG_TRACE("state: " ++ show (Happy_GHC_Exts.I# st) ++ - ",\ttoken: " ++ show (Happy_GHC_Exts.I# i) ++ + DEBUG_TRACE("state: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ + ",\ttoken: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ ",\taction: ") case happyDecodeAction (happyNextAction i st) of HappyFail -> DEBUG_TRACE("failing.\n") happyFail i tk st HappyAccept -> DEBUG_TRACE("accept.\n") happyAccept i tk st - HappyReduce rule -> DEBUG_TRACE("reduce (rule " ++ show (Happy_GHC_Exts.I# rule) ++ ")") + HappyReduce rule -> DEBUG_TRACE("reduce (rule " Prelude.++ Prelude.show (Happy_GHC_Exts.I# rule) Prelude.++ ")") (happyReduceArr Happy_Data_Array.! (Happy_GHC_Exts.I# rule)) i tk st - HappyShift new_state -> DEBUG_TRACE("shift, enter state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") + HappyShift new_state -> DEBUG_TRACE("shift, enter state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") happyShift new_state i tk st {-# INLINE happyNextAction #-} happyNextAction i st = case happyIndexActionTable i st of - Just (Happy_GHC_Exts.I# act) -> act - Nothing -> happyIndexOffAddr happyDefActions st + Prelude.Just (Happy_GHC_Exts.I# act) -> act + Prelude.Nothing -> happyIndexOffAddr happyDefActions st {-# INLINE happyIndexActionTable #-} happyIndexActionTable i st @@ -970,7 +982,7 @@ happyIndexActionTable i st -- off >= 0: Otherwise it's a default action -- equality check: Ensure that the entry in the compressed array is owned by st = Prelude.Just (Happy_GHC_Exts.I# (happyIndexOffAddr happyTable off)) - | otherwise + | Prelude.otherwise = Prelude.Nothing where off = PLUS(happyIndexOffAddr happyActOffsets st, i) @@ -980,14 +992,14 @@ data HappyAction | HappyAccept | HappyReduce Happy_Int -- rule number | HappyShift Happy_Int -- new state - deriving Show + deriving Prelude.Show {-# INLINE happyDecodeAction #-} happyDecodeAction :: Happy_Int -> HappyAction happyDecodeAction 0# = HappyFail happyDecodeAction -1# = HappyAccept happyDecodeAction action | LT(action, 0#) = HappyReduce NEGATE(PLUS(action, 1#)) - | otherwise = HappyShift MINUS(action, 1#) + | Prelude.otherwise = HappyShift MINUS(action, 1#) {-# INLINE happyIndexGotoTable #-} happyIndexGotoTable nt st = happyIndexOffAddr happyTable off @@ -1086,7 +1098,7 @@ happyDropStk n (x `HappyStk` xs) = happyDropStk MINUS(n,(1#::Happy_Int)) xs -- Moving to a new state after a reduction happyGoto nt j tk st = - DEBUG_TRACE(", goto state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") + DEBUG_TRACE(", goto state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") happyDoAction j tk new_state where new_state = happyIndexGotoTable nt st @@ -1136,8 +1148,8 @@ It is best understood by example. Consider Exp :: { String } Exp : '1' { "1" } | catch { "catch" } - | Exp '+' Exp %shift { $1 ++ " + " ++ $3 } -- %shift: associate 1 + 1 + 1 to the right - | '(' Exp ')' { "(" ++ $2 ++ ")" } + | Exp '+' Exp %shift { $1 Prelude.++ " + " Prelude.++ $3 } -- %shift: associate 1 + 1 + 1 to the right + | '(' Exp ')' { "(" Prelude.++ $2 Prelude.++ ")" } The idea of the use of `catch` here is that upon encountering a parse error during expression parsing, we can gracefully degrade using the `catch` rule, @@ -1214,7 +1226,7 @@ In general, we pick the catch frame for resumption that discards the least amount of input for a successful shift, preferring the topmost such catch frame. -} --- happyFail :: Happy_Int -> _ -> Happy_Int -> _ +-- happyFail :: Happy_Int -> Token -> Happy_Int -> _ -- This function triggers Note [Error recovery]. -- If the current token is ERROR_TOK, phase (1) has failed and we might try -- phase (2). @@ -1240,72 +1252,72 @@ happyFixupFailed tk st sts (x `HappyStk` stk) = expected = happyExpectedTokens st sts in happyReport i tk expected resume --- happyResume :: Happy_Int -> _ -> Happy_Int -> _ +-- happyResume :: Happy_Int -> Token -> Happy_Int -> _ -- See Note [happyResume] happyResume i tk st sts stk = pop_items [] st sts stk where !(Happy_GHC_Exts.I# n_starts) = happy_n_starts -- this is to test whether we have a start token - !(Happy_GHC_Exts.I# eof_i) = happy_n_terms - 1 -- this is the token number of the EOF token - happy_list_to_list :: Happy_IntList -> [Int] + !(Happy_GHC_Exts.I# eof_i) = happy_n_terms Prelude.- 1 -- this is the token number of the EOF token + happy_list_to_list :: Happy_IntList -> [Prelude.Int] happy_list_to_list (HappyCons st sts) | LT(st, n_starts) = [(Happy_GHC_Exts.I# st)] - | otherwise + | Prelude.otherwise = (Happy_GHC_Exts.I# st) : happy_list_to_list sts -- See (1) of Note [happyResume] pop_items catch_frames st sts stk | LT(st, n_starts) - = DEBUG_TRACE("reached start state " ++ show (Happy_GHC_Exts.I# st) ++ ", ") - if null catch_frames_new + = DEBUG_TRACE("reached start state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", ") + if Prelude.null catch_frames_new then DEBUG_TRACE("no resumption.\n") happyAbort - else DEBUG_TRACE("now discard input, trying to anchor in states (reverse " ++ show (map (happy_list_to_list . fst) catch_frames_new) ++ ").\n") - discard_input_until_exp i tk (reverse catch_frames_new) + else DEBUG_TRACE("now discard input, trying to anchor in states " Prelude.++ Prelude.show (Prelude.map (happy_list_to_list . Prelude.fst) (Prelude.reverse catch_frames_new)) Prelude.++ ".\n") + discard_input_until_exp i tk (Prelude.reverse catch_frames_new) | (HappyCons st1 sts1) <- sts, _ `HappyStk` stk1 <- stk = pop_items catch_frames_new st1 sts1 stk1 where !catch_frames_new | HappyShift new_state <- happyDecodeAction (happyNextAction CATCH_TOK st) - , DEBUG_TRACE("can shift catch token in state " ++ show (Happy_GHC_Exts.I# st) ++ ", into state " ++ show (Happy_GHC_Exts.I# new_state) ++ "\n") - null (filter (\(HappyCons _ (HappyCons h _),_) -> EQ(st,h)) catch_frames) + , DEBUG_TRACE("can shift catch token in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", into state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# new_state) Prelude.++ "\n") + Prelude.null (Prelude.filter (\(HappyCons _ (HappyCons h _),_) -> EQ(st,h)) catch_frames) = (HappyCons new_state (HappyCons st sts), MK_ERROR_TOKEN(i) `HappyStk` stk):catch_frames -- MK_ERROR_TOKEN(i) is just some dummy that should not be accessed by user code - | otherwise - = DEBUG_TRACE("already shifted or can't shift catch in " ++ show (Happy_GHC_Exts.I# st) ++ "\n") + | Prelude.otherwise + = DEBUG_TRACE("already shifted or can't shift catch in " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ "\n") catch_frames -- See (2) of Note [happyResume] discard_input_until_exp i tk catch_frames - | Just (HappyCons st (HappyCons catch_st sts), catch_frame) <- some_catch_state_shifts i catch_frames - = DEBUG_TRACE("found expected token in state " ++ show (Happy_GHC_Exts.I# st) ++ " after shifting from " ++ show (Happy_GHC_Exts.I# catch_st) ++ ": " ++ show (Happy_GHC_Exts.I# i) ++ "\n") + | Prelude.Just (HappyCons st (HappyCons catch_st sts), catch_frame) <- some_catch_state_shifts i catch_frames + = DEBUG_TRACE("found expected token in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ " after shifting from " Prelude.++ Prelude.show (Happy_GHC_Exts.I# catch_st) Prelude.++ ": " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ "\n") happyDoAction i tk st (HappyCons catch_st sts) catch_frame | EQ(i,eof_i) -- is i EOF? = DEBUG_TRACE("reached EOF, cannot resume. abort parse :(\n") happyAbort - | otherwise - = DEBUG_TRACE("discard token " ++ show (Happy_GHC_Exts.I# i) ++ "\n") + | Prelude.otherwise + = DEBUG_TRACE("discard token " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ "\n") happyLex (\eof_tk -> discard_input_until_exp eof_i eof_tk catch_frames) -- eof (\i tk -> discard_input_until_exp i tk catch_frames) -- not eof - some_catch_state_shifts _ [] = DEBUG_TRACE("no catch state could shift.\n") Nothing + some_catch_state_shifts _ [] = DEBUG_TRACE("no catch state could shift.\n") Prelude.Nothing some_catch_state_shifts i catch_frames@(((HappyCons st sts),_):_) = try_head i st sts catch_frames where try_head i st sts catch_frames = -- PRECONDITION: head catch_frames = (HappyCons st sts) - DEBUG_TRACE("trying token " ++ show (Happy_GHC_Exts.I# i) ++ " in state " ++ show (Happy_GHC_Exts.I# st) ++ ": ") + DEBUG_TRACE("trying token " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ " in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ": ") case happyDecodeAction (happyNextAction i st) of - HappyFail -> DEBUG_TRACE("fail.\n") some_catch_state_shifts i (tail catch_frames) - HappyAccept -> DEBUG_TRACE("accept.\n") Just (head catch_frames) - HappyShift _ -> DEBUG_TRACE("shift.\n") Just (head catch_frames) + HappyFail -> DEBUG_TRACE("fail.\n") some_catch_state_shifts i (Prelude.tail catch_frames) + HappyAccept -> DEBUG_TRACE("accept.\n") Prelude.Just (Prelude.head catch_frames) + HappyShift _ -> DEBUG_TRACE("shift.\n") Prelude.Just (Prelude.head catch_frames) HappyReduce r -> case happySimulateReduce r st sts of (HappyCons st1 sts1) -> try_head i st1 sts1 catch_frames happySimulateReduce r st sts = - DEBUG_TRACE("simulate reduction of rule " ++ show (Happy_GHC_Exts.I# r) ++ ", ") + DEBUG_TRACE("simulate reduction of rule " Prelude.++ Prelude.show (Happy_GHC_Exts.I# r) Prelude.++ ", ") let (# nt, len #) = happyIndexRuleArr r in - DEBUG_TRACE("nt " ++ show (Happy_GHC_Exts.I# nt) ++ ", len: " ++ show (Happy_GHC_Exts.I# len) ++ ", new_st ") + DEBUG_TRACE("nt " Prelude.++ Prelude.show (Happy_GHC_Exts.I# nt) Prelude.++ ", len: " Prelude.++ Prelude.show (Happy_GHC_Exts.I# len) Prelude.++ ", new_st ") let !(sts1@(HappyCons st1 _)) = happyDrop len (HappyCons st sts) new_st = happyIndexGotoTable nt st1 in - DEBUG_TRACE(show (Happy_GHC_Exts.I# new_st) ++ ".\n") + DEBUG_TRACE(Prelude.show (Happy_GHC_Exts.I# new_st) Prelude.++ ".\n") (HappyCons new_st sts1) happyTokenToString :: Prelude.Int -> Prelude.String @@ -1322,11 +1334,11 @@ happyExpectedTokens :: Happy_Int -> Happy_IntList -> [Prelude.String] -- returned. happyExpectedTokens st sts = DEBUG_TRACE("constructing expected tokens.\n") - map happyTokenToString $ search_shifts st sts [] + Prelude.map happyTokenToString (search_shifts st sts []) where - search_shifts st sts shifts = foldr (add_action st sts) shifts (distinct_actions st) + search_shifts st sts shifts = Prelude.foldr (add_action st sts) shifts (distinct_actions st) add_action st sts (Happy_GHC_Exts.I# i, Happy_GHC_Exts.I# act) shifts = - DEBUG_TRACE("found action in state " ++ show (Happy_GHC_Exts.I# st) ++ ", input " ++ show (Happy_GHC_Exts.I# i) ++ ", " ++ show (happyDecodeAction act) ++ "\n") + DEBUG_TRACE("found action in state " Prelude.++ Prelude.show (Happy_GHC_Exts.I# st) Prelude.++ ", input " Prelude.++ Prelude.show (Happy_GHC_Exts.I# i) Prelude.++ ", " Prelude.++ Prelude.show (happyDecodeAction act) Prelude.++ "\n") case happyDecodeAction act of HappyFail -> shifts HappyAccept -> shifts -- This would always be %eof or error... Not helpful @@ -1345,7 +1357,7 @@ happyExpectedTokens st sts = , GTE(off_i,0#) , EQ(happyIndexOffAddr happyCheck off_i,i) = [(Happy_GHC_Exts.I# (happyIndexOffAddr happyTable off_i))] - | otherwise + | Prelude.otherwise = [] -- Internal happy errors: @@ -1363,7 +1375,7 @@ happyTcHack x y = y ----------------------------------------------------------------------------- -- Seq-ing. If the --strict flag is given, then Happy emits -- happySeq = happyDoSeq --- otherwise it emits +-- Prelude.otherwise it emits -- happySeq = happyDontSeq happyDoSeq, happyDontSeq :: a -> b -> b diff --git a/lib/grammar/src/Happy/Grammar.lhs b/lib/grammar/src/Happy/Grammar.lhs index bb7ea2a5..b4376720 100644 --- a/lib/grammar/src/Happy/Grammar.lhs +++ b/lib/grammar/src/Happy/Grammar.lhs @@ -17,7 +17,8 @@ The Grammar data type. > Priority(..), > Assoc(..), > ErrorHandlerInfo(..), -> Pragmas(..), +> ErrorExpectedMode(..), +> Directives(..), > > errorName, errorTok, catchName, catchTok, > startName, dummyName, firstStartTok, dummyTok, @@ -111,16 +112,22 @@ The Grammar data type. > -- Then try to resume parsing by finding a catch production. > -- If that ultimately fails, call `abort`. +> data ErrorExpectedMode +> = NoExpected -- ^ Neither `%errorhandertype explist` nor `%error.expected` +> | OldExpected -- ^ `%errorhandertype explist`. The error handler takes a pair `(Token, [String])` +> | NewExpected -- ^ `%error.expected`. The error handler takes two (or more) args `Token -> [String] -> ...`. +> deriving Eq + > -- | Stuff like `\%monad`, `\%expect` -> data Pragmas -> = Pragmas { +> data Directives +> = Directives { > token_type :: String, > imported_identity :: Bool, > monad :: (Bool,String,String,String,String), > expect :: Maybe Int, > lexer :: Maybe (String,String), > error_handler :: ErrorHandlerInfo, -> error_expected :: Bool +> error_expected :: ErrorExpectedMode > -- ^ Error handler specified in `error_handler` takes > -- a `[String]` carrying the pretty-printed expected tokens > } diff --git a/lib/happy-lib.cabal b/lib/happy-lib.cabal index 6eb3bf8f..a5bc31a0 100644 --- a/lib/happy-lib.cabal +++ b/lib/happy-lib.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: happy-lib -version: 2.1 +version: 2.1.1 license: BSD-2-Clause copyright: (c) Andy Gill, Simon Marlow author: Andy Gill and Simon Marlow diff --git a/tests/monaderror-explist.y b/tests/monaderror-explist.y index dd84d23c..558f28ee 100644 --- a/tests/monaderror-explist.y +++ b/tests/monaderror-explist.y @@ -14,8 +14,8 @@ import Data.List (isPrefixOf) %name parseFoo %tokentype { Token } +%errorhandlertype explist %error { handleErrorExpList } -%error.expected %monad { ParseM } { (>>=) } { return } @@ -46,9 +46,9 @@ data Token | TokenTest deriving (Eq,Show) -handleErrorExpList :: [Token] -> [String] -> ParseM a -handleErrorExpList [] _ = throwError $ ParseError Nothing -handleErrorExpList ts explist = throwError $ ParseError $ Just $ (head ts, explist) +handleErrorExpList :: ([Token], [String]) -> ParseM a +handleErrorExpList ([], _) = throwError $ ParseError Nothing +handleErrorExpList (ts, explist) = throwError $ ParseError $ Just $ (head ts, explist) lexer :: String -> [Token] lexer [] = [] diff --git a/tests/monaderror-lexer-explist.y b/tests/monaderror-lexer-explist.y new file mode 100644 index 00000000..74b86df4 --- /dev/null +++ b/tests/monaderror-lexer-explist.y @@ -0,0 +1,79 @@ +{ +{-# LANGUAGE FunctionalDependencies #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiWayIf #-} +-- For ancient GHC 7.0.4 +{-# LANGUAGE MultiParamTypeClasses #-} +module Main where + +import Data.Char +import Control.Monad (when) +import System.Exit +import System.Environment (getProgName) +import Data.List (isPrefixOf) +import Control.Monad.Trans.State +import Control.Monad.Trans.Except +import Control.Monad.Trans.Class +} + +%name parseFoo +%tokentype { Token } +%errorhandlertype explist +%error { handleErrorExpList } +%lexer { lexer } { TokenEOF } + +%monad { ParseM } { (>>=) } { return } + +%token + 'S' { TokenSucc } + 'Z' { TokenZero } + 'T' { TokenTest } + +%% + +Exp : 'Z' { 0 } + | 'T' 'Z' Exp { $3 + 1 } + | 'S' Exp { $2 + 1 } + +{ + +type ParseM a = ExceptT ParseError (State String) a +data ParseError = ParseError (Maybe (Token, [String])) + deriving (Eq,Show) + +data Token + = TokenSucc + | TokenZero + | TokenTest + | TokenEOF + deriving (Eq,Show) + +handleErrorExpList :: (Token, [String]) -> ParseM a +handleErrorExpList (t, explist) = throwE $ ParseError $ Just $ (t, explist) + +lexer :: (Token -> ParseM a) -> ParseM a +lexer cont = do + toks <- lift get + case toks of + [] -> cont TokenEOF + c : rest -> do + lift $ put rest + if | isSpace c -> lexer cont + | c == 'S' -> cont TokenSucc + | c == 'Z' -> cont TokenZero + | c == 'T' -> cont TokenTest + | otherwise -> error "lexer error" + +main :: IO () +main = do + test "Z Z" $ Left (ParseError (Just (TokenZero,[]))) + test "T S" $ Left (ParseError (Just (TokenSucc,["'Z'"]))) + + where + test inp exp = do + putStrLn $ "testing " ++ inp + let act = evalState (runExceptT parseFoo) inp + when (act /= exp) $ do + print act + exitWith (ExitFailure 1) +} diff --git a/tests/monaderror-newexplist.y b/tests/monaderror-newexplist.y new file mode 100644 index 00000000..dd84d23c --- /dev/null +++ b/tests/monaderror-newexplist.y @@ -0,0 +1,84 @@ +{ +{-# LANGUAGE FunctionalDependencies #-} +{-# LANGUAGE FlexibleInstances #-} +-- For ancient GHC 7.0.4 +{-# LANGUAGE MultiParamTypeClasses #-} +module Main where + +import Data.Char +import Control.Monad (when) +import System.Exit +import System.Environment (getProgName) +import Data.List (isPrefixOf) +} + +%name parseFoo +%tokentype { Token } +%error { handleErrorExpList } +%error.expected + +%monad { ParseM } { (>>=) } { return } + +%token + 'S' { TokenSucc } + 'Z' { TokenZero } + 'T' { TokenTest } + +%% + +Exp : 'Z' { 0 } + | 'T' 'Z' Exp { $3 + 1 } + | 'S' Exp { $2 + 1 } + +{ + +type ParseM a = Either ParseError a +data ParseError + = ParseError (Maybe (Token, [String])) + | StringError String + deriving (Eq,Show) +instance Error ParseError where + strMsg = StringError + +data Token + = TokenSucc + | TokenZero + | TokenTest + deriving (Eq,Show) + +handleErrorExpList :: [Token] -> [String] -> ParseM a +handleErrorExpList [] _ = throwError $ ParseError Nothing +handleErrorExpList ts explist = throwError $ ParseError $ Just $ (head ts, explist) + +lexer :: String -> [Token] +lexer [] = [] +lexer (c:cs) + | isSpace c = lexer cs + | c == 'S' = TokenSucc:(lexer cs) + | c == 'Z' = TokenZero:(lexer cs) + | c == 'T' = TokenTest:(lexer cs) + | otherwise = error "lexer error" + +main :: IO () +main = do + test "Z Z" $ Left (ParseError (Just (TokenZero,[]))) + test "T S" $ Left (ParseError (Just (TokenSucc,["'Z'"]))) + + where + test inp exp = do + putStrLn $ "testing " ++ inp + let tokens = lexer inp + when (parseFoo tokens /= exp) $ do + print (parseFoo tokens) + exitWith (ExitFailure 1) + +--- +class Error a where + noMsg :: a + noMsg = strMsg "" + strMsg :: String -> a +class Monad m => MonadError e m | m -> e where + throwError :: e -> m a +instance MonadError e (Either e) where + throwError = Left +}