alex-meta (empty) → 0.1.1
raw patch · 22 files changed
+4237/−0 lines, 22 filesdep +arraydep +basedep +containerssetup-changed
Dependencies added: array, base, containers, directory, haskell-src-meta, template-haskell, th-lift
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- Text/Alex/Quote.hs +26/−0
- alex-meta.cabal +47/−0
- dist/build/Parser.hs +1123/−0
- dist/build/Scan.hs +407/−0
- src/AbsSyn.hs +271/−0
- src/CharSet.hs +57/−0
- src/DFA.hs +250/−0
- src/DFS.hs +136/−0
- src/Info.hs +65/−0
- src/Map.hs +67/−0
- src/NFA.hs +215/−0
- src/Output.hs +345/−0
- src/ParseMonad.hs +128/−0
- src/Parser.y +220/−0
- src/Scan.x +218/−0
- src/Set.hs +14/−0
- src/Sort.hs +71/−0
- src/Text/Alex.hs +146/−0
- src/Text/Alex/AlexTemplate.hs +352/−0
- src/Util.hs +47/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2010, Chis Dornan, Jonas Duregard, Simon Marlow + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Jonas Duregard nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple +main = defaultMain
+ Text/Alex/Quote.hs view
@@ -0,0 +1,26 @@+module Text.Alex.Quote ( + parseAlex + , compileAlex + , alex + ) where + +import Text.Alex(runAlex, Target(..)) +import Text.Alex.AlexTemplate + +import Language.Haskell.TH.Quote +import Language.Haskell.TH +import Language.Haskell.TH.Lift + +import Language.Haskell.Meta + +type Alex = String + +compileAlex :: Alex -> Q [Dec] +compileAlex = return . either error id . parseDecs + +alex :: QuasiQuoter +alex = QuasiQuoter (lift . parseAlex) (error "pattern quoting is not supported") + +parseAlex :: String -> Alex +parseAlex s = fst (runAlex [] Nothing s) ++ "\n" ++ alexTemplate HaskellTarget + -- fst (runAlex [] Nothing s)
+ alex-meta.cabal view
@@ -0,0 +1,47 @@+Name: alex-meta +Version: 0.1.1 +Synopsis: Quasi-quoter for Alex lexers +-- Description: +License: BSD3 +License-file: LICENSE +Author: Jonas Duregard +Maintainer: jonas.duregard@gmail.com +Category: Development +Build-type: Simple + +Cabal-version: >=1.2 + + +Library + hs-source-dirs: src . + + extensions: CPP + + Exposed-modules: + Text.Alex.Quote + + -- Packages needed in order to build this package. + Build-depends: + template-haskell >=2.4&&<2.5 + , th-lift >=0.5&&<0.6 + , haskell-src-meta >=0.1.1&&<0.2 + , base >= 4.2 && < 5 + , array, containers, directory + + other-modules: + Text.Alex + Text.Alex.AlexTemplate + AbsSyn + CharSet + DFA + DFS + Info + Map + NFA + Output + Parser + ParseMonad + Scan + Set + Sort + Util
+ dist/build/Parser.hs view
@@ -0,0 +1,1123 @@+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-} +{-# OPTIONS -fglasgow-exts -cpp #-} +-- ----------------------------------------------------------------------------- +-- +-- Parser.y, part of Alex +-- +-- (c) Simon Marlow 2003 +-- +-- ----------------------------------------------------------------------------- + +{-# OPTIONS_GHC -w #-} + +module Parser ( parse, P ) where +import AbsSyn +import Scan +import CharSet +import ParseMonad hiding ( StartCode ) + +import Data.Char +--import Debug.Trace +import qualified Data.Array as Happy_Data_Array +import qualified GHC.Exts as Happy_GHC_Exts + +-- parser produced by Happy Version 1.18.5 + +newtype HappyAbsSyn = HappyAbsSyn HappyAny +#if __GLASGOW_HASKELL__ >= 607 +type HappyAny = Happy_GHC_Exts.Any +#else +type HappyAny = forall a . a +#endif +happyIn4 :: ((Maybe (AlexPosn,Code), [Directive], Scanner, Maybe (AlexPosn,Code))) -> (HappyAbsSyn ) +happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn4 #-} +happyOut4 :: (HappyAbsSyn ) -> ((Maybe (AlexPosn,Code), [Directive], Scanner, Maybe (AlexPosn,Code))) +happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut4 #-} +happyIn5 :: (Maybe (AlexPosn,Code)) -> (HappyAbsSyn ) +happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn5 #-} +happyOut5 :: (HappyAbsSyn ) -> (Maybe (AlexPosn,Code)) +happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut5 #-} +happyIn6 :: ([Directive]) -> (HappyAbsSyn ) +happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn6 #-} +happyOut6 :: (HappyAbsSyn ) -> ([Directive]) +happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut6 #-} +happyIn7 :: (Directive) -> (HappyAbsSyn ) +happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn7 #-} +happyOut7 :: (HappyAbsSyn ) -> (Directive) +happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut7 #-} +happyIn8 :: (()) -> (HappyAbsSyn ) +happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn8 #-} +happyOut8 :: (HappyAbsSyn ) -> (()) +happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut8 #-} +happyIn9 :: (()) -> (HappyAbsSyn ) +happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn9 #-} +happyOut9 :: (HappyAbsSyn ) -> (()) +happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut9 #-} +happyIn10 :: (Scanner) -> (HappyAbsSyn ) +happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn10 #-} +happyOut10 :: (HappyAbsSyn ) -> (Scanner) +happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut10 #-} +happyIn11 :: ([RECtx]) -> (HappyAbsSyn ) +happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn11 #-} +happyOut11 :: (HappyAbsSyn ) -> ([RECtx]) +happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut11 #-} +happyIn12 :: ([RECtx]) -> (HappyAbsSyn ) +happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn12 #-} +happyOut12 :: (HappyAbsSyn ) -> ([RECtx]) +happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut12 #-} +happyIn13 :: (RECtx) -> (HappyAbsSyn ) +happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn13 #-} +happyOut13 :: (HappyAbsSyn ) -> (RECtx) +happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut13 #-} +happyIn14 :: ([RECtx]) -> (HappyAbsSyn ) +happyIn14 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn14 #-} +happyOut14 :: (HappyAbsSyn ) -> ([RECtx]) +happyOut14 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut14 #-} +happyIn15 :: ([(String,StartCode)]) -> (HappyAbsSyn ) +happyIn15 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn15 #-} +happyOut15 :: (HappyAbsSyn ) -> ([(String,StartCode)]) +happyOut15 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut15 #-} +happyIn16 :: ([(String,StartCode)]) -> (HappyAbsSyn ) +happyIn16 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn16 #-} +happyOut16 :: (HappyAbsSyn ) -> ([(String,StartCode)]) +happyOut16 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut16 #-} +happyIn17 :: (String) -> (HappyAbsSyn ) +happyIn17 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn17 #-} +happyOut17 :: (HappyAbsSyn ) -> (String) +happyOut17 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut17 #-} +happyIn18 :: (Maybe Code) -> (HappyAbsSyn ) +happyIn18 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn18 #-} +happyOut18 :: (HappyAbsSyn ) -> (Maybe Code) +happyOut18 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut18 #-} +happyIn19 :: (Maybe CharSet, RExp, RightContext RExp) -> (HappyAbsSyn ) +happyIn19 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn19 #-} +happyOut19 :: (HappyAbsSyn ) -> (Maybe CharSet, RExp, RightContext RExp) +happyOut19 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut19 #-} +happyIn20 :: (CharSet) -> (HappyAbsSyn ) +happyIn20 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn20 #-} +happyOut20 :: (HappyAbsSyn ) -> (CharSet) +happyOut20 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut20 #-} +happyIn21 :: (RightContext RExp) -> (HappyAbsSyn ) +happyIn21 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn21 #-} +happyOut21 :: (HappyAbsSyn ) -> (RightContext RExp) +happyOut21 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut21 #-} +happyIn22 :: (RExp) -> (HappyAbsSyn ) +happyIn22 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn22 #-} +happyOut22 :: (HappyAbsSyn ) -> (RExp) +happyOut22 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut22 #-} +happyIn23 :: (RExp) -> (HappyAbsSyn ) +happyIn23 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn23 #-} +happyOut23 :: (HappyAbsSyn ) -> (RExp) +happyOut23 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut23 #-} +happyIn24 :: (RExp) -> (HappyAbsSyn ) +happyIn24 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn24 #-} +happyOut24 :: (HappyAbsSyn ) -> (RExp) +happyOut24 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut24 #-} +happyIn25 :: (RExp -> RExp) -> (HappyAbsSyn ) +happyIn25 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn25 #-} +happyOut25 :: (HappyAbsSyn ) -> (RExp -> RExp) +happyOut25 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut25 #-} +happyIn26 :: (RExp) -> (HappyAbsSyn ) +happyIn26 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn26 #-} +happyOut26 :: (HappyAbsSyn ) -> (RExp) +happyOut26 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut26 #-} +happyIn27 :: (CharSet) -> (HappyAbsSyn ) +happyIn27 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn27 #-} +happyOut27 :: (HappyAbsSyn ) -> (CharSet) +happyOut27 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut27 #-} +happyIn28 :: (CharSet) -> (HappyAbsSyn ) +happyIn28 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn28 #-} +happyOut28 :: (HappyAbsSyn ) -> (CharSet) +happyOut28 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut28 #-} +happyIn29 :: ([CharSet]) -> (HappyAbsSyn ) +happyIn29 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn29 #-} +happyOut29 :: (HappyAbsSyn ) -> ([CharSet]) +happyOut29 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut29 #-} +happyIn30 :: ((AlexPosn,String)) -> (HappyAbsSyn ) +happyIn30 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyIn30 #-} +happyOut30 :: (HappyAbsSyn ) -> ((AlexPosn,String)) +happyOut30 x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOut30 #-} +happyInTok :: (Token) -> (HappyAbsSyn ) +happyInTok x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyInTok #-} +happyOutTok :: (HappyAbsSyn ) -> (Token) +happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x +{-# INLINE happyOutTok #-} + + +happyActOffsets :: HappyAddr +happyActOffsets = HappyA# "\x72\x00\x72\x00\x66\x00\x00\x00\x52\x00\x51\x00\x60\x00\x67\x00\x00\x00\x00\x00\x63\x00\x51\x00\x7b\x00\x6d\x00\x00\x00\x5b\x00\x00\x00\x1a\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x49\x00\x7b\x00\x80\x00\x00\x00\x64\x00\x00\x00\x00\x00\x62\x00\x00\x00\x4d\x00\x13\x00\x00\x00\x13\x00\x00\x00\x01\x00\xff\xff\x6d\x00\x02\x00\x10\x00\x1b\x00\x00\x00\x00\x00\x7b\x00\x48\x00\x73\x00\x59\x00\x7b\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\x00\x00\x00\x6d\x00\x00\x00\x15\x00\x00\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x25\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\xf7\xff\x00\x00\x00\x00\x3c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# + +happyGotoOffsets :: HappyAddr +happyGotoOffsets = HappyA# "\x69\x00\x39\x00\x5c\x00\x00\x00\x00\x00\x4b\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x30\x00\x3a\x00\x11\x00\xfe\x00\x00\x00\x03\x01\x00\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x00\x2b\x00\x07\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x00\xaa\x00\x00\x00\x96\x00\x00\x00\xda\x00\xf6\xff\xec\x00\x22\x00\x00\x00\x20\x00\x00\x00\x00\x00\x23\x00\x00\x00\xc2\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\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\xf3\xff\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# + +happyDefActions :: HappyAddr +happyDefActions = HappyA# "\xfc\xff\x00\x00\xfa\xff\xfd\xff\x00\x00\xf7\xff\xfa\xff\x00\x00\xf9\xff\xfb\xff\x00\x00\xf7\xff\x00\x00\x00\x00\xf5\xff\xdb\xff\xd9\xff\xd7\xff\xcd\xff\xca\xff\xc7\xff\xc1\xff\x00\x00\x00\x00\xc2\xff\xcf\xff\xc9\xff\xc0\xff\xce\xff\xf6\xff\xf8\xff\xfc\xff\xf2\xff\xf4\xff\xf2\xff\xef\xff\x00\x00\x00\x00\x00\x00\xdd\xff\xcd\xff\x00\x00\xe2\xff\xfe\xff\x00\x00\x00\x00\xc2\xff\x00\x00\xc2\xff\xc4\xff\x00\x00\xd0\xff\xd8\xff\xd6\xff\xd5\xff\xd4\xff\x00\x00\xda\xff\x00\x00\xdc\xff\x00\x00\xcc\xff\x00\x00\xc6\xff\xc3\xff\xc8\xff\xcb\xff\x00\x00\xe9\xff\xe8\xff\xe7\xff\xe1\xff\xe3\xff\xe0\xff\x00\x00\xdd\xff\xee\xff\xe5\xff\xe6\xff\xf1\xff\xec\xff\xf3\xff\xec\xff\x00\x00\xe4\xff\xdf\xff\xde\xff\x00\x00\xeb\xff\xc5\xff\x00\x00\xd3\xff\xd2\xff\x00\x00\xea\xff\xf0\xff\xed\xff\xd1\xff"# + +happyCheck :: HappyAddr +happyCheck = HappyA# "\xff\xff\x02\x00\x01\x00\x0c\x00\x0e\x00\x12\x00\x13\x00\x14\x00\x06\x00\x16\x00\x17\x00\x18\x00\x0b\x00\x1a\x00\x0d\x00\x0c\x00\x0d\x00\x10\x00\x1b\x00\x12\x00\x01\x00\x14\x00\x03\x00\x15\x00\x17\x00\x1a\x00\x05\x00\x11\x00\x1b\x00\x1c\x00\x1d\x00\x0f\x00\x0d\x00\x0c\x00\x01\x00\x10\x00\x14\x00\x12\x00\x01\x00\x14\x00\x17\x00\x18\x00\x17\x00\x1a\x00\x0c\x00\x0d\x00\x1b\x00\x1c\x00\x1d\x00\x16\x00\x0d\x00\x11\x00\x19\x00\x10\x00\x06\x00\x12\x00\x01\x00\x14\x00\x01\x00\x18\x00\x17\x00\x1a\x00\x04\x00\x05\x00\x1b\x00\x1c\x00\x1d\x00\x18\x00\x0d\x00\x1a\x00\x15\x00\x10\x00\x0c\x00\x12\x00\x01\x00\x0c\x00\x02\x00\x03\x00\x17\x00\x04\x00\x05\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x05\x00\x0d\x00\x0e\x00\x04\x00\x10\x00\x13\x00\x12\x00\x01\x00\x1b\x00\x02\x00\x03\x00\x17\x00\x0e\x00\x07\x00\x1b\x00\x1b\x00\x1c\x00\x1d\x00\x1a\x00\x0d\x00\x00\x00\x01\x00\x10\x00\x13\x00\x12\x00\x01\x00\x1e\x00\x1f\x00\x0f\x00\x17\x00\x21\x00\x01\x00\x11\x00\x1b\x00\x1c\x00\x1d\x00\x0f\x00\x0d\x00\x18\x00\x01\x00\x10\x00\x17\x00\x12\x00\x20\x00\x01\x00\x0f\x00\x10\x00\x17\x00\x12\x00\x20\x00\xff\xff\x1b\x00\x1c\x00\x1d\x00\x10\x00\x1a\x00\x12\x00\x1b\x00\x1c\x00\x10\x00\xff\xff\x12\x00\xff\xff\x14\x00\xff\xff\x1b\x00\x1c\x00\xff\xff\xff\xff\xff\xff\x1b\x00\x1c\x00\x07\x00\x08\x00\x09\x00\xff\xff\x0b\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x07\x00\x08\x00\x09\x00\xff\xff\x0b\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x09\x00\x0a\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x09\x00\x0a\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\x14\x00\x09\x00\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x12\x00\x13\x00\x14\x00\xff\xff\x16\x00\x17\x00\x18\x00\x14\x00\x1a\x00\x16\x00\x17\x00\x18\x00\xff\xff\x1a\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x08\x00\x09\x00\x0a\x00\x0b\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"# + +happyTable :: HappyAddr +happyTable = HappyA# "\x00\x00\x4e\x00\x16\x00\x5d\x00\x4c\x00\x55\x00\x0f\x00\x10\x00\x4a\x00\x11\x00\x12\x00\x13\x00\x51\x00\x14\x00\x17\x00\x5e\x00\x44\x00\x18\x00\x5e\x00\x19\x00\x16\x00\x2b\x00\x2a\x00\x4b\x00\x1a\x00\x4f\x00\x5b\x00\x54\x00\x1b\x00\x1c\x00\x1d\x00\x2d\x00\x17\x00\x5c\x00\x2b\x00\x18\x00\x48\x00\x19\x00\x16\x00\x2b\x00\x1d\x00\x13\x00\x1a\x00\x14\x00\x43\x00\x44\x00\x1b\x00\x1c\x00\x1d\x00\x46\x00\x17\x00\x48\x00\x47\x00\x18\x00\x1f\x00\x19\x00\x16\x00\x2b\x00\x02\x00\x42\x00\x1a\x00\x14\x00\x1e\x00\x0b\x00\x1b\x00\x1c\x00\x1d\x00\x31\x00\x17\x00\x14\x00\x34\x00\x18\x00\x62\x00\x19\x00\x16\x00\x60\x00\x09\x00\x06\x00\x1a\x00\x0a\x00\x0b\x00\x57\x00\x1b\x00\x1c\x00\x1d\x00\x58\x00\x17\x00\x34\x00\x59\x00\x18\x00\x5a\x00\x19\x00\x16\x00\x3d\x00\x05\x00\x06\x00\x1a\x00\x3e\x00\x3b\x00\x42\x00\x1b\x00\x1c\x00\x1d\x00\x04\x00\x17\x00\x04\x00\x02\x00\x18\x00\x40\x00\x19\x00\x16\x00\x0d\x00\x0e\x00\x2d\x00\x1a\x00\xff\xff\x16\x00\x2e\x00\x1b\x00\x1c\x00\x1d\x00\x2d\x00\x17\x00\x21\x00\x16\x00\x18\x00\x09\x00\x19\x00\x08\x00\x16\x00\x2d\x00\x18\x00\x1a\x00\x19\x00\x08\x00\x00\x00\x1b\x00\x1c\x00\x1d\x00\x18\x00\x04\x00\x19\x00\x1b\x00\x1c\x00\x18\x00\x00\x00\x19\x00\x00\x00\x31\x00\x00\x00\x1b\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x1c\x00\x51\x00\x22\x00\x23\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x25\x00\x26\x00\x00\x00\x27\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x28\x00\x13\x00\x00\x00\x14\x00\x21\x00\x22\x00\x23\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x25\x00\x26\x00\x00\x00\x27\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x28\x00\x13\x00\x00\x00\x14\x00\x52\x00\x60\x00\x2e\x00\x13\x00\x3e\x00\x14\x00\x25\x00\x26\x00\x00\x00\x27\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x28\x00\x13\x00\x00\x00\x14\x00\x52\x00\x53\x00\x2e\x00\x13\x00\x40\x00\x14\x00\x25\x00\x26\x00\x00\x00\x27\x00\x0f\x00\x10\x00\x4f\x00\x11\x00\x28\x00\x13\x00\x00\x00\x14\x00\x25\x00\x26\x00\x00\x00\x27\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x28\x00\x13\x00\x00\x00\x14\x00\x3b\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x12\x00\x13\x00\x00\x00\x14\x00\x4b\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x12\x00\x13\x00\x00\x00\x14\x00\x32\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x12\x00\x13\x00\x00\x00\x14\x00\x0e\x00\x0f\x00\x10\x00\x00\x00\x11\x00\x12\x00\x13\x00\x39\x00\x14\x00\x11\x00\x12\x00\x13\x00\x00\x00\x14\x00\x2e\x00\x13\x00\x2f\x00\x14\x00\x36\x00\x37\x00\x38\x00\x39\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, 63) [ + (1 , happyReduce_1), + (2 , happyReduce_2), + (3 , happyReduce_3), + (4 , happyReduce_4), + (5 , happyReduce_5), + (6 , happyReduce_6), + (7 , happyReduce_7), + (8 , happyReduce_8), + (9 , happyReduce_9), + (10 , happyReduce_10), + (11 , happyReduce_11), + (12 , happyReduce_12), + (13 , happyReduce_13), + (14 , happyReduce_14), + (15 , happyReduce_15), + (16 , happyReduce_16), + (17 , happyReduce_17), + (18 , happyReduce_18), + (19 , happyReduce_19), + (20 , happyReduce_20), + (21 , happyReduce_21), + (22 , happyReduce_22), + (23 , happyReduce_23), + (24 , happyReduce_24), + (25 , happyReduce_25), + (26 , happyReduce_26), + (27 , happyReduce_27), + (28 , happyReduce_28), + (29 , happyReduce_29), + (30 , happyReduce_30), + (31 , happyReduce_31), + (32 , happyReduce_32), + (33 , happyReduce_33), + (34 , happyReduce_34), + (35 , happyReduce_35), + (36 , happyReduce_36), + (37 , happyReduce_37), + (38 , happyReduce_38), + (39 , happyReduce_39), + (40 , happyReduce_40), + (41 , happyReduce_41), + (42 , happyReduce_42), + (43 , happyReduce_43), + (44 , happyReduce_44), + (45 , happyReduce_45), + (46 , happyReduce_46), + (47 , happyReduce_47), + (48 , happyReduce_48), + (49 , happyReduce_49), + (50 , happyReduce_50), + (51 , happyReduce_51), + (52 , happyReduce_52), + (53 , happyReduce_53), + (54 , happyReduce_54), + (55 , happyReduce_55), + (56 , happyReduce_56), + (57 , happyReduce_57), + (58 , happyReduce_58), + (59 , happyReduce_59), + (60 , happyReduce_60), + (61 , happyReduce_61), + (62 , happyReduce_62), + (63 , happyReduce_63) + ] + +happy_n_terms = 34 :: Int +happy_n_nonterms = 27 :: Int + +happyReduce_1 = happyReduce 5# 0# happyReduction_1 +happyReduction_1 (happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut5 happy_x_1 of { happy_var_1 -> + case happyOut6 happy_x_2 of { happy_var_2 -> + case happyOut10 happy_x_4 of { happy_var_4 -> + case happyOut5 happy_x_5 of { happy_var_5 -> + happyIn4 + ((happy_var_1,happy_var_2,happy_var_4,happy_var_5) + ) `HappyStk` happyRest}}}} + +happyReduce_2 = happySpecReduce_1 1# happyReduction_2 +happyReduction_2 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn5 + (case happy_var_1 of T pos (CodeT code) -> + Just (pos,code) + )} + +happyReduce_3 = happySpecReduce_0 1# happyReduction_3 +happyReduction_3 = happyIn5 + (Nothing + ) + +happyReduce_4 = happySpecReduce_2 2# happyReduction_4 +happyReduction_4 happy_x_2 + happy_x_1 + = case happyOut7 happy_x_1 of { happy_var_1 -> + case happyOut6 happy_x_2 of { happy_var_2 -> + happyIn6 + (happy_var_1 : happy_var_2 + )}} + +happyReduce_5 = happySpecReduce_0 2# happyReduction_5 +happyReduction_5 = happyIn6 + ([] + ) + +happyReduce_6 = happySpecReduce_2 3# happyReduction_6 +happyReduction_6 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_2 of { (T _ (StringT happy_var_2)) -> + happyIn7 + (WrapperDirective happy_var_2 + )} + +happyReduce_7 = happySpecReduce_2 4# happyReduction_7 +happyReduction_7 happy_x_2 + happy_x_1 + = happyIn8 + (() + ) + +happyReduce_8 = happySpecReduce_0 4# happyReduction_8 +happyReduction_8 = happyIn8 + (() + ) + +happyReduce_9 = happyMonadReduce 2# 5# happyReduction_9 +happyReduction_9 (happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOutTok happy_x_1 of { (T _ (SMacDefT happy_var_1)) -> + case happyOut27 happy_x_2 of { happy_var_2 -> + ( newSMac happy_var_1 happy_var_2)}} + ) (\r -> happyReturn (happyIn9 r)) + +happyReduce_10 = happyMonadReduce 2# 5# happyReduction_10 +happyReduction_10 (happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOutTok happy_x_1 of { (T _ (RMacDefT happy_var_1)) -> + case happyOut22 happy_x_2 of { happy_var_2 -> + ( newRMac happy_var_1 happy_var_2)}} + ) (\r -> happyReturn (happyIn9 r)) + +happyReduce_11 = happySpecReduce_2 6# happyReduction_11 +happyReduction_11 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { (T _ (BindT happy_var_1)) -> + case happyOut11 happy_x_2 of { happy_var_2 -> + happyIn10 + (Scanner happy_var_1 happy_var_2 + )}} + +happyReduce_12 = happySpecReduce_2 7# happyReduction_12 +happyReduction_12 happy_x_2 + happy_x_1 + = case happyOut12 happy_x_1 of { happy_var_1 -> + case happyOut11 happy_x_2 of { happy_var_2 -> + happyIn11 + (happy_var_1 ++ happy_var_2 + )}} + +happyReduce_13 = happySpecReduce_0 7# happyReduction_13 +happyReduction_13 = happyIn11 + ([] + ) + +happyReduce_14 = happySpecReduce_2 8# happyReduction_14 +happyReduction_14 happy_x_2 + happy_x_1 + = case happyOut15 happy_x_1 of { happy_var_1 -> + case happyOut13 happy_x_2 of { happy_var_2 -> + happyIn12 + ([ replaceCodes happy_var_1 happy_var_2 ] + )}} + +happyReduce_15 = happyReduce 4# 8# happyReduction_15 +happyReduction_15 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOut15 happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_3 of { happy_var_3 -> + happyIn12 + (map (replaceCodes happy_var_1) happy_var_3 + ) `HappyStk` happyRest}} + +happyReduce_16 = happySpecReduce_1 8# happyReduction_16 +happyReduction_16 happy_x_1 + = case happyOut13 happy_x_1 of { happy_var_1 -> + happyIn12 + ([ happy_var_1 ] + )} + +happyReduce_17 = happySpecReduce_2 9# happyReduction_17 +happyReduction_17 happy_x_2 + happy_x_1 + = case happyOut19 happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + happyIn13 + (let (l,e,r) = happy_var_1 in + RECtx [] l e r happy_var_2 + )}} + +happyReduce_18 = happySpecReduce_2 10# happyReduction_18 +happyReduction_18 happy_x_2 + happy_x_1 + = case happyOut13 happy_x_1 of { happy_var_1 -> + case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn14 + (happy_var_1 : happy_var_2 + )}} + +happyReduce_19 = happySpecReduce_0 10# happyReduction_19 +happyReduction_19 = happyIn14 + ([] + ) + +happyReduce_20 = happySpecReduce_3 11# happyReduction_20 +happyReduction_20 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut16 happy_x_2 of { happy_var_2 -> + happyIn15 + (happy_var_2 + )} + +happyReduce_21 = happySpecReduce_3 12# happyReduction_21 +happyReduction_21 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut17 happy_x_1 of { happy_var_1 -> + case happyOut16 happy_x_3 of { happy_var_3 -> + happyIn16 + ((happy_var_1,0) : happy_var_3 + )}} + +happyReduce_22 = happySpecReduce_1 12# happyReduction_22 +happyReduction_22 happy_x_1 + = case happyOut17 happy_x_1 of { happy_var_1 -> + happyIn16 + ([(happy_var_1,0)] + )} + +happyReduce_23 = happySpecReduce_1 13# happyReduction_23 +happyReduction_23 happy_x_1 + = happyIn17 + ("0" + ) + +happyReduce_24 = happySpecReduce_1 13# happyReduction_24 +happyReduction_24 happy_x_1 + = case happyOutTok happy_x_1 of { (T _ (IdT happy_var_1)) -> + happyIn17 + (happy_var_1 + )} + +happyReduce_25 = happySpecReduce_1 14# happyReduction_25 +happyReduction_25 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn18 + (case happy_var_1 of T _ (CodeT code) -> Just code + )} + +happyReduce_26 = happySpecReduce_1 14# happyReduction_26 +happyReduction_26 happy_x_1 + = happyIn18 + (Nothing + ) + +happyReduce_27 = happySpecReduce_3 15# happyReduction_27 +happyReduction_27 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut20 happy_x_1 of { happy_var_1 -> + case happyOut22 happy_x_2 of { happy_var_2 -> + case happyOut21 happy_x_3 of { happy_var_3 -> + happyIn19 + ((Just happy_var_1,happy_var_2,happy_var_3) + )}}} + +happyReduce_28 = happySpecReduce_2 15# happyReduction_28 +happyReduction_28 happy_x_2 + happy_x_1 + = case happyOut22 happy_x_1 of { happy_var_1 -> + case happyOut21 happy_x_2 of { happy_var_2 -> + happyIn19 + ((Nothing,happy_var_1,happy_var_2) + )}} + +happyReduce_29 = happySpecReduce_1 16# happyReduction_29 +happyReduction_29 happy_x_1 + = happyIn20 + (charSetSingleton '\n' + ) + +happyReduce_30 = happySpecReduce_2 16# happyReduction_30 +happyReduction_30 happy_x_2 + happy_x_1 + = case happyOut27 happy_x_1 of { happy_var_1 -> + happyIn20 + (happy_var_1 + )} + +happyReduce_31 = happySpecReduce_1 17# happyReduction_31 +happyReduction_31 happy_x_1 + = happyIn21 + (RightContextRExp (Ch (charSetSingleton '\n')) + ) + +happyReduce_32 = happySpecReduce_2 17# happyReduction_32 +happyReduction_32 happy_x_2 + happy_x_1 + = case happyOut22 happy_x_2 of { happy_var_2 -> + happyIn21 + (RightContextRExp happy_var_2 + )} + +happyReduce_33 = happySpecReduce_2 17# happyReduction_33 +happyReduction_33 happy_x_2 + happy_x_1 + = case happyOutTok happy_x_2 of { happy_var_2 -> + happyIn21 + (RightContextCode (case happy_var_2 of + T _ (CodeT code) -> code) + )} + +happyReduce_34 = happySpecReduce_0 17# happyReduction_34 +happyReduction_34 = happyIn21 + (NoRightContext + ) + +happyReduce_35 = happySpecReduce_3 18# happyReduction_35 +happyReduction_35 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut23 happy_x_1 of { happy_var_1 -> + case happyOut22 happy_x_3 of { happy_var_3 -> + happyIn22 + (happy_var_1 :| happy_var_3 + )}} + +happyReduce_36 = happySpecReduce_1 18# happyReduction_36 +happyReduction_36 happy_x_1 + = case happyOut23 happy_x_1 of { happy_var_1 -> + happyIn22 + (happy_var_1 + )} + +happyReduce_37 = happySpecReduce_2 19# happyReduction_37 +happyReduction_37 happy_x_2 + happy_x_1 + = case happyOut23 happy_x_1 of { happy_var_1 -> + case happyOut24 happy_x_2 of { happy_var_2 -> + happyIn23 + (happy_var_1 :%% happy_var_2 + )}} + +happyReduce_38 = happySpecReduce_1 19# happyReduction_38 +happyReduction_38 happy_x_1 + = case happyOut24 happy_x_1 of { happy_var_1 -> + happyIn23 + (happy_var_1 + )} + +happyReduce_39 = happySpecReduce_2 20# happyReduction_39 +happyReduction_39 happy_x_2 + happy_x_1 + = case happyOut26 happy_x_1 of { happy_var_1 -> + case happyOut25 happy_x_2 of { happy_var_2 -> + happyIn24 + (happy_var_2 happy_var_1 + )}} + +happyReduce_40 = happySpecReduce_1 20# happyReduction_40 +happyReduction_40 happy_x_1 + = case happyOut26 happy_x_1 of { happy_var_1 -> + happyIn24 + (happy_var_1 + )} + +happyReduce_41 = happySpecReduce_1 21# happyReduction_41 +happyReduction_41 happy_x_1 + = happyIn25 + (Star + ) + +happyReduce_42 = happySpecReduce_1 21# happyReduction_42 +happyReduction_42 happy_x_1 + = happyIn25 + (Plus + ) + +happyReduce_43 = happySpecReduce_1 21# happyReduction_43 +happyReduction_43 happy_x_1 + = happyIn25 + (Ques + ) + +happyReduce_44 = happySpecReduce_3 21# happyReduction_44 +happyReduction_44 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOutTok happy_x_2 of { (T _ (CharT happy_var_2)) -> + happyIn25 + (repeat_rng (digit happy_var_2) Nothing + )} + +happyReduce_45 = happyReduce 4# 21# happyReduction_45 +happyReduction_45 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_2 of { (T _ (CharT happy_var_2)) -> + happyIn25 + (repeat_rng (digit happy_var_2) (Just Nothing) + ) `HappyStk` happyRest} + +happyReduce_46 = happyReduce 5# 21# happyReduction_46 +happyReduction_46 (happy_x_5 `HappyStk` + happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) + = case happyOutTok happy_x_2 of { (T _ (CharT happy_var_2)) -> + case happyOutTok happy_x_4 of { (T _ (CharT happy_var_4)) -> + happyIn25 + (repeat_rng (digit happy_var_2) (Just (Just (digit happy_var_4))) + ) `HappyStk` happyRest}} + +happyReduce_47 = happySpecReduce_2 22# happyReduction_47 +happyReduction_47 happy_x_2 + happy_x_1 + = happyIn26 + (Eps + ) + +happyReduce_48 = happySpecReduce_1 22# happyReduction_48 +happyReduction_48 happy_x_1 + = case happyOutTok happy_x_1 of { (T _ (StringT happy_var_1)) -> + happyIn26 + (foldr (:%%) Eps + (map (Ch . charSetSingleton) happy_var_1) + )} + +happyReduce_49 = happyMonadReduce 1# 22# happyReduction_49 +happyReduction_49 (happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOutTok happy_x_1 of { (T _ (RMacT happy_var_1)) -> + ( lookupRMac happy_var_1)} + ) (\r -> happyReturn (happyIn26 r)) + +happyReduce_50 = happySpecReduce_1 22# happyReduction_50 +happyReduction_50 happy_x_1 + = case happyOut27 happy_x_1 of { happy_var_1 -> + happyIn26 + (Ch happy_var_1 + )} + +happyReduce_51 = happySpecReduce_3 22# happyReduction_51 +happyReduction_51 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut22 happy_x_2 of { happy_var_2 -> + happyIn26 + (happy_var_2 + )} + +happyReduce_52 = happySpecReduce_3 23# happyReduction_52 +happyReduction_52 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut27 happy_x_1 of { happy_var_1 -> + case happyOut28 happy_x_3 of { happy_var_3 -> + happyIn27 + (happy_var_1 `charSetMinus` happy_var_3 + )}} + +happyReduce_53 = happySpecReduce_1 23# happyReduction_53 +happyReduction_53 happy_x_1 + = case happyOut28 happy_x_1 of { happy_var_1 -> + happyIn27 + (happy_var_1 + )} + +happyReduce_54 = happySpecReduce_1 24# happyReduction_54 +happyReduction_54 happy_x_1 + = case happyOutTok happy_x_1 of { (T _ (CharT happy_var_1)) -> + happyIn28 + (charSetSingleton happy_var_1 + )} + +happyReduce_55 = happySpecReduce_3 24# happyReduction_55 +happyReduction_55 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOutTok happy_x_1 of { (T _ (CharT happy_var_1)) -> + case happyOutTok happy_x_3 of { (T _ (CharT happy_var_3)) -> + happyIn28 + (charSetRange happy_var_1 happy_var_3 + )}} + +happyReduce_56 = happyMonadReduce 1# 24# happyReduction_56 +happyReduction_56 (happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOut30 happy_x_1 of { happy_var_1 -> + ( lookupSMac happy_var_1)} + ) (\r -> happyReturn (happyIn28 r)) + +happyReduce_57 = happySpecReduce_3 24# happyReduction_57 +happyReduction_57 happy_x_3 + happy_x_2 + happy_x_1 + = case happyOut29 happy_x_2 of { happy_var_2 -> + happyIn28 + (foldr charSetUnion emptyCharSet happy_var_2 + )} + +happyReduce_58 = happyMonadReduce 4# 24# happyReduction_58 +happyReduction_58 (happy_x_4 `HappyStk` + happy_x_3 `HappyStk` + happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut29 happy_x_3 of { happy_var_3 -> + ( do { dot <- lookupSMac (tokPosn happy_var_1, "."); + return (dot `charSetMinus` + foldr charSetUnion emptyCharSet happy_var_3) })}} + ) (\r -> happyReturn (happyIn28 r)) + +happyReduce_59 = happyMonadReduce 2# 24# happyReduction_59 +happyReduction_59 (happy_x_2 `HappyStk` + happy_x_1 `HappyStk` + happyRest) tk + = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> + case happyOut28 happy_x_2 of { happy_var_2 -> + ( do { dot <- lookupSMac (tokPosn happy_var_1, "."); + return (dot `charSetMinus` happy_var_2) })}} + ) (\r -> happyReturn (happyIn28 r)) + +happyReduce_60 = happySpecReduce_2 25# happyReduction_60 +happyReduction_60 happy_x_2 + happy_x_1 + = case happyOut27 happy_x_1 of { happy_var_1 -> + case happyOut29 happy_x_2 of { happy_var_2 -> + happyIn29 + (happy_var_1 : happy_var_2 + )}} + +happyReduce_61 = happySpecReduce_0 25# happyReduction_61 +happyReduction_61 = happyIn29 + ([] + ) + +happyReduce_62 = happySpecReduce_1 26# happyReduction_62 +happyReduction_62 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + ((tokPosn happy_var_1, ".") + )} + +happyReduce_63 = happySpecReduce_1 26# happyReduction_63 +happyReduction_63 happy_x_1 + = case happyOutTok happy_x_1 of { happy_var_1 -> + happyIn30 + (case happy_var_1 of T p (SMacT s) -> (p, s) + )} + +happyNewToken action sts stk + = lexer(\tk -> + let cont i = happyDoAction i tk action sts stk in + case tk of { + T _ EOFT -> happyDoAction 33# tk action sts stk; + T _ (SpecialT '.') -> cont 1#; + T _ (SpecialT ';') -> cont 2#; + T _ (SpecialT '<') -> cont 3#; + T _ (SpecialT '>') -> cont 4#; + T _ (SpecialT ',') -> cont 5#; + T _ (SpecialT '$') -> cont 6#; + T _ (SpecialT '|') -> cont 7#; + T _ (SpecialT '*') -> cont 8#; + T _ (SpecialT '+') -> cont 9#; + T _ (SpecialT '?') -> cont 10#; + T _ (SpecialT '{') -> cont 11#; + T _ (SpecialT '}') -> cont 12#; + T _ (SpecialT '(') -> cont 13#; + T _ (SpecialT ')') -> cont 14#; + T _ (SpecialT '#') -> cont 15#; + T _ (SpecialT '~') -> cont 16#; + T _ (SpecialT '-') -> cont 17#; + T _ (SpecialT '[') -> cont 18#; + T _ (SpecialT ']') -> cont 19#; + T _ (SpecialT '^') -> cont 20#; + T _ (SpecialT '/') -> cont 21#; + T _ ZeroT -> cont 22#; + T _ (StringT happy_dollar_dollar) -> cont 23#; + T _ (BindT happy_dollar_dollar) -> cont 24#; + T _ (IdT happy_dollar_dollar) -> cont 25#; + T _ (CodeT _) -> cont 26#; + T _ (CharT happy_dollar_dollar) -> cont 27#; + T _ (SMacT _) -> cont 28#; + T _ (RMacT happy_dollar_dollar) -> cont 29#; + T _ (SMacDefT happy_dollar_dollar) -> cont 30#; + T _ (RMacDefT happy_dollar_dollar) -> cont 31#; + T _ WrapperT -> cont 32#; + _ -> happyError' tk + }) + +happyError_ tk = happyError' tk + +happyThen :: () => P a -> (a -> P b) -> P b +happyThen = ((>>=)) +happyReturn :: () => a -> P a +happyReturn = (return) +happyThen1 = happyThen +happyReturn1 :: () => a -> P a +happyReturn1 = happyReturn +happyError' :: () => (Token) -> P a +happyError' tk = (\token -> happyError) tk + +parse = happySomeParser where + happySomeParser = happyThen (happyParse 0#) (\x -> happyReturn (happyOut4 x)) + +happySeq = happyDontSeq + + +happyError :: P a +happyError = failP "parse error" + +-- ----------------------------------------------------------------------------- +-- Utils + +digit c = ord c - ord '0' + +repeat_rng :: Int -> Maybe (Maybe Int) -> (RExp->RExp) +repeat_rng n (Nothing) re = foldr (:%%) Eps (replicate n re) +repeat_rng n (Just Nothing) re = foldr (:%%) (Star re) (replicate n re) +repeat_rng n (Just (Just m)) re = intl :%% rst + where + intl = repeat_rng n Nothing re + rst = foldr (\re re'->Ques(re :%% re')) Eps (replicate (m-n) re) + +replaceCodes codes rectx = rectx{ reCtxStartCodes = codes } +{-# LINE 1 "templates\GenericTemplate.hs" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +{-# LINE 1 "<built-in>" #-} +{-# LINE 1 "<command line>" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp + +{-# LINE 30 "templates\\GenericTemplate.hs" #-} + + +data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList + + + + + +{-# LINE 51 "templates\\GenericTemplate.hs" #-} + +{-# LINE 61 "templates\\GenericTemplate.hs" #-} + +{-# LINE 70 "templates\\GenericTemplate.hs" #-} + +infixr 9 `HappyStk` +data HappyStk a = HappyStk a (HappyStk a) + +----------------------------------------------------------------------------- +-- starting the parse + +happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll + +----------------------------------------------------------------------------- +-- Accepting the parse + +-- If the current token is 0#, it means we've just accepted a partial +-- parse (a %partial parser). We must ignore the saved token on the top of +-- the stack in this case. +happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) = + happyReturn1 ans +happyAccept j tk st sts (HappyStk ans _) = + (happyTcHack j (happyTcHack st)) (happyReturn1 ans) + +----------------------------------------------------------------------------- +-- Arrays only: do the next action + + + +happyDoAction i tk st + = {- nothing -} + + + case action of + 0# -> {- nothing -} + happyFail i tk st + -1# -> {- nothing -} + happyAccept i tk st + n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#)) -> {- nothing -} + + (happyReduceArr Happy_Data_Array.! rule) i tk st + where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#)))))) + n -> {- nothing -} + + + happyShift new_state i tk st + where !(new_state) = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) + where !(off) = indexShortOffAddr happyActOffsets st + !(off_i) = (off Happy_GHC_Exts.+# i) + check = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#)) + then (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i) + else False + !(action) + | check = indexShortOffAddr happyTable off_i + | otherwise = indexShortOffAddr happyDefActions st + +{-# LINE 130 "templates\\GenericTemplate.hs" #-} + + +indexShortOffAddr (HappyA# arr) off = + Happy_GHC_Exts.narrow16Int# i + where + !i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low) + !high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#))) + !low = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off')) + !off' = off Happy_GHC_Exts.*# 2# + + + + + +data HappyAddr = HappyA# Happy_GHC_Exts.Addr# + + + + +----------------------------------------------------------------------------- +-- HappyState data type (not arrays) + +{-# LINE 163 "templates\\GenericTemplate.hs" #-} + +----------------------------------------------------------------------------- +-- Shifting a token + +happyShift new_state 0# tk st sts stk@(x `HappyStk` _) = + let !(i) = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in +-- trace "shifting the error token" $ + happyDoAction i tk new_state (HappyCons (st) (sts)) (stk) + +happyShift new_state i tk st sts stk = + happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk) + +-- happyReduce is specialised for the common cases. + +happySpecReduce_0 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_0 nt fn j tk st@((action)) sts stk + = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk) + +happySpecReduce_1 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk') + = let r = fn v1 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happySpecReduce_2 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk') + = let r = fn v1 v2 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happySpecReduce_3 i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk') + = let r = fn v1 v2 v3 in + happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) + +happyReduce k i fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyReduce k nt fn j tk st sts stk + = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of + sts1@((HappyCons (st1@(action)) (_))) -> + let r = fn stk in -- it doesn't hurt to always seq here... + happyDoSeq r (happyGoto nt j tk st1 sts1 r) + +happyMonadReduce k nt fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyMonadReduce k nt fn j tk st sts stk = + happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk)) + where !(sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts)) + drop_stk = happyDropStk k stk + +happyMonad2Reduce k nt fn 0# tk st sts stk + = happyFail 0# tk st sts stk +happyMonad2Reduce k nt fn j tk st sts stk = + happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk)) + where !(sts1@((HappyCons (st1@(action)) (_)))) = happyDrop k (HappyCons (st) (sts)) + drop_stk = happyDropStk k stk + + !(off) = indexShortOffAddr happyGotoOffsets st1 + !(off_i) = (off Happy_GHC_Exts.+# nt) + !(new_state) = indexShortOffAddr happyTable off_i + + + + +happyDrop 0# l = l +happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t + +happyDropStk 0# l = l +happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs + +----------------------------------------------------------------------------- +-- Moving to a new state after a reduction + + +happyGoto nt j tk st = + {- nothing -} + happyDoAction j tk new_state + where !(off) = indexShortOffAddr happyGotoOffsets st + !(off_i) = (off Happy_GHC_Exts.+# nt) + !(new_state) = indexShortOffAddr happyTable off_i + + + + +----------------------------------------------------------------------------- +-- Error recovery (0# is the error token) + +-- parse error if we are in recovery and we fail again +happyFail 0# tk old_st _ stk = +-- trace "failing" $ + happyError_ tk + +{- We don't need state discarding for our restricted implementation of + "error". In fact, it can cause some bogus parses, so I've disabled it + for now --SDM + +-- discard a state +happyFail 0# tk old_st (HappyCons ((action)) (sts)) + (saved_tok `HappyStk` _ `HappyStk` stk) = +-- trace ("discarding state, depth " ++ show (length stk)) $ + happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk)) +-} + +-- Enter error recovery: generate an error token, +-- save the old token and carry on. +happyFail i tk (action) sts stk = +-- trace "entering error recovery" $ + happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk) + +-- Internal happy errors: + +notHappyAtAll = error "Internal Happy error\n" + +----------------------------------------------------------------------------- +-- Hack to get the typechecker to accept our action functions + + +happyTcHack :: Happy_GHC_Exts.Int# -> a -> a +happyTcHack x y = y +{-# INLINE happyTcHack #-} + + +----------------------------------------------------------------------------- +-- Seq-ing. If the --strict flag is given, then Happy emits +-- happySeq = happyDoSeq +-- otherwise it emits +-- happySeq = happyDontSeq + +happyDoSeq, happyDontSeq :: a -> b -> b +happyDoSeq a b = a `seq` b +happyDontSeq a b = b + +----------------------------------------------------------------------------- +-- Don't inline any functions from the template. GHC has a nasty habit +-- of deciding to inline happyGoto everywhere, which increases the size of +-- the generated parser quite a bit. + + +{-# NOINLINE happyDoAction #-} +{-# NOINLINE happyTable #-} +{-# NOINLINE happyCheck #-} +{-# NOINLINE happyActOffsets #-} +{-# NOINLINE happyGotoOffsets #-} +{-# NOINLINE happyDefActions #-} + +{-# NOINLINE happyShift #-} +{-# NOINLINE happySpecReduce_0 #-} +{-# NOINLINE happySpecReduce_1 #-} +{-# NOINLINE happySpecReduce_2 #-} +{-# NOINLINE happySpecReduce_3 #-} +{-# NOINLINE happyReduce #-} +{-# NOINLINE happyMonadReduce #-} +{-# NOINLINE happyGoto #-} +{-# NOINLINE happyFail #-} + +-- end of Happy Template.
+ dist/build/Scan.hs view
@@ -0,0 +1,407 @@+{-# OPTIONS -fglasgow-exts -cpp #-} +{-# LINE 13 "src\Scan.x" #-} + +{-# OPTIONS_GHC -w #-} + +module Scan(lexer, AlexPosn(..), Token(..), Tkn(..), tokPosn) where + +import Data.Char +import ParseMonad +--import Debug.Trace + +#if __GLASGOW_HASKELL__ >= 603 +#include "ghcconfig.h" +#elif defined(__GLASGOW_HASKELL__) +#include "config.h" +#endif +#if __GLASGOW_HASKELL__ >= 503 +import Data.Array +import Data.Char (ord) +import Data.Array.Base (unsafeAt) +#else +import Array +import Char (ord) +#endif +#if __GLASGOW_HASKELL__ >= 503 +import GHC.Exts +#else +import GlaExts +#endif +alex_base :: AlexAddr +alex_base = AlexA# "\xf8\xff\xff\xff\x6e\x00\x00\x00\x89\x00\x00\x00\x77\x00\x00\x00\xfc\xff\xff\xff\xfd\xff\xff\xff\xdb\xff\xff\xff\xdc\xff\xff\xff\x00\x00\x00\x00\x7b\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\xdd\xff\xff\xff\x73\x00\x00\x00\xde\xff\xff\xff\xfb\x00\x00\x00\x6d\x01\x00\x00\x00\x01\x00\x00\x74\x00\x00\x00\x75\x00\x00\x00\xdf\xff\xff\xff\x00\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x01\x00\x00\x00\x00\x00\x00\x96\xff\xff\xff\x9c\xff\xff\xff\xae\xff\xff\xff\xa0\xff\xff\xff\xa1\xff\xff\xff\xad\xff\xff\xff\xa2\xff\xff\xff\xde\x00\x00\x00\x4b\x01\x00\x00\x03\x02\x00\x00\x52\x02\x00\x00\x69\x02\x00\x00\x71\x00\x00\x00\x55\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x02\x00\x00\x02\x03\x00\x00\x74\x03\x00\x00\x83\x02\x00\x00\xc8\x03\x00\x00\x1c\x04\x00\x00\x59\x04\x00\x00\xcb\x04\x00\x00\x3d\x05\x00\x00\xaf\x05\x00\x00\xad\x05\x00\x00\x01\x06\x00\x00\x3e\x06\x00\x00\x00\x00\x00\x00\x87\x00\x00\x00\x8c\x01\x00\x00\xa7\x00\x00\x00\xa8\x00\x00\x00\xe6\xff\xff\xff\x00\x00\x00\x00\xa9\x00\x00\x00\x21\x03\x00\x00\xaa\x00\x00\x00\x19\x01\x00\x00\xe8\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x92\x06\x00\x00\xe6\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x02\x00\x00"# + +alex_table :: AlexAddr +alex_table = AlexA# "\x00\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\x04\x00\x04\x00\x0b\x00\x0b\x00\x13\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x3c\x00\x1b\x00\x42\x00\x00\x00\x00\x00\x03\x00\x2b\x00\x09\x00\x19\x00\x1a\x00\x1c\x00\x2b\x00\x2b\x00\x19\x00\x19\x00\x19\x00\x19\x00\x19\x00\x07\x00\x19\x00\x19\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x2b\x00\x0f\x00\x19\x00\x45\x00\x2b\x00\x2b\x00\x19\x00\x2c\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x19\x00\x25\x00\x19\x00\x19\x00\x2b\x00\x2b\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x10\x00\x16\x00\x19\x00\x19\x00\x19\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\xff\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x08\x00\x08\x00\x00\x00\x0c\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x03\x00\x00\x00\x00\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x49\x00\x06\x00\x00\x00\x00\x00\x46\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x3a\x00\x3a\x00\x40\x00\x40\x00\x00\x00\x4c\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x47\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x11\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x40\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x12\x00\x12\x00\x12\x00\x12\x00\x12\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x28\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x15\x00\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x39\x00\x00\x00\x00\x00\x11\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x32\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x24\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x29\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x27\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x00\x00\x00\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x3e\x00\x00\x00\x00\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\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\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x26\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x33\x00\x38\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\x00\x3e\x00\x00\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x41\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x3b\x00\x3b\x00\x3b\x00\x3b\x00\x3b\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\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x39\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x2e\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\x2f\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\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\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\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\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x00\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x34\x00\x41\x00\x41\x00\x41\x00\x41\x00\x41\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\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3f\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x37\x00\x00\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x37\x00\x00\x00\x00\x00\x35\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x36\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x00\x48\x00\x00\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\x00\x48\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\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\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"# + +alex_check :: AlexAddr +alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x0a\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x77\x00\x72\x00\x61\x00\x70\x00\x70\x00\x65\x00\x2d\x00\x72\x00\x2d\x00\xff\xff\xff\xff\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x0a\x00\x0a\x00\x0a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x0a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\x0a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x20\x00\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\x22\x00\x22\x00\xff\xff\x2d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x20\x00\xff\xff\xff\xff\x3a\x00\x3a\x00\x3a\x00\x3a\x00\xff\xff\x0a\x00\x0a\x00\x0a\x00\x0a\x00\x2c\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3d\x00\xff\xff\xff\xff\x3e\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\xff\xff\x7b\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\x27\x00\x0a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x3d\x00\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\x3d\x00\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x2d\x00\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\x20\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\x3d\x00\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\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\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x27\x00\xff\xff\x7d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\x7d\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\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\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\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\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\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\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3d\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x27\x00\xff\xff\x7d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\x7d\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\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\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\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\xff\xff"# + +alex_deflt :: AlexAddr +alex_deflt = AlexA# "\xff\xff\xff\xff\xff\xff\xff\xff\x05\x00\x05\x00\xff\xff\xff\xff\xff\xff\x0a\x00\x0a\x00\xff\xff\x14\x00\xff\xff\x14\x00\xff\xff\xff\xff\xff\xff\xff\xff\x14\x00\x14\x00\xff\xff\xff\xff\x18\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\x3d\x00\xff\xff\x3d\x00\x3d\x00\xff\xff\xff\xff\x43\x00\xff\xff\x43\x00\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4b\x00"# + +alex_accept = listArray (0::Int,76) [[],[(AlexAcc (alex_action_21))],[],[(AlexAcc (alex_action_0))],[(AlexAcc (alex_action_0))],[(AlexAcc (alex_action_0))],[],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_1))],[(AlexAcc (alex_action_10))],[],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_2))],[],[],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_10))],[],[],[],[],[],[(AlexAccPred (alex_action_3) (alexRightContext 23)),(AlexAcc (alex_action_4))],[],[(AlexAccSkip)],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_5))],[],[],[],[],[],[],[],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_7))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_11))],[],[],[],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_12))],[],[],[],[(AlexAcc (alex_action_13))],[(AlexAcc (alex_action_13))],[],[],[],[],[(AlexAcc (alex_action_14))],[(AlexAcc (alex_action_14))],[],[],[],[],[(AlexAcc (alex_action_15))],[(AlexAcc (alex_action_16))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_18))],[(AlexAcc (alex_action_19))],[(AlexAcc (alex_action_20))],[]] +{-# LINE 75 "src\Scan.x" #-} + + +-- ----------------------------------------------------------------------------- +-- Token type + +data Token = T AlexPosn Tkn + deriving Show + +tokPosn (T p _) = p + +data Tkn + = SpecialT Char + | CodeT String + | ZeroT + | IdT String + | StringT String + | BindT String + | CharT Char + | SMacT String + | RMacT String + | SMacDefT String + | RMacDefT String + | NumT Int + | WrapperT + | EOFT + deriving Show + +-- ----------------------------------------------------------------------------- +-- Token functions + +special (p,_,str) ln = return $ T p (SpecialT (head str)) +zero (p,_,str) ln = return $ T p ZeroT +string (p,_,str) ln = return $ T p (StringT (extract ln str)) +bind (p,_,str) ln = return $ T p (BindT (takeWhile isIdChar str)) +escape (p,_,str) ln = return $ T p (CharT (esc str)) +decch (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (tail str)))) +hexch (p,_,str) ln = return $ T p (CharT (do_ech 16 ln (take (ln-2) (drop 2 str)))) +octch (p,_,str) ln = return $ T p (CharT (do_ech 8 ln (take (ln-2) (drop 2 str)))) +char (p,_,str) ln = return $ T p (CharT (head str)) +smac (p,_,str) ln = return $ T p (SMacT (mac ln str)) +rmac (p,_,str) ln = return $ T p (RMacT (mac ln str)) +smacdef (p,_,str) ln = return $ T p (SMacDefT (macdef ln str)) +rmacdef (p,_,str) ln = return $ T p (RMacDefT (macdef ln str)) +startcode (p,_,str) ln = return $ T p (IdT (take ln str)) +wrapper (p,_,str) ln = return $ T p WrapperT + +isIdChar c = isAlphaNum c || c `elem` "_'" + +extract ln str = take (ln-2) (tail str) + +do_ech radix ln str = chr (parseInt radix str) + +mac ln (_ : str) = take (ln-1) str + +macdef ln (_ : str) = takeWhile (not.isSpace) str + +esc (_ : x : _) = + case x of + 'a' -> '\a' + 'b' -> '\b' + 'f' -> '\f' + 'n' -> '\n' + 'r' -> '\r' + 't' -> '\t' + 'v' -> '\v' + c -> c + +parseInt :: Int -> String -> Int +parseInt radix ds = foldl1 (\n d -> n * radix + d) (map digitToInt ds) + +-- In brace-delimited code, we have to be careful to match braces +-- within the code, but ignore braces inside strings and character +-- literals. We do an approximate job (doing it properly requires +-- implementing a large chunk of the Haskell lexical syntax). + +code (p,_,inp) len = do + inp <- getInput + go inp 1 "" + where + go inp 0 cs = do + setInput inp + return (T p (CodeT (reverse (tail cs)))) + go inp n cs = do + case alexGetChar inp of + Nothing -> err inp + Just (c,inp) -> + case c of + '{' -> go inp (n+1) (c:cs) + '}' -> go inp (n-1) (c:cs) + '\'' -> go_char inp n (c:cs) + '\"' -> go_str inp n (c:cs) '\"' + c -> go inp n (c:cs) + + -- try to catch occurrences of ' within an identifier + go_char inp n (c1:c2:cs) | isAlphaNum c2 = go inp n (c1:c2:cs) + go_char inp n cs = go_str inp n cs '\'' + + go_str inp n cs end = do + case alexGetChar inp of + Nothing -> err inp + Just (c,inp) + | c == end -> go inp n (c:cs) + | otherwise -> + case c of + '\\' -> case alexGetChar inp of + Nothing -> err inp + Just (d,inp) -> go_str inp n (d:c:cs) end + c -> go_str inp n (c:cs) end + + err inp = do setInput inp; lexError "lexical error in code fragment" + + + +lexError s = do + (p,_,input) <- getInput + failP (s ++ (if (not (null input)) + then " at " ++ show (head input) + else " at end of file")) + +lexer :: (Token -> P a) -> P a +lexer cont = lexToken >>= cont + +lexToken :: P Token +lexToken = do + inp@(p,_,_) <- getInput + sc <- getStartCode + case alexScan inp sc of + AlexEOF -> return (T p EOFT) + AlexError _ -> lexError "lexical error" + AlexSkip inp1 len -> do + setInput inp1 + lexToken + AlexToken inp1 len t -> do + setInput inp1 + t inp len + +type Action = AlexInput -> Int -> P Token + +skip :: Action +skip _ _ = lexToken + +andBegin :: Action -> StartCode -> Action +andBegin act sc inp len = setStartCode sc >> act inp len + + +afterstartcodes,startcodes :: Int +afterstartcodes = 1 +startcodes = 2 +alex_action_0 = skip +alex_action_1 = string +alex_action_2 = bind +alex_action_3 = code +alex_action_4 = special +alex_action_5 = wrapper +alex_action_6 = decch +alex_action_7 = hexch +alex_action_8 = octch +alex_action_9 = escape +alex_action_10 = char +alex_action_11 = smac +alex_action_12 = rmac +alex_action_13 = smacdef +alex_action_14 = rmacdef +alex_action_15 = special `andBegin` startcodes +alex_action_16 = zero +alex_action_17 = startcode +alex_action_18 = special +alex_action_19 = special `andBegin` afterstartcodes +alex_action_20 = special `andBegin` 0 +alex_action_21 = skip `andBegin` 0 +{-# LINE 1 "templates\GenericTemplate.hs" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +{-# LINE 1 "<built-in>" #-} +{-# LINE 1 "<command line>" #-} +{-# LINE 1 "templates\\GenericTemplate.hs" #-} +-- ----------------------------------------------------------------------------- +-- ALEX TEMPLATE +-- +-- This code is in the PUBLIC DOMAIN; you may copy it freely and use +-- it for any purpose whatsoever. + +-- ----------------------------------------------------------------------------- +-- INTERNALS and main scanner engine + +{-# LINE 37 "templates\\GenericTemplate.hs" #-} + +{-# LINE 47 "templates\\GenericTemplate.hs" #-} + + +data AlexAddr = AlexA# Addr# + +#if __GLASGOW_HASKELL__ < 503 +uncheckedShiftL# = shiftL# +#endif + +{-# INLINE alexIndexInt16OffAddr #-} +alexIndexInt16OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN + narrow16Int# i + where + i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low) + high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) + low = int2Word# (ord# (indexCharOffAddr# arr off')) + off' = off *# 2# +#else + indexInt16OffAddr# arr off +#endif + + + + + +{-# INLINE alexIndexInt32OffAddr #-} +alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN + narrow32Int# i + where + i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#` + (b2 `uncheckedShiftL#` 16#) `or#` + (b1 `uncheckedShiftL#` 8#) `or#` b0) + b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#))) + b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#))) + b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) + b0 = int2Word# (ord# (indexCharOffAddr# arr off')) + off' = off *# 4# +#else + indexInt32OffAddr# arr off +#endif + + + + + +#if __GLASGOW_HASKELL__ < 503 +quickIndex arr i = arr ! i +#else +-- GHC >= 503, unsafeAt is available from Data.Array.Base. +quickIndex = unsafeAt +#endif + + + + +-- ----------------------------------------------------------------------------- +-- Main lexing routines + +data AlexReturn a + = AlexEOF + | AlexError !AlexInput + | AlexSkip !AlexInput !Int + | AlexToken !AlexInput !Int a + +-- alexScan :: AlexInput -> StartCode -> AlexReturn a +alexScan input (I# (sc)) + = alexScanUser undefined input (I# (sc)) + +alexScanUser user input (I# (sc)) + = case alex_scan_tkn user input 0# input sc AlexNone of + (AlexNone, input') -> + case alexGetChar input of + Nothing -> + + + + AlexEOF + Just _ -> + + + + AlexError input' + + (AlexLastSkip input'' len, _) -> + + + + AlexSkip input'' len + + (AlexLastAcc k input''' len, _) -> + + + + AlexToken input''' len k + + +-- Push the input through the DFA, remembering the most recent accepting +-- state it encountered. + +alex_scan_tkn user orig_input len input s last_acc = + input `seq` -- strict in the input + let + new_acc = check_accs (alex_accept `quickIndex` (I# (s))) + in + new_acc `seq` + case alexGetChar input of + Nothing -> (new_acc, input) + Just (c, new_input) -> + + + + let + !(base) = alexIndexInt32OffAddr alex_base s + !((I# (ord_c))) = ord c + !(offset) = (base +# ord_c) + !(check) = alexIndexInt16OffAddr alex_check offset + + !(new_s) = if (offset >=# 0#) && (check ==# ord_c) + then alexIndexInt16OffAddr alex_table offset + else alexIndexInt16OffAddr alex_deflt s + in + case new_s of + -1# -> (new_acc, input) + -- on an error, we want to keep the input *before* the + -- character that failed, not after. + _ -> alex_scan_tkn user orig_input (len +# 1#) + new_input new_s new_acc + + where + check_accs [] = last_acc + check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len)) + check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len)) + check_accs (AlexAccPred a predx : rest) + | predx user orig_input (I# (len)) input + = AlexLastAcc a input (I# (len)) + check_accs (AlexAccSkipPred predx : rest) + | predx user orig_input (I# (len)) input + = AlexLastSkip input (I# (len)) + check_accs (_ : rest) = check_accs rest + +data AlexLastAcc a + = AlexNone + | AlexLastAcc a !AlexInput !Int + | AlexLastSkip !AlexInput !Int + +data AlexAcc a user + = AlexAcc a + | AlexAccSkip + | AlexAccPred a (AlexAccPred user) + | AlexAccSkipPred (AlexAccPred user) + +type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool + +-- ----------------------------------------------------------------------------- +-- Predicates on a rule + +alexAndPred p1 p2 user in1 len in2 + = p1 user in1 len in2 && p2 user in1 len in2 + +--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input + +--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input + +--alexRightContext :: Int -> AlexAccPred _ +alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of + (AlexNone, _) -> False + _ -> True + -- TODO: there's no need to find the longest + -- match when checking the right context, just + -- the first match will do. + +-- used by wrappers +iUnbox (I# (i)) = i
+ src/AbsSyn.hs view
@@ -0,0 +1,271 @@+-- -----------------------------------------------------------------------------+-- +-- AbsSyn.hs, part of Alex+--+-- (c) Chris Dornan 1995-2000, Simon Marlow 2003+--+-- This module provides a concrete representation for regular expressions and+-- scanners. Scanners are used for tokenising files in preparation for parsing.+--+-- ----------------------------------------------------------------------------}++module AbsSyn (+ Code, Directive(..),+ Scanner(..),+ RECtx(..),+ RExp(..),+ DFA(..), State(..), SNum, StartCode, Accept(..),+ RightContext(..), showRCtx,+ encodeStartCodes, extractActions,+ Target(..)+ ) where++import CharSet ( CharSet )+import Map ( Map )+import qualified Map hiding ( Map )+import Sort ( nub' )+import Util ( str, nl )++import Data.Maybe ( fromJust )++infixl 4 :|+infixl 5 :%%++-- -----------------------------------------------------------------------------+-- Abstract Syntax for Alex scripts++type Code = String++data Directive+ = WrapperDirective String -- use this wrapper++-- TODO: update this comment+--+-- A `Scanner' consists of an association list associating token names with+-- regular expressions with context. The context may include a list of start+-- codes, some leading context to test the character immediately preceding the+-- token and trailing context to test the residual input after the token.+-- +-- The start codes consist of the names and numbers of the start codes;+-- initially the names only will be generated by the parser, the numbers being+-- allocated at a later stage. Start codes become meaningful when scanners are+-- converted to DFAs; see the DFA section of the Scan module for details.++data Scanner = Scanner { scannerName :: String,+ scannerTokens :: [RECtx] }+ deriving Show++data RECtx = RECtx { reCtxStartCodes :: [(String,StartCode)],+ reCtxPreCtx :: Maybe CharSet,+ reCtxRE :: RExp,+ reCtxPostCtx :: RightContext RExp,+ reCtxCode :: Maybe Code+ }++data RightContext r+ = NoRightContext + | RightContextRExp r+ | RightContextCode Code++instance Show RECtx where+ showsPrec _ (RECtx scs _ r rctx code) = + showStarts scs . shows r . showRCtx rctx . showMaybeCode code++showMaybeCode :: Maybe String -> String -> String+showMaybeCode Nothing = id+showMaybeCode (Just code) = showCode code++showCode :: String -> String -> String+showCode code = showString " { " . showString code . showString " }"++showStarts :: [(String, StartCode)] -> String -> String+showStarts [] = id+showStarts scs = shows scs++showRCtx :: Show r => RightContext r -> String -> String+showRCtx NoRightContext = id+showRCtx (RightContextRExp r) = ('\\':) . shows r+showRCtx (RightContextCode code) = showString "\\ " . showCode code++-- -----------------------------------------------------------------------------+-- DFAs++data DFA s a = DFA+ { dfa_start_states :: [s],+ dfa_states :: Map s (State s a)+ }++data State s a = State [Accept a] (Map Char s)++type SNum = Int++data Accept a+ = Acc { accPrio :: Int,+ accAction :: Maybe a,+ accLeftCtx :: Maybe CharSet,+ accRightCtx :: RightContext SNum+ }++-- debug stuff+instance Show (Accept a) where+ showsPrec _ (Acc p _act _lctx _rctx) = shows p --TODO++type StartCode = Int++-- -----------------------------------------------------------------------------+-- Regular expressions++-- `RExp' provides an abstract syntax for regular expressions. `Eps' will+-- match empty strings; `Ch p' matches strings containinng a single character+-- `c' if `p c' is true; `re1 :%% re2' matches a string if `re1' matches one of+-- its prefixes and `re2' matches the rest; `re1 :| re2' matches a string if+-- `re1' or `re2' matches it; `Star re', `Plus re' and `Ques re' can be+-- expressed in terms of the other operators. See the definitions of `ARexp'+-- for a formal definition of the semantics of these operators.++data RExp + = Eps+ | Ch CharSet+ | RExp :%% RExp+ | RExp :| RExp+ | Star RExp+ | Plus RExp+ | Ques RExp ++instance Show RExp where+ showsPrec _ Eps = showString "()"+ showsPrec _ (Ch _) = showString "[..]"+ showsPrec _ (l :%% r) = shows l . shows r+ showsPrec _ (l :| r) = shows l . ('|':) . shows r+ showsPrec _ (Star r) = shows r . ('*':)+ showsPrec _ (Plus r) = shows r . ('+':)+ showsPrec _ (Ques r) = shows r . ('?':)++{------------------------------------------------------------------------------+ Abstract Regular Expression+------------------------------------------------------------------------------}+++-- This section contains demonstrations; it is not part of Alex.++{-+-- This function illustrates `ARexp'. It returns true if the string in its+-- argument is matched by the regular expression.++recognise:: RExp -> String -> Bool+recognise re inp = any (==len) (ap_ar (arexp re) inp)+ where+ len = length inp+++-- `ARexp' provides an regular expressions in abstract format. Here regular+-- expressions are represented by a function that takes the string to be+-- matched and returns the sizes of all the prefixes matched by the regular+-- expression (the list may contain duplicates). Each of the `RExp' operators+-- are represented by similarly named functions over ARexp. The `ap' function+-- takes an `ARExp', a string and returns the sizes of all the prefixes+-- matching that regular expression. `arexp' converts an `RExp' to an `ARexp'.+++arexp:: RExp -> ARexp+arexp Eps = eps_ar+arexp (Ch p) = ch_ar p+arexp (re :%% re') = arexp re `seq_ar` arexp re'+arexp (re :| re') = arexp re `bar_ar` arexp re'+arexp (Star re) = star_ar (arexp re)+arexp (Plus re) = plus_ar (arexp re)+arexp (Ques re) = ques_ar (arexp re)+++star_ar:: ARexp -> ARexp+star_ar sc = eps_ar `bar_ar` plus_ar sc++plus_ar:: ARexp -> ARexp+plus_ar sc = sc `seq_ar` star_ar sc++ques_ar:: ARexp -> ARexp+ques_ar sc = eps_ar `bar_ar` sc+++-- Hugs abstract type definition -- not for GHC.++type ARexp = String -> [Int]+-- in ap_ar, eps_ar, ch_ar, seq_ar, bar_ar++ap_ar:: ARexp -> String -> [Int]+ap_ar sc = sc++eps_ar:: ARexp+eps_ar inp = [0]++ch_ar:: (Char->Bool) -> ARexp+ch_ar p "" = []+ch_ar p (c:rst) = if p c then [1] else []++seq_ar:: ARexp -> ARexp -> ARexp+seq_ar sc sc' inp = [n+m| n<-sc inp, m<-sc' (drop n inp)]++bar_ar:: ARexp -> ARexp -> ARexp +bar_ar sc sc' inp = sc inp ++ sc' inp+-}++-- -----------------------------------------------------------------------------+-- Utils++-- Map the available start codes onto [1..]++encodeStartCodes:: Scanner -> (Scanner,[StartCode],ShowS)+encodeStartCodes scan = (scan', 0 : map snd name_code_pairs, sc_hdr)+ where+ scan' = scan{ scannerTokens = map mk_re_ctx (scannerTokens scan) }++ mk_re_ctx (RECtx scs lc re rc code)+ = RECtx (map mk_sc scs) lc re rc code++ mk_sc (nm,_) = (nm, if nm=="0" then 0 + else fromJust (Map.lookup nm code_map))++ sc_hdr tl =+ case name_code_pairs of+ [] -> tl+ (nm,_):rst -> "\n" ++ nm ++ foldr f t rst+ where+ f (nm', _) t' = "," ++ nm' ++ t'+ t = " :: Int\n" ++ foldr fmt_sc tl name_code_pairs+ where+ fmt_sc (nm,sc) t = nm ++ " = " ++ show sc ++ "\n" ++ t++ code_map = Map.fromList name_code_pairs++ name_code_pairs = zip (nub' (<=) nms) [1..]++ nms = [nm | RECtx{reCtxStartCodes = scs} <- scannerTokens scan,+ (nm,_) <- scs, nm /= "0"]+++-- Grab the code fragments for the token actions, and replace them+-- with function names of the form alex_action_$n$. We do this+-- because the actual action fragments might be duplicated in the+-- generated file.++extractActions :: Scanner -> (Scanner,ShowS)+extractActions scanner = (scanner{scannerTokens = new_tokens}, decl_str)+ where+ (new_tokens, decls) = unzip (zipWith f (scannerTokens scanner) act_names)++ f r@RECtx{ reCtxCode = Just code } name+ = (r{reCtxCode = Just name}, Just (mkDecl name code))+ f r@RECtx{ reCtxCode = Nothing } _+ = (r{reCtxCode = Nothing}, Nothing)++ mkDecl fun code = str fun . str " = " . str code . nl++ act_names = map (\n -> "alex_action_" ++ show (n::Int)) [0..]++ decl_str = foldr (.) id [ decl | Just decl <- decls ]++-- -----------------------------------------------------------------------------+-- Code generation targets++data Target = GhcTarget | HaskellTarget+
+ src/CharSet.hs view
@@ -0,0 +1,57 @@+-- -----------------------------------------------------------------------------+-- +-- CharSet.hs, part of Alex+--+-- (c) Chris Dornan 1995-2000, Simon Marlow 2003+--+-- An abstract CharSet type for Alex. To begin with we'll use Alex's+-- original definition of sets as functions, then later will+-- transition to something that will work better with Unicode.+--+-- ----------------------------------------------------------------------------}++module CharSet (+ CharSet, -- abstract+ emptyCharSet,+ charSetSingleton,+ charSet,+ charSetMinus,+ charSetComplement,+ charSetRange,+ charSetUnion,+ charSetToArray,+ charSetElems+ ) where++import Data.Array ( Array, array )++-- Implementation as functions+type CharSet = Char -> Bool++emptyCharSet :: CharSet+emptyCharSet = const False++charSetSingleton :: Char -> CharSet+charSetSingleton c = \x -> x == c++charSet :: [Char] -> CharSet+charSet s x = x `elem` s++charSetMinus :: CharSet -> CharSet -> CharSet+charSetMinus s1 s2 x = s1 x && not (s2 x)++charSetUnion :: CharSet -> CharSet -> CharSet+charSetUnion s1 s2 x = s1 x || s2 x++charSetComplement :: CharSet -> CharSet+charSetComplement s1 = not . s1++charSetRange :: Char -> Char -> CharSet+charSetRange c1 c2 x = x >= c1 && x <= c2++charSetToArray :: CharSet -> Array Char Bool+charSetToArray set = array (fst (head ass), fst (last ass)) ass+ where ass = [(c,set c) | c <- ['\0'..'\xff']]++charSetElems :: CharSet -> [Char]+charSetElems set = [c | c <- ['\0'..'\xff'], set c]
+ src/DFA.hs view
@@ -0,0 +1,250 @@+-- -----------------------------------------------------------------------------+-- +-- DFA.hs, part of Alex+--+-- (c) Chris Dornan 1995-2000, Simon Marlow 2003+--+-- This module generates a DFA from a scanner by first converting it+-- to an NFA and then converting the NFA with the subset construction.+-- +-- See the chapter on `Finite Automata and Lexical Analysis' in the+-- dragon book for an excellent overview of the algorithms in this+-- module.+--+-- ----------------------------------------------------------------------------}++module DFA(scanner2dfa) where++import AbsSyn+import qualified Map+import NFA+import Sort ( msort, nub' )+import CharSet++import Data.Array ( (!) )+import Data.Maybe ( fromJust )++{- Defined in the Scan Module++-- (This section should logically belong to the DFA module but it has been+-- placed here to make this module self-contained.)+-- +-- `DFA' provides an alternative to `Scanner' (described in the RExp module);+-- it can be used directly to scan text efficiently. Additionally it has an+-- extra place holder for holding action functions for generating+-- application-specific tokens. When this place holder is not being used, the+-- unit type will be used.+-- +-- Each state in the automaton consist of a list of `Accept' values, descending+-- in priority, and an array mapping characters to new states. As the array+-- may only cover a sub-range of the characters, a default state number is+-- given in the third field. By convention, all transitions to the -1 state+-- represent invalid transitions.+-- +-- A list of accept states is provided for as the original specification may+-- have been ambiguous, in which case the highest priority token should be+-- taken (the one appearing earliest in the specification); this can not be+-- calculated when the DFA is generated in all cases as some of the tokens may+-- be associated with leading or trailing context or start codes.+-- +-- `scan_token' (see above) can deal with unconditional accept states more+-- efficiently than those associated with context; to save it testing each time+-- whether the list of accept states contains an unconditional state, the flag+-- in the first field of `St' is set to true whenever the list contains an+-- unconditional state.+-- +-- The `Accept' structure contains the priority of the token being accepted+-- (lower numbers => higher priorities), the name of the token, a place holder+-- that can be used for storing the `action' function for constructing the+-- token from the input text and thge scanner's state, a list of start codes+-- (listing the start codes that the scanner must be in for the token to be+-- accepted; empty => no restriction), the leading and trailing context (both+-- `Nothing' if there is none).+-- +-- The leading context consists simply of a character predicate that will+-- return true if the last character read is acceptable. The trailing context+-- consists of an alternative starting state within the DFA; if this `sub-dfa'+-- turns up any accepting state when applied to the residual input then the+-- trailing context is acceptable (see `scan_token' above).++type DFA a = Array SNum (State a)++type SNum = Int++data State a = St Bool [Accept a] SNum (Array Char SNum)++data Accept a = Acc Int String a [StartCode] (MB(Char->Bool)) (MB SNum)++type StartCode = Int+-}+++-- Scanners are converted to DFAs by converting them to NFAs first. Converting+-- an NFA to a DFA works by identifying the states of the DFA with subsets of+-- the NFA. The PartDFA is used to construct the DFA; it is essentially a DFA+-- in which the states are represented directly by state sets of the NFA.+-- `nfa2pdfa' constructs the partial DFA from the NFA by searching for all the+-- transitions from a given list of state sets, initially containing the start+-- state of the partial DFA, until all possible state sets have been considered+-- The final DFA is then constructed with a `mk_dfa'.++scanner2dfa:: Scanner -> [StartCode] -> DFA SNum Code+scanner2dfa scanner scs = nfa2dfa scs (scanner2nfa scanner scs)++nfa2dfa:: [StartCode] -> NFA -> DFA SNum Code+nfa2dfa scs nfa = mk_int_dfa nfa (nfa2pdfa nfa pdfa (dfa_start_states pdfa))+ where+ pdfa = new_pdfa n_starts nfa+ n_starts = length scs -- number of start states++-- `nfa2pdfa' works by taking the next outstanding state set to be considered+-- and and ignoring it if the state is already in the partial DFA, otherwise+-- generating all possible transitions from it, adding the new state to the+-- partial DFA and continuing the closure with the extra states. Note the way+-- it incorporates the trailing context references into the search (by+-- including `rctx_ss' in the search).++nfa2pdfa:: NFA -> DFA StateSet Code -> [StateSet] -> DFA StateSet Code+nfa2pdfa _ pdfa [] = pdfa+nfa2pdfa nfa pdfa (ss:umkd)+ | ss `in_pdfa` pdfa = nfa2pdfa nfa pdfa umkd+ | otherwise = nfa2pdfa nfa pdfa' umkd'+ where+ pdfa' = add_pdfa ss (State accs (Map.fromList ss_outs)) pdfa++ umkd' = rctx_sss ++ map snd ss_outs ++ umkd++ -- for each character, the set of states that character would take+ -- us to from the current set of states in the NFA.+ ss_outs :: [(Char, StateSet)]+ ss_outs = [ (ch, mk_ss nfa ss')+ | ch <- dfa_alphabet,+ let ss' = [ s' | (p,s') <- outs, p ch ],+ not (null ss')+ ]++ rctx_sss = [ mk_ss nfa [s]+ | Acc _ _ _ (RightContextRExp s) <- accs ]++ outs :: [(CharSet,SNum)]+ outs = [ out | s <- ss, out <- nst_outs (nfa!s) ]++ accs = sort_accs [acc| s<-ss, acc<-nst_accs (nfa!s)]++dfa_alphabet:: [Char]+dfa_alphabet = ['\0'..'\255']++-- `sort_accs' sorts a list of accept values into decending order of priority,+-- eliminating any elements that follow an unconditional accept value.++sort_accs:: [Accept a] -> [Accept a]+sort_accs accs = foldr chk [] (msort le accs)+ where+ chk acc@(Acc _ _ Nothing NoRightContext) _ = [acc]+ chk acc rst = acc:rst++ le (Acc{accPrio = n}) (Acc{accPrio=n'}) = n<=n'++++{------------------------------------------------------------------------------+ State Sets and Partial DFAs+------------------------------------------------------------------------------}++++-- A `PartDFA' is a partially constructed DFA in which the states are+-- represented by sets of states of the original NFA. It is represented by a+-- triple consisting of the start state of the partial DFA, the NFA from which+-- it is derived and a map from state sets to states of the partial DFA. The+-- state set for a given list of NFA states is calculated by taking the epsilon+-- closure of all the states, sorting the result with duplicates eliminated.++type StateSet = [SNum]++new_pdfa:: Int -> NFA -> DFA StateSet a+new_pdfa starts nfa+ = DFA { dfa_start_states = start_ss,+ dfa_states = Map.empty+ }+ where+ start_ss = [ msort (<=) (nst_cl(nfa!n)) | n <- [0..(starts-1)]]++ -- starts is the number of start states++-- constructs the epsilon-closure of a set of NFA states+mk_ss:: NFA -> [SNum] -> StateSet+mk_ss nfa l = nub' (<=) [s'| s<-l, s'<-nst_cl(nfa!s)]++add_pdfa:: StateSet -> State StateSet a -> DFA StateSet a -> DFA StateSet a+add_pdfa ss pst (DFA st mp) = DFA st (Map.insert ss pst mp)++in_pdfa:: StateSet -> DFA StateSet a -> Bool+in_pdfa ss (DFA _ mp) = ss `Map.member` mp++-- Construct a DFA with numbered states, from a DFA whose states are+-- sets of states from the original NFA.++mk_int_dfa:: NFA -> DFA StateSet a -> DFA SNum a+mk_int_dfa nfa (DFA start_states mp)+ = DFA [0 .. length start_states-1] + (Map.fromList [ (lookup' st, cnv pds) | (st, pds) <- Map.toAscList mp ])+ where+ mp' = Map.fromList (zip (start_states ++ + (map fst . Map.toAscList) (foldr Map.delete mp start_states)) [0..])++ lookup' = fromJust . flip Map.lookup mp'++ cnv :: State StateSet a -> State SNum a+ cnv (State accs as) = State accs' as'+ where+ as' = Map.mapWithKey (\_ch s -> lookup' s) as++ accs' = map cnv_acc accs+ cnv_acc (Acc p a lctx rctx) = Acc p a lctx rctx'+ where rctx' = + case rctx of+ RightContextRExp s -> + RightContextRExp (lookup' (mk_ss nfa [s]))+ other -> other++{-++-- `mk_st' constructs a state node from the list of accept values and a list of+-- transitions. The transitions list all the valid transitions out of the+-- node; all invalid transitions should be represented in the array by state+-- -1. `mk_st' has to work out whether the accept states contain an+-- unconditional entry, in which case the first field of `St' should be true,+-- and which default state to use in constructing the array (the array may span+-- a sub-range of the character set, the state number given the third argument+-- of `St' being taken as the default if an input character lies outside the+-- range). The default values is chosen to minimise the bounds of the array+-- and so there are two candidates: the value that 0 maps to (in which case+-- some initial segment of the array may be omitted) or the value that 255 maps+-- to (in which case a final segment of the array may be omitted), hence the+-- calculation of `(df,bds)'.+-- +-- Note that empty arrays are avoided as they can cause severe problems for+-- some popular Haskell compilers.++mk_st:: [Accept Code] -> [(Char,Int)] -> State Code+mk_st accs as =+ if null as+ then St accs (-1) (listArray ('0','0') [-1])+ else St accs df (listArray bds [arr!c| c<-range bds])+ where+ bds = if sz==0 then ('0','0') else bds0++ (sz,df,bds0) | sz1 < sz2 = (sz1,df1,bds1)+ | otherwise = (sz2,df2,bds2)++ (sz1,df1,bds1) = mk_bds(arr!chr 0)+ (sz2,df2,bds2) = mk_bds(arr!chr 255)++ mk_bds df = (t-b, df, (chr b, chr (255-t)))+ where+ b = length (takeWhile id [arr!c==df| c<-['\0'..'\xff']])+ t = length (takeWhile id [arr!c==df| c<-['\xff','\xfe'..'\0']])++ arr = listArray ('\0','\xff') (take 256 (repeat (-1))) // as+-}
+ src/DFS.hs view
@@ -0,0 +1,136 @@+{------------------------------------------------------------------------------+ DFS++This module is a portable version of the ghc-specific `DFS.g.hs', which is+itself a straightforward encoding of the Launchbury/King paper on linear graph+algorithms. This module uses balanced binary trees instead of mutable arrays+to implement the depth-first search so the complexity of the algorithms is+n.log(n) instead of linear.++The vertices of the graphs manipulated by these modules are labelled with the+integers from 0 to n-1 where n is the number of vertices in the graph.++The module's principle products are `mk_graph' for constructing a graph from an+edge list, `t_close' for taking the transitive closure of a graph and `scc'+for generating a list of strongly connected components; the components are+listed in dependency order and each component takes the form of a `dfs tree'+(see Launchberry and King). Thus if each edge (fid,fid') encodes the fact that+function `fid' references function `fid'' in a program then `scc' performs a+dependency analysis.++Chris Dornan, 23-Jun-94, 2-Jul-96, 29-Aug-96, 29-Sep-97+------------------------------------------------------------------------------}++module DFS where++import Set ( Set )+import qualified Set hiding ( Set )++import Data.Array ( (!), accumArray, listArray )++-- The result of a depth-first search of a graph is a list of trees,+-- `GForrest'. `post_order' provides a post-order traversal of a forrest.++type GForrest = [GTree]+data GTree = GNode Int GForrest++postorder:: GForrest -> [Int]+postorder ts = po ts []+ where+ po ts' l = foldr po_tree l ts'++ po_tree (GNode a ts') l = po ts' (a:l)++list_tree:: GTree -> [Int]+list_tree t = l_t t []+ where+ l_t (GNode x ts) l = foldr l_t (x:l) ts+++-- Graphs are represented by a pair of an integer, giving the number of nodes+-- in the graph, and function mapping each vertex (0..n-1, n=size of graph) to+-- its neighbouring nodes. `mk_graph' takes a size and an edge list and+-- constructs a graph.++type Graph = (Int,Int->[Int])+type Edge = (Int,Int)++mk_graph:: Int -> [Edge] -> Graph+mk_graph sz es = (sz,\v->ar!v)+ where+ ar = accumArray (flip (:)) [] (0,sz-1) [(v,v')| (v,v')<-es]++vertices:: Graph -> [Int]+vertices (sz,_) = [0..sz-1]++out:: Graph -> Int -> [Int]+out (_,f) = f++edges:: Graph -> [Edge]+edges g = [(v,v')| v<-vertices g, v'<-out g v]++rev_edges:: Graph -> [Edge]+rev_edges g = [(v',v)| v<-vertices g, v'<-out g v]++reverse_graph:: Graph -> Graph+reverse_graph g@(sz,_) = mk_graph sz (rev_edges g)+++-- `t_close' takes the transitive closure of a graph; `scc' returns the stronly+-- connected components of the graph and `top_sort' topologically sorts the+-- graph. Note that the array is given one more element in order to avoid+-- problems with empty arrays.++t_close:: Graph -> Graph+t_close g@(sz,_) = (sz,\v->ar!v)+ where+ ar = listArray (0,sz) ([postorder(dff' [v] g)| v<-vertices g]++[und])+ und = error "t_close"++scc:: Graph -> GForrest+scc g = dff' (reverse (top_sort (reverse_graph g))) g++top_sort:: Graph -> [Int]+top_sort = postorder . dff +++-- `dff' computes the depth-first forrest. It works by unrolling the+-- potentially infinite tree from each of the vertices with `generate_g' and+-- then pruning out the duplicates.++dff:: Graph -> GForrest+dff g = dff' (vertices g) g++dff':: [Int] -> Graph -> GForrest+dff' vs (_bs, f) = prune (map (generate_g f) vs)++generate_g:: (Int->[Int]) -> Int -> GTree+generate_g f v = GNode v (map (generate_g f) (f v))++prune:: GForrest -> GForrest+prune ts = snd(chop(empty_int,ts))+ where+ empty_int:: Set Int+ empty_int = Set.empty++chop:: (Set Int,GForrest) -> (Set Int,GForrest)+chop p@(_, []) = p+chop (vstd,GNode v ts:us) =+ if v `Set.member` vstd+ then chop (vstd,us)+ else let vstd1 = Set.insert v vstd+ (vstd2,ts') = chop (vstd1,ts)+ (vstd3,us') = chop (vstd2,us)+ in+ (vstd3,GNode v ts' : us')+++{-- Some simple test functions++test:: Graph Char+test = mk_graph (char_bds ('a','h')) (mk_pairs "eefggfgegdhfhged")+ where+ mk_pairs [] = []+ mk_pairs (a:b:l) = (a,b):mk_pairs l++-}
+ src/Info.hs view
@@ -0,0 +1,65 @@+-- -----------------------------------------------------------------------------+-- +-- Info.hs, part of Alex+--+-- (c) Simon Marlow 2003+--+-- Generate a human-readable rendition of the state machine.+--+-- ----------------------------------------------------------------------------}++module Info (infoDFA) where++import AbsSyn+import qualified Map+import Util+import CharSet++import Data.Array++-- -----------------------------------------------------------------------------+-- Generate a human readable dump of the state machine++infoDFA :: Int -> String -> DFA SNum Code -> ShowS+infoDFA _ func_nm dfa+ = str "Scanner : " . str func_nm . nl+ . str "States : " . shows (length dfa_list) . nl+ . nl . infoDFA'+ where + dfa_list = Map.toAscList (dfa_states dfa)++ infoDFA' = interleave_shows nl (map infoStateN dfa_list)++ infoStateN (i,s) = str "State " . shows i . nl . infoState s++ infoState :: State SNum Code -> ShowS+ infoState (State accs out)+ = foldr (.) id (map infoAccept accs)+ . infoArr out . nl++ infoArr out+ = char '\t' . interleave_shows (str "\n\t")+ (map infoTransition (Map.toAscList out))++ infoAccept (Acc p act lctx rctx)+ = str "\tAccept" . paren (shows p) . space+ . outputLCtx lctx . space+ . showRCtx rctx+ . (case act of+ Nothing -> id+ Just code -> str " { " . str code . str " }")+ . nl+ + infoTransition (char',state)+ = str (ljustify 8 (show char'))+ . str " -> "+ . shows state++ outputLCtx Nothing+ = id+ outputLCtx (Just set)+ = paren (outputArr (charSetToArray set)) . char '^'++ outputArr arr+ = str "Array.array " . shows (bounds arr) . space+ . shows (assocs arr)
+ src/Map.hs view
@@ -0,0 +1,67 @@+module Map (+ Map,+ member, lookup, findWithDefault,+ empty,+ insert, insertWith,+ delete,+ union, unionWith, unions,+ mapWithKey,+ elems,+ fromList, fromListWith,+ toAscList+) where++#if __GLASGOW_HASKELL__ >= 603+import Data.Map+import Prelude ()+#else+import Data.FiniteMap+import Prelude hiding ( lookup )++type Map k a = FiniteMap k a++member :: Ord k => k -> Map k a -> Bool+member = elemFM++lookup :: Ord k => k -> Map k a -> Maybe a+lookup = flip lookupFM++findWithDefault :: Ord k => a -> k -> Map k a -> a+findWithDefault a k m = lookupWithDefaultFM m a k++empty :: Map k a+empty = emptyFM++insert :: Ord k => k -> a -> Map k a -> Map k a+insert k a m = addToFM m k a++insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a+insertWith c k a m = addToFM_C c m k a++delete :: Ord k => k -> Map k a -> Map k a+delete = flip delFromFM++union :: Ord k => Map k a -> Map k a -> Map k a+union = flip plusFM++unionWith :: Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a+unionWith c l r = plusFM_C c r l++unions :: Ord k => [Map k a] -> Map k a+unions = foldl (flip plusFM) emptyFM++mapWithKey :: (k -> a -> b) -> Map k a -> Map k b+mapWithKey = mapFM++elems :: Map k a -> [a]+elems = eltsFM++fromList :: Ord k => [(k,a)] -> Map k a+fromList = listToFM++fromListWith :: Ord k => (a -> a -> a) -> [(k,a)] -> Map k a +fromListWith c = addListToFM_C (flip c) emptyFM++toAscList :: Map k a -> [(k,a)]+toAscList = fmToList+#endif
+ src/NFA.hs view
@@ -0,0 +1,215 @@+-- -----------------------------------------------------------------------------+-- +-- NFA.hs, part of Alex+--+-- (c) Chris Dornan 1995-2000, Simon Marlow 2003+--+-- The `scanner2nfa' takes a `Scanner' (see the `RExp' module) and+-- generates its equivelent nondeterministic finite automaton. NFAs+-- are turned into DFAs in the DFA module.+-- +-- See the chapter on `Finite Automata and Lexical Analysis' in the+-- dragon book for an excellent overview of the algorithms in this+-- module.+--+-- ----------------------------------------------------------------------------}++module NFA where++import AbsSyn+import CharSet ( CharSet, charSetToArray )+import DFS ( t_close, out )+import Map ( Map )+import qualified Map hiding ( Map )+import Util ( str, space )++import Control.Monad ( zipWithM, zipWithM_ )+import Data.Array ( Array, (!), array, listArray, assocs, bounds )+--import Debug.Trace++-- Each state of a nondeterministic automaton contains a list of `Accept'+-- values, a list of epsilon transitions (an epsilon transition represents a+-- transition to another state that can be made without reading a character)+-- and a list of transitions qualified with a character predicate (the+-- transition can only be made to the given state on input of a character+-- permitted by the predicate). Although a list of `Accept' values is provided+-- for, in actual fact each state will have zero or one of them (the `Maybe'+-- type is not used because the flexibility offered by the list representation+-- is useful).++type NFA = Array SNum NState++data NState = NSt {+ nst_accs :: [Accept Code],+ nst_cl :: [SNum],+ nst_outs :: [(CharSet,SNum)]+ }++-- Debug stuff+instance Show NState where+ showsPrec _ (NSt accs cl outs) =+ str "NSt " . shows accs . space . shows cl . space .+ shows [ (charSetToArray c, s) | (c,s) <- outs ]++{- From the Scan Module++-- The `Accept' structure contains the priority of the token being accepted+-- (lower numbers => higher priorities), the name of the token, a place holder+-- that can be used for storing the `action' function, a list of start codes+-- (listing the start codes that the scanner must be in for the token to be+-- accepted; empty => no restriction), the leading and trailing context (both+-- `Nothing' if there is none).+-- +-- The leading context consists simply of a character predicate that will+-- return true if the last character read is acceptable. The trailing context+-- consists of an alternative starting state within the DFA; if this `sub-dfa'+-- turns up any accepting state when applied to the residual input then the+-- trailing context is acceptable.+-}+++-- `scanner2nfa' takes a scanner (see the AbsSyn module) and converts it to an+-- NFA, using the NFA creation monad (see below).+--+-- We generate a start state for each startcode, with the same number+-- as that startcode, and epsilon transitions from this state to each+-- of the sub-NFAs for each of the tokens acceptable in that startcode.++scanner2nfa:: Scanner -> [StartCode] -> NFA+scanner2nfa Scanner{scannerTokens = toks} startcodes+ = runNFA $+ do+ -- make a start state for each start code (these will be+ -- numbered from zero).+ start_states <- sequence (replicate (length startcodes) newState)+ + -- construct the NFA for each token+ tok_states <- zipWithM do_token toks [0..]++ -- make an epsilon edge from each state state to each+ -- token that is acceptable in that state+ zipWithM_ (tok_transitions (zip toks tok_states)) + startcodes start_states++ where+ do_token (RECtx _scs lctx re rctx code) prio = do+ b <- newState+ e <- newState+ rexp2nfa b e re++ rctx_e <- case rctx of+ NoRightContext ->+ return NoRightContext+ RightContextCode code' ->+ return (RightContextCode code')+ RightContextRExp re' -> do + r_b <- newState+ r_e <- newState+ rexp2nfa r_b r_e re'+ accept r_e rctxt_accept+ return (RightContextRExp r_b)++ accept e (Acc prio code lctx rctx_e)+ return b++ tok_transitions toks_with_states start_code start_state = do+ let states = [ s | (RECtx scs _ _ _ _, s) <- toks_with_states,+ null scs || start_code `elem` map snd scs ]+ mapM_ (epsilonEdge start_state) states++-- -----------------------------------------------------------------------------+-- NFA creation from a regular expression++-- rexp2nfa B E R generates an NFA that begins in state B, recognises+-- R, and ends in state E only if R has been recognised. ++rexp2nfa :: SNum -> SNum -> RExp -> NFAM ()+rexp2nfa b e Eps = epsilonEdge b e+rexp2nfa b e (Ch p) = charEdge b p e+rexp2nfa b e (re1 :%% re2) = do+ s <- newState+ rexp2nfa b s re1+ rexp2nfa s e re2+rexp2nfa b e (re1 :| re2) = do+ rexp2nfa b e re1+ rexp2nfa b e re2+rexp2nfa b e (Star re) = do+ s <- newState+ epsilonEdge b s+ rexp2nfa s s re+ epsilonEdge s e+rexp2nfa b e (Plus re) = do+ s1 <- newState+ s2 <- newState+ rexp2nfa s1 s2 re+ epsilonEdge b s1+ epsilonEdge s2 s1+ epsilonEdge s2 e+rexp2nfa b e (Ques re) = do+ rexp2nfa b e re+ epsilonEdge b e++-- -----------------------------------------------------------------------------+-- NFA creation monad.++-- Partial credit to Thomas Hallgren for this code, as I adapted it from+-- his "Lexing Haskell in Haskell" lexer generator.++type MapNFA = Map SNum NState++newtype NFAM a = N {unN :: SNum -> MapNFA -> (SNum, MapNFA, a)}++instance Monad NFAM where+ return a = N $ \s n -> (s,n,a)++ m >>= k = N $ \s n -> case unN m s n of+ (s', n', a) -> unN (k a) s' n'++runNFA :: NFAM () -> NFA+runNFA m = case unN m 0 Map.empty of+ (s, nfa_map, ()) -> -- trace (show (Map.toAscList nfa_map)) $ + e_close (array (0,s-1) (Map.toAscList nfa_map))++e_close:: Array Int NState -> NFA+e_close ar = listArray bds+ [NSt accs (out gr v) outs|(v,NSt accs _ outs)<-assocs ar]+ where+ gr = t_close (hi+1,\v->nst_cl (ar!v))+ bds@(_,hi) = bounds ar++newState :: NFAM SNum+newState = N $ \s n -> (s+1,n,s)++charEdge :: SNum -> CharSet -> SNum -> NFAM ()+charEdge from charset to = N $ \s n -> (s, addEdge n, ())+ where+ addEdge n =+ case Map.lookup from n of+ Nothing -> + Map.insert from (NSt [] [] [(charset,to)]) n+ Just (NSt acc eps trans) ->+ Map.insert from (NSt acc eps ((charset,to):trans)) n++epsilonEdge :: SNum -> SNum -> NFAM ()+epsilonEdge from to + | from == to = return ()+ | otherwise = N $ \s n -> (s, addEdge n, ())+ where+ addEdge n =+ case Map.lookup from n of+ Nothing -> Map.insert from (NSt [] [to] []) n+ Just (NSt acc eps trans) -> Map.insert from (NSt acc (to:eps) trans) n++accept :: SNum -> Accept Code -> NFAM ()+accept state new_acc = N $ \s n -> (s, addAccept n, ())+ where+ addAccept n = + case Map.lookup state n of+ Nothing ->+ Map.insert state (NSt [new_acc] [] []) n+ Just (NSt acc eps trans) ->+ Map.insert state (NSt (new_acc:acc) eps trans) n+++rctxt_accept :: Accept Code+rctxt_accept = Acc 0 Nothing Nothing NoRightContext
+ src/Output.hs view
@@ -0,0 +1,345 @@+-- -----------------------------------------------------------------------------+-- +-- Output.hs, part of Alex+--+-- (c) Simon Marlow 2003+--+-- Code-outputing and table-generation routines+--+-- ----------------------------------------------------------------------------}++module Output (outputDFA) where++import AbsSyn+import CharSet+import Util+import qualified Map++import Control.Monad.ST ( ST, runST )+import Data.Array ( Array )+import Data.Array.Base ( unsafeRead )+import Data.Array.ST ( STUArray, newArray, readArray, writeArray, freeze )+import Data.Array.Unboxed ( UArray, bounds, assocs, elems, (!), array, listArray )+import Data.Bits+import Data.Char ( ord, chr )+-- import Debug.Trace+import Data.List ( maximumBy, sortBy, groupBy )++-- -----------------------------------------------------------------------------+-- Printing the output++outputDFA :: Target -> Int -> String -> DFA SNum Code -> ShowS+outputDFA target _ _ dfa+ = interleave_shows nl + [outputBase, outputTable, outputCheck, outputDefault, outputAccept]+ where + (base, table, check, deflt, accept) = mkTables dfa++ table_size = length table - 1+ n_states = length base - 1++ base_nm = "alex_base"+ table_nm = "alex_table"+ check_nm = "alex_check"+ deflt_nm = "alex_deflt"+ accept_nm = "alex_accept"++ outputBase = do_array hexChars32 base_nm n_states base+ outputTable = do_array hexChars16 table_nm table_size table+ outputCheck = do_array hexChars16 check_nm table_size check+ outputDefault = do_array hexChars16 deflt_nm n_states deflt++ do_array hex_chars nm upper_bound ints = case target of+ GhcTarget ->+ str nm . str " :: AlexAddr\n"+ . str nm . str " = AlexA# \""+ . str (hex_chars ints)+ . str "\"#\n"++ _ ->+ str nm . str " :: Array Int Int\n"+ . str nm . str " = listArray (0," . shows upper_bound+ . str ") [" . interleave_shows (char ',') (map shows ints)+ . str "]\n"++ outputAccept+ = -- No type signature: we don't know what the type of the actions is.+ -- str accept_nm . str " :: Array Int (Accept Code)\n"+ str accept_nm . str " = listArray (0::Int," . shows n_states+ . str ") [" . interleave_shows (char ',') (map outputAccs accept)+ . str "]\n"++ outputAccs :: [Accept Code] -> ShowS+ outputAccs accs+ = brack (interleave_shows (char ',') (map (paren.outputAcc) accs))++ outputAcc (Acc _ Nothing Nothing NoRightContext)+ = str "AlexAccSkip"+ outputAcc (Acc _ (Just act) Nothing NoRightContext)+ = str "AlexAcc " . paren (str act)+ outputAcc (Acc _ Nothing lctx rctx)+ = str "AlexAccSkipPred " . space+ . paren (outputPred lctx rctx)+ outputAcc (Acc _ (Just act) lctx rctx)+ = str "AlexAccPred " . space+ . paren (str act) . space+ . paren (outputPred lctx rctx)++ outputPred (Just set) NoRightContext+ = outputLCtx set+ outputPred Nothing rctx+ = outputRCtx rctx+ outputPred (Just set) rctx+ = outputLCtx set+ . str " `alexAndPred` "+ . outputRCtx rctx++ outputLCtx set + = case charSetElems set of+ [] -> error "outputLCtx"+ [c] -> str "alexPrevCharIs " . shows c+ _other -> str "alexPrevCharIsOneOf " + . paren (outputArr (charSetToArray set))++ outputRCtx NoRightContext = id+ outputRCtx (RightContextRExp sn)+ = str "alexRightContext " . shows sn+ outputRCtx (RightContextCode code)+ = str code++ outputArr arr+ = str "array " . shows (bounds arr) . space+ . shows (assocs arr)++-- -----------------------------------------------------------------------------+-- Generating arrays.++-- Here we use the table-compression algorithm described in section+-- 3.9 of the dragon book, which is a common technique used by lexical+-- analyser generators.++-- We want to generate:+--+-- base :: Array SNum Int+-- maps the current state to an offset in the main table+--+-- table :: Array Int SNum+-- maps (base!state + char) to the next state+--+-- check :: Array Int SNum+-- maps (base!state + char) to state if table entry is valid,+-- otherwise we use the default for this state+--+-- default :: Array SNum SNum+-- default production for this state+--+-- accept :: Array SNum [Accept Code]+-- maps state to list of accept codes for this state+--+-- For each state, we decide what will be the default symbol (pick the+-- most common). We now have a mapping Char -> SNum, with one special+-- state reserved as the default.+++mkTables :: DFA SNum Code+ -> ( + [Int], -- base+ [Int], -- table+ [Int], -- check+ [Int], -- default+ [[Accept Code]] -- accept+ )+mkTables dfa+ = ( elems base_offs, + take max_off (elems table),+ take max_off (elems check),+ elems defaults,+ accept+ )+ where + accept = [ as | State as _ <- elems dfa_arr ]++ state_assocs = Map.toAscList (dfa_states dfa)+ n_states = length state_assocs+ top_state = n_states - 1++ dfa_arr :: Array SNum (State SNum Code)+ dfa_arr = array (0,top_state) state_assocs++ -- fill in all the error productions+ expand_states =+ [ expand (dfa_arr!state) | state <- [0..top_state] ]+ + expand (State _ out) = + [(i, lookup' out i) | i <- ['\0'..'\255']]+ where lookup' out' i = case Map.lookup i out' of+ Nothing -> -1+ Just s -> s++ defaults :: UArray SNum SNum+ defaults = listArray (0,top_state) (map best_default expand_states)++ -- find the most common destination state in a given state, and+ -- make it the default.+ best_default :: [(Char,SNum)] -> SNum+ best_default prod_list+ | null sorted = -1+ | otherwise = snd (head (maximumBy lengths eq))+ where sorted = sortBy compareSnds prod_list+ compareSnds (_,a) (_,b) = compare a b+ eq = groupBy (\(_,a) (_,b) -> a == b) sorted+ lengths a b = length a `compare` length b++ -- remove all the default productions from the DFA+ dfa_no_defaults =+ [ (s, prods_without_defaults s out)+ | (s, out) <- zip [0..] expand_states+ ]++ prods_without_defaults s out + = [ (ord c, dest) | (c,dest) <- out, dest /= defaults!s ]++ (base_offs, table, check, max_off)+ = runST (genTables n_states 255 dfa_no_defaults)+ ++genTables+ :: Int -- number of states+ -> Int -- maximum token no.+ -> [(SNum,[(Int,SNum)])] -- entries for the table+ -> ST s (UArray Int Int, -- base+ UArray Int Int, -- table+ UArray Int Int, -- check+ Int -- highest offset in table+ )++genTables n_states max_token entries = do++ base <- newArray (0, n_states-1) 0+ table <- newArray (0, mAX_TABLE_SIZE) 0+ check <- newArray (0, mAX_TABLE_SIZE) (-1)+ off_arr <- newArray (-max_token, mAX_TABLE_SIZE) 0++ max_off <- genTables' base table check off_arr entries max_token++ base' <- freeze base+ table' <- freeze table+ check' <- freeze check+ return (base', table',check',max_off+1)++ where mAX_TABLE_SIZE = n_states * (max_token + 1)+++genTables'+ :: STUArray s Int Int -- base+ -> STUArray s Int Int -- table+ -> STUArray s Int Int -- check+ -> STUArray s Int Int -- offset array+ -> [(SNum,[(Int,SNum)])] -- entries for the table+ -> Int -- maximum token no.+ -> ST s Int -- highest offset in table++genTables' base table check off_arr entries max_token+ = fit_all entries 0 1+ where++ fit_all [] max_off _ = return max_off+ fit_all (s:ss) max_off fst_zero = do+ (off, new_max_off, new_fst_zero) <- fit s max_off fst_zero+ writeArray off_arr off 1+ fit_all ss new_max_off new_fst_zero++ -- fit a vector into the table. Return the offset of the vector,+ -- the maximum offset used in the table, and the offset of the first+ -- entry in the table (used to speed up the lookups a bit).+ fit (_,[]) max_off fst_zero = return (0,max_off,fst_zero)++ fit (state_no, state@((t,_):_)) max_off fst_zero = do+ -- start at offset 1 in the table: all the empty states+ -- (states with just a default reduction) are mapped to+ -- offset zero.+ off <- findFreeOffset (-t + fst_zero) check off_arr state+ let new_max_off | furthest_right > max_off = furthest_right+ | otherwise = max_off+ furthest_right = off + max_token++ --trace ("fit: state " ++ show state_no ++ ", off " ++ show off ++ ", elems " ++ show state) $ do++ writeArray base state_no off+ addState off table check state+ new_fst_zero <- findFstFreeSlot check fst_zero+ return (off, new_max_off, new_fst_zero)+++-- Find a valid offset in the table for this state.+findFreeOffset :: Int+ -> STUArray s Int Int+ -> STUArray s Int Int+ -> [(Int, Int)]+ -> ST s Int+findFreeOffset off check off_arr state = do+ -- offset 0 isn't allowed+ if off == 0 then try_next else do++ -- don't use an offset we've used before+ b <- readArray off_arr off+ if b /= 0 then try_next else do++ -- check whether the actions for this state fit in the table+ ok <- fits off state check+ if ok then return off else try_next + where+ try_next = findFreeOffset (off+1) check off_arr state++-- This is an inner loop, so we use some strictness hacks, and avoid+-- array bounds checks (unsafeRead instead of readArray) to speed+-- things up a bit.+fits :: Int -> [(Int,Int)] -> STUArray s Int Int -> ST s Bool+fits off [] check = off `seq` check `seq` return True -- strictness hacks+fits off ((t,_):rest) check = do+ i <- unsafeRead check (off+t)+ if i /= -1 then return False+ else fits off rest check++addState :: Int -> STUArray s Int Int -> STUArray s Int Int -> [(Int, Int)]+ -> ST s ()+addState _ _ _ [] = return ()+addState off table check ((t,val):state) = do+ writeArray table (off+t) val+ writeArray check (off+t) t+ addState off table check state++findFstFreeSlot :: STUArray s Int Int -> Int -> ST s Int+findFstFreeSlot table n = do+ i <- readArray table n+ if i == -1 then return n+ else findFstFreeSlot table (n+1)++-----------------------------------------------------------------------------+-- Convert an integer to a 16-bit number encoded in \xNN\xNN format suitable+-- for placing in a string (copied from Happy's ProduceCode.lhs)++hexChars16 :: [Int] -> String+hexChars16 acts = concat (map conv16 acts)+ where+ conv16 i | i > 0x7fff || i < -0x8000+ = error ("Internal error: hexChars16: out of range: " ++ show i)+ | otherwise+ = hexChar16 i++hexChars32 :: [Int] -> String+hexChars32 acts = concat (map conv32 acts)+ where+ conv32 i = hexChar16 (i .&. 0xffff) ++ + hexChar16 ((i `shiftR` 16) .&. 0xffff)++hexChar16 :: Int -> String+hexChar16 i = toHex (i .&. 0xff)+ ++ toHex ((i `shiftR` 8) .&. 0xff) -- force little-endian++toHex :: Int -> String+toHex i = ['\\','x', hexDig (i `div` 16), hexDig (i `mod` 16)]++hexDig :: Int -> Char+hexDig i | i <= 9 = chr (i + ord '0')+ | otherwise = chr (i - 10 + ord 'a')
+ src/ParseMonad.hs view
@@ -0,0 +1,128 @@+-- -----------------------------------------------------------------------------+-- +-- ParseMonad.hs, part of Alex+--+-- (c) Simon Marlow 2003+--+-- ----------------------------------------------------------------------------}++module ParseMonad (+ AlexInput, alexInputPrevChar, alexGetChar,+ AlexPosn(..), alexStartPos,+ + P, runP, StartCode, failP, lookupSMac, lookupRMac, newSMac, newRMac,+ setStartCode, getStartCode, getInput, setInput,+ ) where++import AbsSyn hiding ( StartCode )+import CharSet ( CharSet )+import Map ( Map )+import qualified Map hiding ( Map )++-- -----------------------------------------------------------------------------+-- The input type++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (_,c,_) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (_,_,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq,Show)++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l _) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)++-- -----------------------------------------------------------------------------+-- Alex lexing/parsing monad++type ParseError = (Maybe AlexPosn, String)+type StartCode = Int++data PState = PState {+ smac_env :: Map String CharSet,+ rmac_env :: Map String RExp,+ startcode :: Int,+ input :: AlexInput+ }++newtype P a = P { unP :: PState -> Either ParseError (PState,a) }++instance Monad P where+ (P m) >>= k = P $ \env -> case m env of+ Left err -> Left err+ Right (env',ok) -> unP (k ok) env'+ return a = P $ \env -> Right (env,a)++runP :: String -> (Map String CharSet, Map String RExp) + -> P a -> Either ParseError a+runP str (senv,renv) (P p) + = case p initial_state of+ Left err -> Left err+ Right (_,a) -> Right a+ where initial_state = + PState{ smac_env=senv, rmac_env=renv,+ startcode = 0, input=(alexStartPos,'\n',str) }++failP :: String -> P a+failP str = P $ \PState{ input = (p,_,_) } -> Left (Just p,str)++-- Macros are expanded during parsing, to simplify the abstract+-- syntax. The parsing monad passes around two environments mapping+-- macro names to sets and regexps respectively.++lookupSMac :: (AlexPosn,String) -> P CharSet+lookupSMac (posn,smac)+ = P $ \s@PState{ smac_env = senv } -> + case Map.lookup smac senv of+ Just ok -> Right (s,ok)+ Nothing -> Left (Just posn, "unknown set macro: $" ++ smac)++lookupRMac :: String -> P RExp+lookupRMac rmac + = P $ \s@PState{ rmac_env = renv } -> + case Map.lookup rmac renv of+ Just ok -> Right (s,ok)+ Nothing -> Left (Nothing, "unknown regex macro: %" ++ rmac)++newSMac :: String -> CharSet -> P ()+newSMac smac set + = P $ \s -> Right (s{smac_env = Map.insert smac set (smac_env s)}, ())++newRMac :: String -> RExp -> P ()+newRMac rmac rexp + = P $ \s -> Right (s{rmac_env = Map.insert rmac rexp (rmac_env s)}, ())++setStartCode :: StartCode -> P ()+setStartCode sc = P $ \s -> Right (s{ startcode = sc }, ())++getStartCode :: P StartCode+getStartCode = P $ \s -> Right (s, startcode s)++getInput :: P AlexInput+getInput = P $ \s -> Right (s, input s)++setInput :: AlexInput -> P ()+setInput inp = P $ \s -> Right (s{ input = inp }, ())
+ src/Parser.y view
@@ -0,0 +1,220 @@+{+-- -----------------------------------------------------------------------------+-- +-- Parser.y, part of Alex+--+-- (c) Simon Marlow 2003+--+-- -----------------------------------------------------------------------------++{-# OPTIONS_GHC -w #-}++module Parser ( parse, P ) where+import AbsSyn+import Scan+import CharSet+import ParseMonad hiding ( StartCode )++import Data.Char+--import Debug.Trace+}++%tokentype { Token }++%name parse++%monad { P } { (>>=) } { return }+%lexer { lexer } { T _ EOFT }++%token+ '.' { T _ (SpecialT '.') }+ ';' { T _ (SpecialT ';') }+ '<' { T _ (SpecialT '<') }+ '>' { T _ (SpecialT '>') }+ ',' { T _ (SpecialT ',') }+ '$' { T _ (SpecialT '$') }+ '|' { T _ (SpecialT '|') }+ '*' { T _ (SpecialT '*') }+ '+' { T _ (SpecialT '+') }+ '?' { T _ (SpecialT '?') }+ '{' { T _ (SpecialT '{') }+ '}' { T _ (SpecialT '}') }+ '(' { T _ (SpecialT '(') }+ ')' { T _ (SpecialT ')') }+ '#' { T _ (SpecialT '#') }+ '~' { T _ (SpecialT '~') }+ '-' { T _ (SpecialT '-') }+ '[' { T _ (SpecialT '[') }+ ']' { T _ (SpecialT ']') }+ '^' { T _ (SpecialT '^') }+ '/' { T _ (SpecialT '/') }+ ZERO { T _ ZeroT }+ STRING { T _ (StringT $$) }+ BIND { T _ (BindT $$) }+ ID { T _ (IdT $$) }+ CODE { T _ (CodeT _) }+ CHAR { T _ (CharT $$) }+ SMAC { T _ (SMacT _) }+ RMAC { T _ (RMacT $$) }+ SMAC_DEF { T _ (SMacDefT $$) }+ RMAC_DEF { T _ (RMacDefT $$) }+ WRAPPER { T _ WrapperT }+%%++alex :: { (Maybe (AlexPosn,Code), [Directive], Scanner, Maybe (AlexPosn,Code)) }+ : maybe_code directives macdefs scanner maybe_code { ($1,$2,$4,$5) }++maybe_code :: { Maybe (AlexPosn,Code) }+ : CODE { case $1 of T pos (CodeT code) -> + Just (pos,code) }+ | {- empty -} { Nothing }++directives :: { [Directive] }+ : directive directives { $1 : $2 }+ | {- empty -} { [] }++directive :: { Directive }+ : WRAPPER STRING { WrapperDirective $2 }++macdefs :: { () }+ : macdef macdefs { () }+ | {- empty -} { () }++-- hack: the lexer looks for the '=' in a macro definition, because there+-- doesn't seem to be a way to formulate the grammar here to avoid a+-- conflict (it needs LR(2) rather than LR(1) to find the '=' and distinguish+-- an SMAC/RMAC at the beginning of a definition from an SMAC/RMAC that is+-- part of a regexp in the previous definition).+macdef :: { () }+ : SMAC_DEF set {% newSMac $1 $2 }+ | RMAC_DEF rexp {% newRMac $1 $2 }++scanner :: { Scanner }+ : BIND tokendefs { Scanner $1 $2 }++tokendefs :: { [RECtx] }+ : tokendef tokendefs { $1 ++ $2 }+ | {- empty -} { [] }++tokendef :: { [RECtx] }+ : startcodes rule { [ replaceCodes $1 $2 ] }+ | startcodes '{' rules '}' { map (replaceCodes $1) $3 }+ | rule { [ $1 ] }++rule :: { RECtx }+ : context rhs { let (l,e,r) = $1 in + RECtx [] l e r $2 }++rules :: { [RECtx] }+ : rule rules { $1 : $2 }+ | {- empty -} { [] }++startcodes :: { [(String,StartCode)] }+ : '<' startcodes0 '>' { $2 }++startcodes0 :: { [(String,StartCode)] }+ : startcode ',' startcodes0 { ($1,0) : $3 }+ | startcode { [($1,0)] }++startcode :: { String }+ : ZERO { "0" }+ | ID { $1 }++rhs :: { Maybe Code }+ : CODE { case $1 of T _ (CodeT code) -> Just code }+ | ';' { Nothing }++context :: { Maybe CharSet, RExp, RightContext RExp }+ : left_ctx rexp right_ctx { (Just $1,$2,$3) }+ | rexp right_ctx { (Nothing,$1,$2) }++left_ctx :: { CharSet }+ : '^' { charSetSingleton '\n' }+ | set '^' { $1 }++right_ctx :: { RightContext RExp }+ : '$' { RightContextRExp (Ch (charSetSingleton '\n')) }+ | '/' rexp { RightContextRExp $2 }+ | '/' CODE { RightContextCode (case $2 of + T _ (CodeT code) -> code) }+ | {- empty -} { NoRightContext }++rexp :: { RExp }+ : alt '|' rexp { $1 :| $3 }+ | alt { $1 }++alt :: { RExp }+ : alt term { $1 :%% $2 }+ | term { $1 }++term :: { RExp }+ : rexp0 rep { $2 $1 }+ | rexp0 { $1 }++rep :: { RExp -> RExp }+ : '*' { Star }+ | '+' { Plus }+ | '?' { Ques }+ -- TODO: these don't check for digits+ -- properly.+ | '{' CHAR '}' { repeat_rng (digit $2) Nothing }+ | '{' CHAR ',' '}' { repeat_rng (digit $2) (Just Nothing) }+ | '{' CHAR ',' CHAR '}' { repeat_rng (digit $2) (Just (Just (digit $4))) }++rexp0 :: { RExp }+ : '(' ')' { Eps }+ | STRING { foldr (:%%) Eps + (map (Ch . charSetSingleton) $1) }+ | RMAC {% lookupRMac $1 }+ | set { Ch $1 }+ | '(' rexp ')' { $2 }++set :: { CharSet }+ : set '#' set0 { $1 `charSetMinus` $3 }+ | set0 { $1 }++set0 :: { CharSet }+ : CHAR { charSetSingleton $1 }+ | CHAR '-' CHAR { charSetRange $1 $3 }+ | smac {% lookupSMac $1 }+ | '[' sets ']' { foldr charSetUnion emptyCharSet $2 }++ -- [^sets] is the same as '. # [sets]'+ -- The upshot is that [^set] does *not* match a newline character,+ -- which seems much more useful than just taking the complement.+ | '[' '^' sets ']' + {% do { dot <- lookupSMac (tokPosn $1, ".");+ return (dot `charSetMinus`+ foldr charSetUnion emptyCharSet $3) }}++ -- ~set is the same as '. # set'+ | '~' set0 {% do { dot <- lookupSMac (tokPosn $1, ".");+ return (dot `charSetMinus` $2) } }++sets :: { [CharSet] }+ : set sets { $1 : $2 }+ | {- empty -} { [] }++smac :: { (AlexPosn,String) }+ : '.' { (tokPosn $1, ".") }+ | SMAC { case $1 of T p (SMacT s) -> (p, s) }++{+happyError :: P a+happyError = failP "parse error"++-- -----------------------------------------------------------------------------+-- Utils++digit c = ord c - ord '0'++repeat_rng :: Int -> Maybe (Maybe Int) -> (RExp->RExp)+repeat_rng n (Nothing) re = foldr (:%%) Eps (replicate n re)+repeat_rng n (Just Nothing) re = foldr (:%%) (Star re) (replicate n re)+repeat_rng n (Just (Just m)) re = intl :%% rst+ where+ intl = repeat_rng n Nothing re+ rst = foldr (\re re'->Ques(re :%% re')) Eps (replicate (m-n) re)++replaceCodes codes rectx = rectx{ reCtxStartCodes = codes }+}
+ src/Scan.x view
@@ -0,0 +1,218 @@+-------------------------------------------------------------------------------+-- ALEX SCANNER AND LITERATE PREPROCESSOR+-- +-- This Script defines the grammar used to generate the Alex scanner and a+-- preprocessing scanner for dealing with literate scripts. The actions for+-- the Alex scanner are given separately in the Alex module.+-- +-- See the Alex manual for a discussion of the scanners defined here.+-- +-- Chris Dornan, Aug-95, 4-Jun-96, 10-Jul-96, 29-Sep-97+-------------------------------------------------------------------------------++{+{-# OPTIONS_GHC -w #-}++module Scan(lexer, AlexPosn(..), Token(..), Tkn(..), tokPosn) where++import Data.Char+import ParseMonad+--import Debug.Trace+}++$digit = 0-9+$hexdig = [0-9 A-F a-f]+$octal = 0-7+$lower = a-z+$upper = A-Z+$alpha = [$upper $lower]+$alphanum = [$alpha $digit]+$idchar = [$alphanum \_ \']++$special = [\.\;\,\$\|\*\+\?\#\~\-\{\}\(\)\[\]\^\/]+$graphic = $printable # $white+$nonspecial = $graphic # [$special \%]++@id = $alpha $idchar*+@smac = \$ @id | \$ \{ @id \}+@rmac = \@ @id | \@ \{ @id \}++@comment = "--".*+@ws = $white+ | @comment++alex :-++@ws { skip } -- white space; ignore++<0> \" [^\"]* \" { string }+<0> (@id @ws?)? \:\- { bind }+<0> \{ / (\n | [^$digit]) { code }+<0> $special { special } -- note: matches {+<0> \% "wrapper" { wrapper }++<0> \\ $digit+ { decch }+<0> \\ x $hexdig+ { hexch }+<0> \\ o $octal+ { octch }+<0> \\ $printable { escape }+<0> $nonspecial # [\<] { char }+<0> @smac { smac }+<0> @rmac { rmac }++<0> @smac @ws? \= { smacdef }+<0> @rmac @ws? \= { rmacdef }++-- identifiers are allowed to be unquoted in startcode lists+<0> \< { special `andBegin` startcodes }+<startcodes> 0 { zero }+<startcodes> @id { startcode }+<startcodes> \, { special }+<startcodes> \> { special `andBegin` afterstartcodes }++-- After a <..> startcode sequence, we can have a {...} grouping of rules,+-- so don't try to interpret the opening { as a code block.+<afterstartcodes> \{ (\n | [^$digit ]) { special `andBegin` 0 }+<afterstartcodes> () { skip `andBegin` 0 } -- note: empty pattern+{++-- -----------------------------------------------------------------------------+-- Token type++data Token = T AlexPosn Tkn+ deriving Show++tokPosn (T p _) = p++data Tkn+ = SpecialT Char+ | CodeT String+ | ZeroT+ | IdT String+ | StringT String+ | BindT String+ | CharT Char+ | SMacT String+ | RMacT String + | SMacDefT String+ | RMacDefT String + | NumT Int + | WrapperT+ | EOFT+ deriving Show++-- -----------------------------------------------------------------------------+-- Token functions++special (p,_,str) ln = return $ T p (SpecialT (head str))+zero (p,_,str) ln = return $ T p ZeroT+string (p,_,str) ln = return $ T p (StringT (extract ln str))+bind (p,_,str) ln = return $ T p (BindT (takeWhile isIdChar str))+escape (p,_,str) ln = return $ T p (CharT (esc str))+decch (p,_,str) ln = return $ T p (CharT (do_ech 10 ln (take (ln-1) (tail str))))+hexch (p,_,str) ln = return $ T p (CharT (do_ech 16 ln (take (ln-2) (drop 2 str))))+octch (p,_,str) ln = return $ T p (CharT (do_ech 8 ln (take (ln-2) (drop 2 str))))+char (p,_,str) ln = return $ T p (CharT (head str))+smac (p,_,str) ln = return $ T p (SMacT (mac ln str))+rmac (p,_,str) ln = return $ T p (RMacT (mac ln str))+smacdef (p,_,str) ln = return $ T p (SMacDefT (macdef ln str))+rmacdef (p,_,str) ln = return $ T p (RMacDefT (macdef ln str))+startcode (p,_,str) ln = return $ T p (IdT (take ln str))+wrapper (p,_,str) ln = return $ T p WrapperT++isIdChar c = isAlphaNum c || c `elem` "_'"++extract ln str = take (ln-2) (tail str)+ +do_ech radix ln str = chr (parseInt radix str)++mac ln (_ : str) = take (ln-1) str++macdef ln (_ : str) = takeWhile (not.isSpace) str++esc (_ : x : _) =+ case x of+ 'a' -> '\a'+ 'b' -> '\b'+ 'f' -> '\f'+ 'n' -> '\n'+ 'r' -> '\r'+ 't' -> '\t'+ 'v' -> '\v'+ c -> c++parseInt :: Int -> String -> Int+parseInt radix ds = foldl1 (\n d -> n * radix + d) (map digitToInt ds)++-- In brace-delimited code, we have to be careful to match braces+-- within the code, but ignore braces inside strings and character+-- literals. We do an approximate job (doing it properly requires+-- implementing a large chunk of the Haskell lexical syntax).++code (p,_,inp) len = do+ inp <- getInput+ go inp 1 ""+ where+ go inp 0 cs = do+ setInput inp+ return (T p (CodeT (reverse (tail cs))))+ go inp n cs = do+ case alexGetChar inp of+ Nothing -> err inp+ Just (c,inp) -> + case c of+ '{' -> go inp (n+1) (c:cs) + '}' -> go inp (n-1) (c:cs)+ '\'' -> go_char inp n (c:cs)+ '\"' -> go_str inp n (c:cs) '\"'+ c -> go inp n (c:cs)++ -- try to catch occurrences of ' within an identifier+ go_char inp n (c1:c2:cs) | isAlphaNum c2 = go inp n (c1:c2:cs)+ go_char inp n cs = go_str inp n cs '\''++ go_str inp n cs end = do+ case alexGetChar inp of+ Nothing -> err inp+ Just (c,inp)+ | c == end -> go inp n (c:cs)+ | otherwise -> + case c of+ '\\' -> case alexGetChar inp of+ Nothing -> err inp+ Just (d,inp) -> go_str inp n (d:c:cs) end+ c -> go_str inp n (c:cs) end++ err inp = do setInput inp; lexError "lexical error in code fragment"+ +++lexError s = do+ (p,_,input) <- getInput+ failP (s ++ (if (not (null input))+ then " at " ++ show (head input)+ else " at end of file"))++lexer :: (Token -> P a) -> P a+lexer cont = lexToken >>= cont++lexToken :: P Token+lexToken = do+ inp@(p,_,_) <- getInput+ sc <- getStartCode+ case alexScan inp sc of+ AlexEOF -> return (T p EOFT)+ AlexError _ -> lexError "lexical error"+ AlexSkip inp1 len -> do+ setInput inp1+ lexToken+ AlexToken inp1 len t -> do+ setInput inp1+ t inp len++type Action = AlexInput -> Int -> P Token++skip :: Action+skip _ _ = lexToken++andBegin :: Action -> StartCode -> Action+andBegin act sc inp len = setStartCode sc >> act inp len+}
+ src/Set.hs view
@@ -0,0 +1,14 @@+module Set ( Set, member, empty, insert ) where++import Data.Set ++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 603+member :: Ord a => a -> Set a -> Bool+member = elementOf++empty :: Set a+empty = emptySet++insert :: Ord a => a -> Set a -> Set a+insert = flip addToSet+#endif
+ src/Sort.hs view
@@ -0,0 +1,71 @@+{------------------------------------------------------------------------------+ SORTING LISTS++This module provides properly parameterised insertion and merge sort functions,+complete with associated functions for inserting and merging. `isort' is the+standard lazy version and can be used to the minimum k elements of a list in+linear time. The merge sort is based on a Bob Buckley's (Bob Buckley+18-AUG-95) coding of Knuth's natural merge sort (see Vol. 2). It seems to be+fast in the average case; it makes use of natural runs in the data becomming+linear on ordered data; and it completes in worst time O(n.log(n)). It is+divinely elegant.++`nub'' is an n.log(n) version of `nub' and `group_sort' sorts a list into+strictly ascending order, using a combining function in its arguments to+amalgamate duplicates.++Chris Dornan, 14-Aug-93, 17-Nov-94, 29-Dec-95+------------------------------------------------------------------------------}++module Sort where++-- Hide (<=) so that we don't get name shadowing warnings for it+import Prelude hiding ((<=))++-- `isort' is an insertion sort and is here for historical reasons; msort is+-- better in almost every situation.++isort:: (a->a->Bool) -> [a] -> [a]+isort (<=) = foldr (insrt (<=)) []++insrt:: (a->a->Bool) -> a -> [a] -> [a]+insrt _ e [] = [e]+insrt (<=) e l@(h:t) = if e<=h then e:l else h:insrt (<=) e t+++msort :: (a->a->Bool) -> [a] -> [a]+msort _ [] = [] -- (foldb f []) is undefined+msort (<=) xs = foldb (mrg (<=)) (runs (<=) xs)++runs :: (a->a->Bool) -> [a] -> [[a]]+runs (<=) xs0 = foldr op [] xs0+ where+ op z xss@(xs@(x:_):xss') | z<=x = (z:xs):xss'+ | otherwise = [z]:xss+ op z xss = [z]:xss++foldb :: (a->a->a) -> [a] -> a+foldb _ [x] = x+foldb f xs0 = foldb f (fold xs0)+ where+ fold (x1:x2:xs) = f x1 x2 : fold xs+ fold xs = xs++mrg:: (a->a->Bool) -> [a] -> [a] -> [a]+mrg _ [] l = l+mrg _ l@(_:_) [] = l+mrg (<=) l1@(h1:t1) l2@(h2:t2) =+ if h1<=h2+ then h1:mrg (<=) t1 l2+ else h2:mrg (<=) l1 t2+++nub':: (a->a->Bool) -> [a] -> [a]+nub' (<=) l = group_sort (<=) const l+++group_sort:: (a->a->Bool) -> (a->[a]->b) -> [a] -> [b]+group_sort le cmb l = s_m (msort le l)+ where+ s_m [] = []+ s_m (h:t) = cmb h (takeWhile (`le` h) t):s_m (dropWhile (`le` h) t)
+ src/Text/Alex.hs view
@@ -0,0 +1,146 @@+-- -----------------------------------------------------------------------------+-- +-- Alex.hs, part of Alex+--+-- (c) Chris Dornan 1995-2000, Simon Marlow 2003+--+-- ----------------------------------------------------------------------------}++module Text.Alex (+ runAlex+ , CLIFlags(..)+ , alex+ , optsToInject+ , importsToInject+ + , parseScript, Target(..)+ ) where++import AbsSyn+import CharSet+import DFA+import Info+import Map ( Map )+import qualified Map hiding ( Map )+import Output+import ParseMonad ( runP )+import Parser+import Scan++import Data.Char ( chr )++++runAlex :: [CLIFlags] -> Maybe FilePath -> String -> (String,String)+runAlex cli file prg =+ let script = parseScript file prg in+ alex cli script++parseScript :: Maybe FilePath -> String+ -> (Maybe (AlexPosn,Code), [Directive], Scanner, Maybe (AlexPosn,Code))+parseScript maybeFile prg =+ let file = maybe "<no file>" id maybeFile in+ case runP prg initialParserEnv parse of+ Left (Just (AlexPn _ line col),err) -> + error (file ++ ":" ++ show line ++ ":" ++ show col+ ++ ": " ++ err ++ "\n")+ Left (Nothing, err) ->+ error (file ++ ": " ++ err ++ "\n")++ Right script -> script++++alex :: [CLIFlags]+ -> (Maybe (AlexPosn, Code), [Directive], Scanner, Maybe (AlexPosn, Code))+ -> (String,String)+alex cli script =+ let + target + | OptGhcTarget `elem` cli = GhcTarget+ | otherwise = HaskellTarget+ (maybe_header, directives, scanner1, maybe_footer) = script+ (scanner2, scs, sc_hdr) = encodeStartCodes scanner1+ (scanner_final, actions) = extractActions scanner2+ dfa = scanner2dfa scanner_final scs+ nm = scannerName scanner_final+ in+ (maybe id ((++) . snd) (maybe_header) $ + maybe id (flip (++) . snd) (maybe_footer) $ + outputDFA target 1 nm dfa "" ++ (actions "") ++ (sc_hdr "")+ ,(infoDFA 1 nm dfa ""))++optsToInject :: Target -> [CLIFlags] -> String+optsToInject GhcTarget _ = "{-# OPTIONS -fglasgow-exts -cpp #-}\n"+optsToInject _ _ = "{-# OPTIONS -cpp #-}\n"++importsToInject :: Target -> [CLIFlags] -> String+importsToInject _ cli = always_imports ++ debug_imports ++ glaexts_import+ where+ glaexts_import | OptGhcTarget `elem` cli = import_glaexts+ | otherwise = ""++ debug_imports | OptDebugParser `elem` cli = import_debug+ | otherwise = ""++-- CPP is turned on for -fglasogw-exts, so we can use conditional+-- compilation. We need to #include "config.h" to get hold of+-- WORDS_BIGENDIAN (see GenericTemplate.hs).++always_imports :: String+always_imports = "#if __GLASGOW_HASKELL__ >= 603\n" +++ "#include \"ghcconfig.h\"\n" +++ "#elif defined(__GLASGOW_HASKELL__)\n" +++ "#include \"config.h\"\n" +++ "#endif\n" +++ "#if __GLASGOW_HASKELL__ >= 503\n" +++ "import Data.Array\n" +++ "import Data.Char (ord)\n" +++ "import Data.Array.Base (unsafeAt)\n" +++ "#else\n" +++ "import Array\n" +++ "import Char (ord)\n" +++ "#endif\n"++import_glaexts :: String+import_glaexts = "#if __GLASGOW_HASKELL__ >= 503\n" +++ "import GHC.Exts\n" +++ "#else\n" +++ "import GlaExts\n" +++ "#endif\n"++import_debug :: String +import_debug = "#if __GLASGOW_HASKELL__ >= 503\n" +++ "import System.IO\n" +++ "import System.IO.Unsafe\n" +++ "import Debug.Trace\n" +++ "#else\n" +++ "import IO\n" +++ "import IOExts\n" +++ "#endif\n"++initialParserEnv :: (Map String CharSet, Map String RExp)+initialParserEnv = (initSetEnv, initREEnv)++initSetEnv :: Map String CharSet+initSetEnv = Map.fromList [("white", charSet " \t\n\v\f\r"),+ ("printable", charSet [chr 32 .. chr 126]),+ (".", charSetComplement emptyCharSet + `charSetMinus` charSetSingleton '\n')]++initREEnv :: Map String RExp+initREEnv = Map.empty++-- -----------------------------------------------------------------------------+-- Command-line flags++data CLIFlags + = OptDebugParser+ | OptGhcTarget+ | OptOutputFile FilePath+ | OptInfoFile (Maybe FilePath)+ | OptTemplateDir FilePath+ | DumpHelp+ | DumpVersion+ deriving Eq+
+ src/Text/Alex/AlexTemplate.hs view
@@ -0,0 +1,352 @@+module Text.Alex.AlexTemplate where+import AbsSyn++alexTemplate GhcTarget =+ "{-# LINE 1 \"templates\\GenericTemplate.hs\" #-}\n" ++ + "{-# LINE 1 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "{-# LINE 1 \"<built-in>\" #-}\n" ++ + "{-# LINE 1 \"<command line>\" #-}\n" ++ + "{-# LINE 1 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- ALEX TEMPLATE\n" ++ + "--\n" ++ + "-- This code is in the PUBLIC DOMAIN; you may copy it freely and use\n" ++ + "-- it for any purpose whatsoever.\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- INTERNALS and main scanner engine\n" ++ + "\n" ++ + "{-# LINE 37 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "\n" ++ + "{-# LINE 47 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "\n" ++ + "\n" ++ + "data AlexAddr = AlexA# Addr#\n" ++ + "\n" ++ + "#if __GLASGOW_HASKELL__ < 503\n" ++ + "uncheckedShiftL# = shiftL#\n" ++ + "#endif\n" ++ + "\n" ++ + "{-# INLINE alexIndexInt16OffAddr #-}\n" ++ + "alexIndexInt16OffAddr (AlexA# arr) off =\n" ++ + "#ifdef WORDS_BIGENDIAN\n" ++ + " narrow16Int# i\n" ++ + " where\n" ++ + "\ti = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)\n" ++ + "\thigh = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))\n" ++ + "\tlow = int2Word# (ord# (indexCharOffAddr# arr off'))\n" ++ + "\toff' = off *# 2#\n" ++ + "#else\n" ++ + " indexInt16OffAddr# arr off\n" ++ + "#endif\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "{-# INLINE alexIndexInt32OffAddr #-}\n" ++ + "alexIndexInt32OffAddr (AlexA# arr) off = \n" ++ + "#ifdef WORDS_BIGENDIAN\n" ++ + " narrow32Int# i\n" ++ + " where\n" ++ + " i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`\n" ++ + "\t\t (b2 `uncheckedShiftL#` 16#) `or#`\n" ++ + "\t\t (b1 `uncheckedShiftL#` 8#) `or#` b0)\n" ++ + " b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))\n" ++ + " b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))\n" ++ + " b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))\n" ++ + " b0 = int2Word# (ord# (indexCharOffAddr# arr off'))\n" ++ + " off' = off *# 4#\n" ++ + "#else\n" ++ + " indexInt32OffAddr# arr off\n" ++ + "#endif\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "#if __GLASGOW_HASKELL__ < 503\n" ++ + "quickIndex arr i = arr ! i\n" ++ + "#else\n" ++ + "-- GHC >= 503, unsafeAt is available from Data.Array.Base.\n" ++ + "quickIndex = unsafeAt\n" ++ + "#endif\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- Main lexing routines\n" ++ + "\n" ++ + "data AlexReturn a\n" ++ + " = AlexEOF\n" ++ + " | AlexError !AlexInput\n" ++ + " | AlexSkip !AlexInput !Int\n" ++ + " | AlexToken !AlexInput !Int a\n" ++ + "\n" ++ + "-- alexScan :: AlexInput -> StartCode -> AlexReturn a\n" ++ + "alexScan input (I# (sc))\n" ++ + " = alexScanUser undefined input (I# (sc))\n" ++ + "\n" ++ + "alexScanUser user input (I# (sc))\n" ++ + " = case alex_scan_tkn user input 0# input sc AlexNone of\n" ++ + "\t(AlexNone, input') ->\n" ++ + "\t\tcase alexGetChar input of\n" ++ + "\t\t\tNothing -> \n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\t\t\t AlexEOF\n" ++ + "\t\t\tJust _ ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\t\t\t AlexError input'\n" ++ + "\n" ++ + "\t(AlexLastSkip input'' len, _) ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\tAlexSkip input'' len\n" ++ + "\n" ++ + "\t(AlexLastAcc k input''' len, _) ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\tAlexToken input''' len k\n" ++ + "\n" ++ + "\n" ++ + "-- Push the input through the DFA, remembering the most recent accepting\n" ++ + "-- state it encountered.\n" ++ + "\n" ++ + "alex_scan_tkn user orig_input len input s last_acc =\n" ++ + " input `seq` -- strict in the input\n" ++ + " let \n" ++ + "\tnew_acc = check_accs (alex_accept `quickIndex` (I# (s)))\n" ++ + " in\n" ++ + " new_acc `seq`\n" ++ + " case alexGetChar input of\n" ++ + " Nothing -> (new_acc, input)\n" ++ + " Just (c, new_input) -> \n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\tlet\n" ++ + "\t\t!(base) = alexIndexInt32OffAddr alex_base s\n" ++ + "\t\t!((I# (ord_c))) = ord c\n" ++ + "\t\t!(offset) = (base +# ord_c)\n" ++ + "\t\t!(check) = alexIndexInt16OffAddr alex_check offset\n" ++ + "\t\t\n" ++ + "\t\t!(new_s) = if (offset >=# 0#) && (check ==# ord_c)\n" ++ + "\t\t\t then alexIndexInt16OffAddr alex_table offset\n" ++ + "\t\t\t else alexIndexInt16OffAddr alex_deflt s\n" ++ + "\tin\n" ++ + "\tcase new_s of \n" ++ + "\t -1# -> (new_acc, input)\n" ++ + "\t\t-- on an error, we want to keep the input *before* the\n" ++ + "\t\t-- character that failed, not after.\n" ++ + " \t _ -> alex_scan_tkn user orig_input (len +# 1#) \n" ++ + "\t\t\tnew_input new_s new_acc\n" ++ + "\n" ++ + " where\n" ++ + "\tcheck_accs [] = last_acc\n" ++ + "\tcheck_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))\n" ++ + "\tcheck_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))\n" ++ + "\tcheck_accs (AlexAccPred a predx : rest)\n" ++ + "\t | predx user orig_input (I# (len)) input\n" ++ + "\t = AlexLastAcc a input (I# (len))\n" ++ + "\tcheck_accs (AlexAccSkipPred predx : rest)\n" ++ + "\t | predx user orig_input (I# (len)) input\n" ++ + "\t = AlexLastSkip input (I# (len))\n" ++ + "\tcheck_accs (_ : rest) = check_accs rest\n" ++ + "\n" ++ + "data AlexLastAcc a\n" ++ + " = AlexNone\n" ++ + " | AlexLastAcc a !AlexInput !Int\n" ++ + " | AlexLastSkip !AlexInput !Int\n" ++ + "\n" ++ + "data AlexAcc a user\n" ++ + " = AlexAcc a\n" ++ + " | AlexAccSkip\n" ++ + " | AlexAccPred a (AlexAccPred user)\n" ++ + " | AlexAccSkipPred (AlexAccPred user)\n" ++ + "\n" ++ + "type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- Predicates on a rule\n" ++ + "\n" ++ + "alexAndPred p1 p2 user in1 len in2\n" ++ + " = p1 user in1 len in2 && p2 user in1 len in2\n" ++ + "\n" ++ + "--alexPrevCharIsPred :: Char -> AlexAccPred _ \n" ++ + "alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input\n" ++ + "\n" ++ + "--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ \n" ++ + "alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input\n" ++ + "\n" ++ + "--alexRightContext :: Int -> AlexAccPred _\n" ++ + "alexRightContext (I# (sc)) user _ _ input = \n" ++ + " case alex_scan_tkn user input 0# input sc AlexNone of\n" ++ + "\t (AlexNone, _) -> False\n" ++ + "\t _ -> True\n" ++ + "\t-- TODO: there's no need to find the longest\n" ++ + "\t-- match when checking the right context, just\n" ++ + "\t-- the first match will do.\n" ++ + "\n" ++ + "-- used by wrappers\n" ++ + "iUnbox (I# (i)) = i"++alexTemplate _ =+ "{-# LINE 1 \"templates\\GenericTemplate.hs\" #-}\n" ++ + "{-# LINE 1 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "{-# LINE 1 \"<built-in>\" #-}\n" ++ + "{-# LINE 1 \"<command line>\" #-}\n" ++ + "{-# LINE 1 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- ALEX TEMPLATE\n" ++ + "--\n" ++ + "-- This code is in the PUBLIC DOMAIN; you may copy it freely and use\n" ++ + "-- it for any purpose whatsoever.\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- INTERNALS and main scanner engine\n" ++ + "\n" ++ + "{-# LINE 37 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "\n" ++ + "{-# LINE 47 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "\n" ++ + "{-# LINE 68 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "alexIndexInt16OffAddr arr off = arr ! off\n" ++ + "\n" ++ + "\n" ++ + "{-# LINE 89 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "alexIndexInt32OffAddr arr off = arr ! off\n" ++ + "\n" ++ + "\n" ++ + "{-# LINE 100 \"templates\\\\GenericTemplate.hs\" #-}\n" ++ + "quickIndex arr i = arr ! i\n" ++ + "\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- Main lexing routines\n" ++ + "\n" ++ + "data AlexReturn a\n" ++ + " = AlexEOF\n" ++ + " | AlexError !AlexInput\n" ++ + " | AlexSkip !AlexInput !Int\n" ++ + " | AlexToken !AlexInput !Int a\n" ++ + "\n" ++ + "-- alexScan :: AlexInput -> StartCode -> AlexReturn a\n" ++ + "alexScan input (sc)\n" ++ + " = alexScanUser undefined input (sc)\n" ++ + "\n" ++ + "alexScanUser user input (sc)\n" ++ + " = case alex_scan_tkn user input (0) input sc AlexNone of\n" ++ + "\t(AlexNone, input') ->\n" ++ + "\t\tcase alexGetChar input of\n" ++ + "\t\t\tNothing -> \n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\t\t\t AlexEOF\n" ++ + "\t\t\tJust _ ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\t\t\t AlexError input'\n" ++ + "\n" ++ + "\t(AlexLastSkip input'' len, _) ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\tAlexSkip input'' len\n" ++ + "\n" ++ + "\t(AlexLastAcc k input''' len, _) ->\n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\t\tAlexToken input''' len k\n" ++ + "\n" ++ + "\n" ++ + "-- Push the input through the DFA, remembering the most recent accepting\n" ++ + "-- state it encountered.\n" ++ + "\n" ++ + "alex_scan_tkn user orig_input len input s last_acc =\n" ++ + " input `seq` -- strict in the input\n" ++ + " let \n" ++ + "\tnew_acc = check_accs (alex_accept `quickIndex` (s))\n" ++ + " in\n" ++ + " new_acc `seq`\n" ++ + " case alexGetChar input of\n" ++ + " Nothing -> (new_acc, input)\n" ++ + " Just (c, new_input) -> \n" ++ + "\n" ++ + "\n" ++ + "\n" ++ + "\tlet\n" ++ + "\t\t(base) = alexIndexInt32OffAddr alex_base s\n" ++ + "\t\t((ord_c)) = ord c\n" ++ + "\t\t(offset) = (base + ord_c)\n" ++ + "\t\t(check) = alexIndexInt16OffAddr alex_check offset\n" ++ + "\t\t\n" ++ + "\t\t(new_s) = if (offset >= (0)) && (check == ord_c)\n" ++ + "\t\t\t then alexIndexInt16OffAddr alex_table offset\n" ++ + "\t\t\t else alexIndexInt16OffAddr alex_deflt s\n" ++ + "\tin\n" ++ + "\tcase new_s + 1 of \n" ++ + "\t (0) -> (new_acc, input)\n" ++ + "\t\t-- on an error, we want to keep the input *before* the\n" ++ + "\t\t-- character that failed, not after.\n" ++ + " \t _ -> alex_scan_tkn user orig_input (len + (1)) \n" ++ + "\t\t\tnew_input new_s new_acc\n" ++ + "\n" ++ + " where\n" ++ + "\tcheck_accs [] = last_acc\n" ++ + "\tcheck_accs (AlexAcc a : _) = AlexLastAcc a input (len)\n" ++ + "\tcheck_accs (AlexAccSkip : _) = AlexLastSkip input (len)\n" ++ + "\tcheck_accs (AlexAccPred a predx : rest)\n" ++ + "\t | predx user orig_input (len) input\n" ++ + "\t = AlexLastAcc a input (len)\n" ++ + "\tcheck_accs (AlexAccSkipPred predx : rest)\n" ++ + "\t | predx user orig_input (len) input\n" ++ + "\t = AlexLastSkip input (len)\n" ++ + "\tcheck_accs (_ : rest) = check_accs rest\n" ++ + "\n" ++ + "data AlexLastAcc a\n" ++ + " = AlexNone\n" ++ + " | AlexLastAcc a !AlexInput !Int\n" ++ + " | AlexLastSkip !AlexInput !Int\n" ++ + "\n" ++ + "data AlexAcc a user\n" ++ + " = AlexAcc a\n" ++ + " | AlexAccSkip\n" ++ + " | AlexAccPred a (AlexAccPred user)\n" ++ + " | AlexAccSkipPred (AlexAccPred user)\n" ++ + "\n" ++ + "type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool\n" ++ + "\n" ++ + "-- -----------------------------------------------------------------------------\n" ++ + "-- Predicates on a rule\n" ++ + "\n" ++ + "alexAndPred p1 p2 user in1 len in2\n" ++ + " = p1 user in1 len in2 && p2 user in1 len in2\n" ++ + "\n" ++ + "--alexPrevCharIsPred :: Char -> AlexAccPred _ \n" ++ + "alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input\n" ++ + "\n" ++ + "--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ \n" ++ + "alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input\n" ++ + "\n" ++ + "--alexRightContext :: Int -> AlexAccPred _\n" ++ + "alexRightContext (sc) user _ _ input = \n" ++ + " case alex_scan_tkn user input (0) input sc AlexNone of\n" ++ + "\t (AlexNone, _) -> False\n" ++ + "\t _ -> True\n" ++ + "\t-- TODO: there's no need to find the longest\n" ++ + "\t-- match when checking the right context, just\n" ++ + "\t-- the first match will do.\n" ++ + "\n" ++ + "-- used by wrappers\n" ++ + "iUnbox (i) = i"+
+ src/Util.hs view
@@ -0,0 +1,47 @@+-- -----------------------------------------------------------------------------+-- +-- Util.hs, part of Alex+--+-- (c) Simon Marlow 2003+--+-- General utilities used in various parts of Alex+--+-- ----------------------------------------------------------------------------}++module Util where++-- Pretty-printing utilities++str :: String -> String -> String+str = showString+char :: Char -> String -> String+char c = (c :)++nl :: String -> String+nl = char '\n'++paren :: (String -> String) -> String -> String+paren s = char '(' . s . char ')'++brack :: (String -> String) -> String -> String+brack s = char '[' . s . char ']'++interleave_shows :: (String -> String) -> [String -> String] -> String -> String+interleave_shows _ [] = id+interleave_shows s xs = foldr1 (\a b -> a . s . b) xs++space :: String -> String+space = char ' '++cjustify, ljustify, rjustify :: Int -> String -> String+cjustify n s = spaces halfm ++ s ++ spaces (m - halfm)+ where m = n - length s+ halfm = m `div` 2+ljustify n s = s ++ spaces (max 0 (n - length s))+rjustify n s = spaces (n - length s) ++ s++spaces :: Int -> String+spaces n = replicate n ' '++hline :: String+hline = replicate 77 '-'