HXQ 0.8 → 0.8.3
raw patch · 23 files changed
+1757/−773 lines, 23 filesdep +HDBCdep +HDBC-sqlite3dep +mtlPVP ok
version bump matches the API change (PVP)
Dependencies added: HDBC, HDBC-sqlite3, mtl
API changes (from Hackage documentation)
+ XML.HXQ.XQuery: XNoPad :: XTree
+ XML.HXQ.XQuery: XStmt :: Statement -> XTree
+ XML.HXQ.XQuery: connect :: FilePath -> IO Connection
+ XML.HXQ.XQuery: createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
+ XML.HXQ.XQuery: disconnect :: (IConnection conn) => conn -> IO ()
+ XML.HXQ.XQuery: executeSQL :: Statement -> XSeq -> IO XSeq
+ XML.HXQ.XQuery: prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
+ XML.HXQ.XQuery: shred :: (IConnection conn) => conn -> String -> String -> IO ()
+ XML.HXQ.XQuery: xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
+ XML.HXQ.XQuery: xqdb :: String -> Q Exp
+ XML.HXQ.XQuery: xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
Files
- HXQ-unstable.hs +94/−0
- HXQ.cabal +8/−9
- HXQ.hs +0/−94
- Main.hs +38/−14
- Makefile +11/−13
- Test1.hs +5/−6
- Test2.hs +3/−3
- TestDB.hs +6/−8
- XML/HXQ/Compiler.hs +114/−45
- XML/HXQ/DB.hs +369/−2
- XML/HXQ/DBConnect.hs +26/−0
- XML/HXQ/Interpreter.hs +85/−28
- XML/HXQ/Optimizer.hs +323/−27
- XML/HXQ/Parser.hs +380/−307
- XML/HXQ/XQuery.hs +13/−3
- XML/HXQ/XQueryDB.hs +0/−38
- XML/HXQ/XTree.hs +23/−11
- XQueryParser.y +162/−115
- data/q1.xq +2/−2
- data/q3.xq +8/−0
- hxml-0.2/XMLScanner.hs +2/−1
- index.html +85/−27
- profile.hs +0/−20
+ HXQ-unstable.hs view
@@ -0,0 +1,94 @@+{--------------------------------------------------------------+-+- The main program of the XQuery Compiler+- **** UNSTABLE *****+- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)+- Date: 05/02/2008+-+---------------------------------------------------------------}++module Main where++import GHC+import DynFlags+import Packages+import PackageConfig+import System.IO+import XML.HXQ.XQuery+import System.Environment+import qualified Control.Exception+import XML.HXQ.Compiler(functions)+import XML.HXQ.Interpreter(evalInput)+++version = "0.8.3"+default_system_path = "/usr/local/lib/ghc-6.8.2"+default_hxq_path = "./"+++parseEnv :: [String] -> [(String,String)]+parseEnv [] = [("hxq",default_hxq_path),("ghc",default_system_path),("o","Temp.hs")]+parseEnv ("-help":xs) = ("help",""):(parseEnv xs)+parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs)+parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)+parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs)+parseEnv ("-h":path:xs) = ("hxq",path):(parseEnv xs)+parseEnv ("-l":path:xs) = ("ghc",path):(parseEnv xs)+parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.")+parseEnv (file:xs) = ("r",file):(parseEnv xs)+++main = do putStrLn ("HXQ: XQuery Compiler version "++version)+ senv <- getArgs+ let env = parseEnv senv+ Just system_path = lookup "ghc" env+ Just hxq_path = lookup "hxq" env+ case lookup "help" env of+ Just _ -> do putStrLn "Command line options and files:"+ putStrLn "xquery-file compile and run the XQuery in xquery-file"+ putStrLn "-c xquery-file compile the XQuery in xquery-file into Haskell code"+ putStrLn "-o haskell-file set the Haskell file for -c (default is Temp.hs)"+ putStrLn "-p XPath-query xml-file compile and run the XPath query against the xml-file"+ putStrLn ("-h path set the HXQ installation directory (default is "++default_hxq_path++")")+ putStrLn ("-l path set the GHC installation directory (default is "++default_system_path++")")+ putStrLn ("Functions: "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))+ _ -> case lookup "c" env of+ Just file -> do query <- readFile file+ let qf = map (\c -> if c=='\"' then '\'' else c)+ (foldr1 (\a r -> a++" "++r) (lines query))+ pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""+ ++ qf ++ "\")\n putXSeq res\n"+ Just ofile = lookup "o" env+ writeFile ofile pr+ _ -> do session <- newSession (Just system_path)+ dflags0 <- getSessionDynFlags session+ (dflags1,b) <- parseDynamicFlags dflags0 ["-fglasgow-exts", "-O2", "-fth", "-fobject-code",+ --"-package HXQ", "-package ghc"]+ "-i"++hxq_path++"XML/HXQ/:"++hxq_path++"hxml-0.2"]+ (dflags2, _) <- initPackages dflags1+ setSessionDynFlags session dflags2+ --load session LoadAllTargets+ let preludeModule = mkModule (stringToPackageId "base") (mkModuleName "Prelude")+ --xqueryModule = mkModule (stringToPackageId "HXQ") (mkModuleName "XQuery")+ setContext session [] [preludeModule]+ t <- guessTarget (hxq_path++"Main.hs") Nothing+ addTarget session t+ f <- getSessionDynFlags session+ sf <- defaultCleanupHandler f (load session LoadAllTargets)+ --ff <- load session (LoadDependenciesOf (mkModuleName "XQuery"))+ case lookup "r" env of+ Just file -> do q <- readFile file+ let qf = map (\c -> if c=='\"' then '\'' else c)+ (foldr1 (\a r -> a++" "++r) (lines q))+ query = "do result <- $(XQuery.xq \""++qf++"\"); XQuery.putXSeq result"+ _ <- runStmt session query SingleStep+ return ()+ _ -> case lookup "p" env of+ Just query -> do _ <- runStmt session ("do result <- $(XML.HXQ.XQuery.xq \""++query+ ++"\"); XML.HXQ.XQuery.putXSeq result") SingleStep+ return ()+ _ -> do putStrLn "To write an XQuery in multiple lines, wrap it in {}"+ evalInput (\s vs fs -> let query = "do result <- $(XML.HXQ.XQuery.xq \""++s++"\");"+ ++"XML.HXQ.XQuery.putXSeq result"+ in Control.Exception.catch (do runStmt session query SingleStep; return (vs,fs))+ (\e -> do putStrLn (show e); return (vs,fs))) [] []
HXQ.cabal view
@@ -1,12 +1,12 @@ Cabal-Version: >= 1.2 Name: HXQ-Version: 0.8+Version: 0.8.3 Synopsis: A Compiler from XQuery to Haskell Description: HXQ is a fast and space-efficient compiler from XQuery (the standard query language for XML) to embedded Haskell code. The translation is based on Haskell templates. It also provides an interpreter for- evaluating ad-hoc XQueries read from input or from files.+ evaluating XQueries from input and database connectivity using HDBC. Category: XML Build-type: Simple License-file: LICENSE@@ -18,20 +18,18 @@ Homepage: http://lambda.uta.edu/HXQ/ Extra-Source-Files: Makefile- HXQ.hs- XML/HXQ/DB.hs- XML/HXQ/XQueryDB.hs+ HXQ-unstable.hs XQueryParser.y Test1.hs Test2.hs TestDB.hs- profile.hs compile data-files: index.html data/cs.xml data/q1.xq data/q2.xq+ data/q3.xq data/dblp.xq data/dblp2.xq data/company.sql@@ -40,13 +38,14 @@ Library Exposed-Modules: XML.HXQ.XQuery- Other-Modules: XML.HXQ.XTree, XML.HXQ.Compiler, XML.HXQ.Interpreter, XML.HXQ.Parser, XML.HXQ.Optimizer,+ Other-Modules: XML.HXQ.XTree, XML.HXQ.Compiler, XML.HXQ.Interpreter, XML.HXQ.Parser,+ XML.HXQ.Optimizer, XML.HXQ.DB, XML.HXQ.DBConnect, HXML, DTD, LLParsing, TreeBuild, XMLParse, ETree, Misc, Tree, XMLScanner, AssocList, PrintXML, XML hs-source-dirs: . hxml-0.2- Build-Depends: base, haskell98, array, readline, template-haskell+ Build-Depends: base, haskell98, array, readline, template-haskell, mtl, HDBC, HDBC-sqlite3 Executable xquery Main-is: Main.hs hs-source-dirs: . hxml-0.2- Build-Depends: base, haskell98, array, readline, template-haskell+ Build-Depends: base, haskell98, array, readline, template-haskell, mtl, HDBC, HDBC-sqlite3
− HXQ.hs
@@ -1,94 +0,0 @@-{------------------------------------------------------------------ The main program of the XQuery Compiler-- **** UNSTABLE *****-- Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)-- Date: 05/02/2008------------------------------------------------------------------}--module Main where--import GHC-import DynFlags-import Packages-import PackageConfig-import System.IO-import XML.HXQ.XQuery-import System.Environment-import qualified Control.Exception-import XML.HXQ.Compiler(functions)-import XML.HXQ.Interpreter(evalInput)---version = "0.8"-default_system_path = "/usr/local/lib/ghc-6.8.2"-default_hxq_path = "./"---parseEnv :: [String] -> [(String,String)]-parseEnv [] = [("hxq",default_hxq_path),("ghc",default_system_path),("o","Temp.hs")]-parseEnv ("-help":xs) = ("help",""):(parseEnv xs)-parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs)-parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)-parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs)-parseEnv ("-h":path:xs) = ("hxq",path):(parseEnv xs)-parseEnv ("-l":path:xs) = ("ghc",path):(parseEnv xs)-parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.")-parseEnv (file:xs) = ("r",file):(parseEnv xs)---main = do putStrLn ("HXQ: XQuery Compiler version "++version)- senv <- getArgs- let env = parseEnv senv- Just system_path = lookup "ghc" env- Just hxq_path = lookup "hxq" env- case lookup "help" env of- Just _ -> do putStrLn "Command line options and files:"- putStrLn "xquery-file compile and run the XQuery in xquery-file"- putStrLn "-c xquery-file compile the XQuery in xquery-file into Haskell code"- putStrLn "-o haskell-file set the Haskell file for -c (default is Temp.hs)"- putStrLn "-p XPath-query xml-file compile and run the XPath query against the xml-file"- putStrLn ("-h path set the HXQ installation directory (default is "++default_hxq_path++")")- putStrLn ("-l path set the GHC installation directory (default is "++default_system_path++")")- putStrLn ("Functions: "++(foldr (\(f,_,_) r -> f++" "++r) "" functions))- _ -> case lookup "c" env of- Just file -> do query <- readFile file- let qf = map (\c -> if c=='\"' then '\'' else c)- (foldr1 (\a r -> a++" "++r) (lines query))- pr = "{-# OPTIONS_GHC -fth #-}\nmodule Main where\nimport XML.HXQ.XQuery\n\nmain = do res <- $(xq \""- ++ qf ++ "\")\n putXSeq res\n"- Just ofile = lookup "o" env- writeFile ofile pr- _ -> do session <- newSession (Just system_path)- dflags0 <- getSessionDynFlags session- (dflags1,b) <- parseDynamicFlags dflags0 ["-fglasgow-exts", "-O2", "-fth", "-fobject-code",- --"-package HXQ", "-package ghc"]- "-i"++hxq_path++"XML/HXQ/:"++hxq_path++"hxml-0.2"]- (dflags2, _) <- initPackages dflags1- setSessionDynFlags session dflags2- --load session LoadAllTargets- let preludeModule = mkModule (stringToPackageId "base") (mkModuleName "Prelude")- --xqueryModule = mkModule (stringToPackageId "HXQ") (mkModuleName "XQuery")- setContext session [] [preludeModule]- t <- guessTarget (hxq_path++"Main.hs") Nothing- addTarget session t- f <- getSessionDynFlags session- sf <- defaultCleanupHandler f (load session LoadAllTargets)- --ff <- load session (LoadDependenciesOf (mkModuleName "XQuery"))- case lookup "r" env of- Just file -> do q <- readFile file- let qf = map (\c -> if c=='\"' then '\'' else c)- (foldr1 (\a r -> a++" "++r) (lines q))- query = "do result <- $(XQuery.xq \""++qf++"\"); XQuery.putXSeq result"- _ <- runStmt session query SingleStep- return ()- _ -> case lookup "p" env of- Just query -> do _ <- runStmt session ("do result <- $(XML.HXQ.XQuery.xq \""++query- ++"\"); XML.HXQ.XQuery.putXSeq result") SingleStep- return ()- _ -> do putStrLn "To write an XQuery in multiple lines, wrap it in {}"- evalInput (\s vs fs -> let query = "do result <- $(XML.HXQ.XQuery.xq \""++s++"\");"- ++"XML.HXQ.XQuery.putXSeq result"- in Control.Exception.catch (do runStmt session query SingleStep; return (vs,fs))- (\e -> do putStrLn (show e); return (vs,fs))) [] []
Main.hs view
@@ -2,11 +2,10 @@ - - The main program of the XQuery interpreter - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)-- Date: 05/02/2008+- Date: 06/10/2008 - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-} module Main where @@ -16,7 +15,7 @@ import XML.HXQ.Interpreter(evalInput,xqueryE) import XML.HXQ.XQuery -version = "0.8"+version = "0.8.3" parseEnv :: [String] -> [(String,String)]@@ -24,24 +23,29 @@ parseEnv ("-help":xs) = ("help",""):(parseEnv xs) parseEnv ("-c":file:xs) = ("c",file):(parseEnv xs) parseEnv ("-o":file:xs) = ("o",file):(parseEnv xs)+parseEnv ("-db":file:xs) = ("db",file):(parseEnv xs)+parseEnv ("-v":xs) = ("v",""):(parseEnv xs) parseEnv ("-p":query:file:xs) = ("p","doc('"++file++"')"++query):(parseEnv xs) parseEnv (('-':x):_) = error ("Unrecognized option -"++x++". Use -help.") parseEnv (file:xs) = ("r",file):(parseEnv xs) -main = do putStrLn ("HXQ: XQuery Interpreter version "++version++". Use -help for help.")- senv <- getArgs+main = do senv <- getArgs let env = parseEnv senv Just system_path = lookup "ghc" env Just hxq_path = lookup "hxq" env+ Just dbname = lookup "db" env+ verbose = case lookup "v" env of Nothing -> False; _ -> True case lookup "help" env of Just _ -> do putStrLn "Command line options and files:" putStrLn " xquery-file interpret the XQuery in xquery-file"+ putStrLn " -db file-path use the relational database in file-path during querying" putStrLn " -c xquery-file compile the XQuery in xquery-file into Haskell code" putStrLn " -o haskell-file set the Haskell file for -c (default is Temp.hs)" putStrLn " -p XPath-query xml-file interpret the XPath query against the xml-file"- putStrLn "Without options, it reads and interprets the input:"- putStrLn " The input may be an XQuery or a declare variable or function"+ putStrLn " -v verbose information"+ putStrLn "Without an xquery-file, it reads and interprets the input"+ putStrLn " The input may be an XQuery or a declare variable/function" putStrLn " To write an XQuery in multiple lines, wrap it in {}" putStrLn ("Functions: "++(foldr (\(f,_,_) r -> f++" "++r) "" functions)) _ -> case lookup "c" env of@@ -53,12 +57,32 @@ Just ofile = lookup "o" env writeFile ofile pr _ -> case lookup "r" env of- Just file -> do result <- xfile file- putXSeq result+ Just file -> case lookup "db" env of+ Just filepath -> do db <- connect filepath+ result <- xfileDB file db+ disconnect db+ putXSeq result+ _ -> do query <- readFile file+ (result,_,_) <- xqueryE query [] [] (\sql -> return []) verbose+ putXSeq result _ -> case lookup "p" env of- Just query -> do result <- xquery query+ Just query -> do (result,_,_) <- xqueryE query [] [] (\sql -> return []) verbose putXSeq result- _ -> evalInput (\s vs fs-> Control.Exception.catch (do (result,nvs,nfs) <- xqueryE s vs fs- putXSeq result- return (nvs,nfs))- (\e -> do putStrLn (show e); return (vs,fs))) [] []+ _ -> do putStrLn ("HXQ: XQuery Interpreter version "++version++". Use -help for help.")+ case lookup "db" env of+ Just filepath+ -> do db <- connect filepath+ evalInput (\s vs fs-> Control.Exception.catch+ (do (result,nvs,nfs) <- xqueryE s vs fs+ (\sql -> do stmt <- prepareSQL db sql+ return [XStmt stmt]) verbose+ putXSeq result+ return (nvs,nfs))+ (\e -> do putStrLn (show e); return (vs,fs))) [] []+ disconnect db+ _ -> evalInput (\s vs fs-> Control.Exception.catch+ (do (result,nvs,nfs) <- xqueryE s vs fs+ (\_ -> error "Missing Database Connection") verbose+ putXSeq result+ return (nvs,nfs))+ (\e -> do putStrLn (show e); return (vs,fs))) [] []
Makefile view
@@ -1,6 +1,6 @@ hxml = hxml-0.2 hxq = XML/HXQ-options = -O2 -fvia-C+options = -O2 parser = $(hxq)/Parser.hs # xquery interpreter@@ -8,8 +8,8 @@ ghc $(options) -i$(hxml) --make Main.hs -o xquery # on-the-fly compiler: unstable; use xquery instead-hxqc: $(parser) HXQ.hs- ghc $(options) -i$(hxml) -optl-s -package ghc --make HXQ.hs -o hxqc+hxqc: $(parser) HXQ-unstable.hs+ ghc $(options) -i$(hxml) -optl-s -package ghc --make HXQ-unstable.hs -o hxqc # generate the XQuery parser using happy $(parser): XQueryParser.y@@ -23,25 +23,23 @@ ghc $(options) -i$(hxml) --make Test2.hs -o a.out time ./a.out +RTS -H20m -testdb: $(parser) TestDB.hs+test3: $(parser) TestDB.hs ghc $(options) -i$(hxml) --make TestDB.hs -o a.out ./a.out -# get in the ghci interpreter and load HXQ+test4: $(parser) TestDB2.hs+ ghc $(options) -i$(hxml) --make TestDB2.hs -o a.out+ ./a.out++# run in the ghci interpreter and load HXQ ghci: $(parser) ghci -fth -i$(hxml) Main.hs -# heap profile of a simple XQuery against dblp.xml-profile: $(parser) profile.hs- ghc -O2 -i$(hxml) -prof -auto-all --make profile.hs -o a- ./a +RTS -hy -p -H20m- hp2ps -color a.hp- # create the cabal distribution-cabal: clean $(parser)+cabal: $(parser) runhaskell Setup.lhs configure --ghc --user --prefix=$(HOME) runhaskell Setup.lhs build runhaskell Setup.lhs sdist clean:- /bin/rm -f *~ data/*~ $(hxq)/*~ *.o *.hi $(hxq)/*.o $(hxq)/*.hi $(hxml)/*.o $(hxml)/*.hi $(parser) *.stat *.prof *.ps *.aux *.hp xquery hxqc Temp.hs a.out a+ /bin/rm -f *~ data/*~ $(hxq)/*~ *.o *.hi $(hxq)/*.o $(hxq)/*.hi $(hxml)/*.o $(hxml)/*.hi $(parser) xquery hxqc Temp.hs a.out
Test1.hs view
@@ -13,12 +13,12 @@ import XML.HXQ.XQuery -f(d,s) = $(xe "<student dept='{$d/text()}'>{$s//firstname/text(),' ',$s//lastname/text()}</student>")+f(d,s) = $(xe "<student dept='{$d/text()}'>{$s//firstname/text(),$s//lastname/text()}</student>") main = do a <- $(xq (" for $s in doc('data/cs.xml')//gradstudent " ++" order by $s/gpa descending, $s//lastname "- ++" return <student>{$s//firstname/text(),' ', "- ++" $s//lastname/text(),' ', "+ ++" return <student>{$s//firstname/text(), "+ ++" $s//lastname/text(), " ++" $s/gpa/text()}</student> ")) putXSeq a let query name = $(xq " doc('data/cs.xml')//gradstudent[.//lastname = $name]//firstname ")@@ -31,9 +31,8 @@ ++" return f($d//deptname,$s) " ++" }</good-students> ")) putXSeq c- let q file = $(xq (" let $d := doc($file)//gradstudent "- ++" return ($d/../deptname,count($d)) "))- d <- q $(xe " 'data/cs.xml' ")+ d <- $(xq (" let $d := doc('data/cs.xml')//gradstudent "+ ++" return ($d/../deptname,count($d)) ")) putXSeq d putStrLn "Type an XQuery:" iquery <- getLine -- read an XQuery from input
Test2.hs view
@@ -14,14 +14,14 @@ import XML.HXQ.XQuery -f(x,y) = $(xe "<a>{$x,', ',$y}</a>")+f(x,y) = $(xe "<a>{$x,$y}</a>") main = do a <- $(xq ("<result>{ " ++" for $x at $i in doc('data/dblp.xml')//inproceedings " ++" where $x/author = 'Leonidas Fegaras' " ++" order by $x/year descending "- ++" return <paper>{ $i, ') ', $x/booktitle/text(), "- ++" ': ', $x/title/text() "+ ++" return <paper>{ $i, $x/booktitle/text(), "+ ++" ':', $x/title/text() " ++" }</paper> " ++" }</result> ")) putXSeq a
TestDB.hs view
@@ -1,10 +1,10 @@ {-------------------------------------------------------------- --- A main program to test XQuery with Sqlite database connectivity+- A main program to test XQuery connected to a Sqlite database - To create the database load the file data/company.sql in sqlite3 - - Programmer: Leonidas Fegaras (fegaras@cse.uta.edu)-- Date: 05/12/2008+- Date: 05/21/2008 - ---------------------------------------------------------------} @@ -12,17 +12,15 @@ module Main where -import XML.HXQ.XQueryDB-import Database.HDBC.Sqlite3+import XML.HXQ.XQuery -main = do db <- connectSqlite3 "myDB"- e <- $(xqdb (" let $ln := 'English' "- ++" for $r in sql(' select e.fname, d.dname "+main = do db <- connect "myDB"+ e <- $(xqdb (" for $r in sql(' select e.fname, d.dname " ++" from employee e, department d " ++" where e.dno = d.dnumber " ++" and e.lname = ? ', "- ++" $ln) "+ ++" 'English') " ++" return <result>{$r/fname,$r/dname}</result> ")) db putXSeq e disconnect db
XML/HXQ/Compiler.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 02/15/08, last update: 05/12/08+- Creation: 02/15/08, last update: 06/02/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -20,26 +20,36 @@ import Data.List import Control.Monad-import Char(isDigit)+import Char(isDigit,toLower) import List(sortBy) import Language.Haskell.TH+import Database.HDBC import XMLParse(parseDocument) import HXML(AttList) import XML.HXQ.Parser import XML.HXQ.XTree import XML.HXQ.Optimizer+import XML.HXQ.DB+import XML.HXQ.DBConnect {--------------- XPath Steps ---------------------------------------------------------} +current_step :: Tag -> XTree -> XSeq+current_step m x+ = case x of+ XElem k _ _ _ | (k==m || m=="*") -> [x]+ _ -> []++ -- XPath step /tag or /* child_step :: Tag -> XTree -> XSeq child_step m x = case x of- (XElem _ _ _ bs)+ XElem _ _ _ bs -> foldr (\b s -> case b of- (XElem k _ _ _) | (k==m || m=="*") -> b:s+ XElem k _ _ _ | (k==m || m=="*") -> b:s _ -> s) [] bs _ -> [] @@ -108,8 +118,11 @@ foldir c n [] i = n foldir c n (x:xs) i = c x i (foldir c n xs (i+1)) + trueXT = XBool True+falseXT = XBool False + readNum :: String -> Maybe XTree readNum cs = case span isDigit cs of (n,[]) -> Just (XInt (read n))@@ -118,18 +131,18 @@ _ -> Nothing _ -> Nothing + text :: XSeq -> XSeq text xs = foldr (\x r -> case x of- XElem _ _ _ [z@(XText _)] -> z:r- XElem _ _ _ [z@(XInt _)] -> z:r- XElem _ _ _ [z@(XFloat _)] -> z:r- XElem _ _ _ [z@(XBool _)] -> z:r+ XElem _ _ _ zs -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;+ XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r XText _ -> x:r XInt _ -> x:r XFloat _ -> x:r XBool _ -> x:r _ -> r) [] xs + toString :: XSeq -> [String] toString xs = map (\x -> case x of XText t -> t@@ -138,6 +151,14 @@ XBool n -> show n) (text xs) ++-- concatenate text with no padding (for element content)+appendText :: [XSeq] -> XSeq+appendText [] = []+appendText [x] = x+appendText (x:xs) = x++[XNoPad]++appendText xs++ toNum :: XSeq -> XSeq toNum xs = foldr (\x r -> case x of XInt n -> x:r@@ -147,6 +168,7 @@ _ -> r _ -> r) [] (text xs) + toFloat :: XTree -> Float toFloat (XText s) = case readNum s of Just (XInt n) -> fromIntegral n@@ -156,23 +178,31 @@ toFloat (XFloat n) = n toFloat x = error("Cannot convert to a float: "++(show x)) + mean :: (Fractional t) => [t] -> t mean = uncurry (/) . foldl' (\(!s, !n) x -> (s+x, n+1)) (0,0.0) + contains :: String -> String -> Bool-contains xs ys | ((take (length ys) xs) == ys) = True-contains (_:xs) ys = contains xs ys-contains [] ys = False+contains text word+ = let len = length word+ c xs | ((take len xs) == word) = True+ c (_:xs) = c xs+ c _ = False+ in c text + distinct :: Eq a => [a] -> [a] distinct = foldl (\r a -> if elem a r then r else r++[a]) [] + arithmetic :: (Float -> Float -> Float) -> XTree -> XTree -> XTree arithmetic op (XInt n) (XInt m) = XInt (round (op (fromIntegral n) (fromIntegral m))) arithmetic op (XFloat n) (XFloat m) = XFloat (op n m) arithmetic op (XFloat n) (XInt m) = XFloat (op n (fromIntegral m)) arithmetic op (XInt n) (XFloat m) = XFloat (op (fromIntegral n) m) + compareXTrees :: XTree -> XTree -> Ordering compareXTrees (XElem _ _ _ _) _ = EQ compareXTrees _ (XElem _ _ _ _) = EQ@@ -183,6 +213,7 @@ compareXTrees (XText n) (XText m) = compare n m compareXTrees x y = compare (toFloat x) (toFloat y) + strictCompareOne [XInt n] [XInt m] = compare n m strictCompareOne [XFloat n] [XFloat m] = compare n m strictCompareOne [XFloat n] [XInt m] = compare n (fromIntegral m)@@ -211,6 +242,7 @@ then LT else EQ + conditionTest :: XSeq -> Bool conditionTest [] = False conditionTest [XText ""] = False@@ -221,7 +253,8 @@ -- XPath steps paths :: [(Tag,Q Exp)]-paths = [ ( "child_step", [| child_step |] ),+paths = [ ( "current_step", [| current_step |] ),+ ( "child_step", [| child_step |] ), ( "descendant_step", [| descendant_step |] ), ( "attribute_step", [| attribute_step |] ), ( "attribute_descendant_step", [| attribute_descendant_step |] )@@ -234,17 +267,19 @@ -- but here we make sure they are unfolded and fused with the rest of the query functions :: [(Tag,Int,Function)] functions = [ ( "=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] |] ),- ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ] then [trueXT] else [] |] ),+ ( "!=", 2, \[xs,ys] -> [| if null [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == EQ ]+ then [trueXT]+ else [falseXT] |] ), ( ">", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == GT ] |] ), ( "<", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y == LT ] |] ), ( ">=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [GT,EQ] ] |] ), ( "<=", 2, \[xs,ys] -> [| [ trueXT | x <- text $xs, y <- text $ys, compareXTrees x y `elem` [LT,EQ] ] |] ),- ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [] |] ),- ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [] |] ),- ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [] |] ),- ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [] |] ),- ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [] |] ),- ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [] |] ),+ ( "eq", 2, \[xs,ys] -> [| if strictCompare $xs $ys == EQ then [trueXT] else [falseXT] |] ),+ ( "neq", 2, \[xs,ys] -> [| if strictCompare $xs $ys /= EQ then [trueXT] else [falseXT] |] ),+ ( "lt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == LT then [trueXT] else [falseXT] |] ),+ ( "gt", 2, \[xs,ys] -> [| if strictCompare $xs $ys == GT then [trueXT] else [falseXT] |] ),+ ( "le", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [LT,EQ] then [trueXT] else [falseXT] |] ),+ ( "ge", 2, \[xs,ys] -> [| if strictCompare $xs $ys `elem` [GT,EQ] then [trueXT] else [falseXT] |] ), ( "<<", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _ <- $ys, ox < oy ] |] ), ( ">>", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _ <- $ys, ox > oy ] |] ), ( "is", 2, \[xs,ys] -> [| [ trueXT | XElem _ _ ox _ <- $xs, XElem _ _ oy _ <- $ys, ox == oy ] |] ),@@ -256,10 +291,10 @@ ( "mod", 2, \[xs,ys] -> [| [ XInt (mod x y) | (XInt x) <- toNum $xs, (XInt y) <- toNum $ys ] |] ), ( "uplus", 1, \[xs] -> [| [ x | x <- toNum $xs ] |] ), ( "uminus", 1, \[xs] -> [| [ case x of XInt n -> XInt (-n); XFloat n -> XFloat (-n) | x <- toNum $xs ] |] ),- ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [] |] ),- ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [] |] ),- ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [] else [trueXT] |] ),- ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [] |] ),+ ( "and", 2, \[xs,ys] -> [| if (conditionTest $xs) && (conditionTest $ys) then [trueXT] else [falseXT] |] ),+ ( "or", 2, \[xs,ys] -> [| if (conditionTest $xs) || (conditionTest $ys) then [trueXT] else [falseXT] |] ),+ ( "not", 1, \[xs] -> [| if (conditionTest $xs) then [falseXT] else [trueXT] |] ),+ ( "some", 1, \[xs] -> [| if (conditionTest $xs) then [trueXT] else [falseXT] |] ), ( "count", 1, \[xs] -> [| [ XInt (length $xs) ] |] ), ( "sum", 1, \[xs] -> [| [ XFloat (sum [ toFloat x | x <- toNum $xs ]) ] |] ), ( "avg", 1, \[xs] -> [| [ XFloat (mean [ toFloat x | x <- toNum $xs ]) ] |] ),@@ -269,7 +304,8 @@ ( "text", 1, \[xs] -> [| text $xs |] ), ( "string", 1, \[xs] -> [| text $xs |] ), ( "data", 1, \[xs] -> [| text $xs |] ),- ( "node", 1, \[xs] -> [| $xs |] ),+ ( "node", 1, \[xs] -> [| [ w | w@(XElem _ _ _ _) <- $xs ] |] ),+ ( "exists", 1, \[xs] -> [| [ XBool (not (null $xs)) ] |] ), ( "empty", 0, \[] -> [| [] |] ), ( "true", 0, \[] -> [| [trueXT] |] ), ( "false", 0, \[] -> [| [] |] ),@@ -278,8 +314,9 @@ ( "attribute", 2, \[tags,xs] -> [| [ z | tag <- toString $tags, x <- $xs, z <- attribute_step tag x ] |] ), ( "name", 1, \[xs] -> [| [ XText tag | XElem tag _ _ _ <- $xs ] |] ), ( "contains", 2, \[xs,text] -> [| [ trueXT | x <- toString $xs, t <- toString $text, contains x t ] |] ),+ ( "substring", 3, \[xs,n1,n2] -> [| [ XText (take m2 (drop (m1-1) x)) | x <- toString $xs,+ XInt m1 <- toNum $n1, XInt m2 <- toNum $n2 ] |] ), ( "concatenate", 2, \[xs,ys] -> [| $xs ++ $ys |] ),- ( "concat", 2, \[xs,ys] -> [| [ XText (showXS ($xs ++ $ys)) ] |] ), ( "distinct-values", 1, \[xs] -> [| distinct $xs |] ), ( "union", 2, \[xs,ys] -> [| distinct ($xs ++ $ys) |] ), ( "intersect", 2, \[xs,ys] -> [| filter (\x -> elem x $ys) $xs |] ),@@ -291,10 +328,11 @@ -- functions to be used by the interpreter -- when evaluated, it gives [(String,Int,[XSeq]->XSeq)] iFunctions :: Q Exp-iFunctions = foldr (\(fname,len,f) r -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]- entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),- lamE [listP (map varP vars)] (f (map varE vars))]- in [| $entry : $r |]) [| [] |] functions+iFunctions = foldr (\(fname,len,f) r+ -> let vars = map (\i -> mkName ("v_"++(show i))) [1..len]+ entry = tupE [litE (StringL fname),litE (IntegerL (toInteger len)),+ lamE [listP (map varP vars)] (f (map varE vars))]+ in [| $entry : $r |]) [| [] |] functions -- XPath steps to be used by the interpreter@@ -424,9 +462,9 @@ -> position Ast "call" [Avar "last"] -> last- Ast "step" [Ast "child_step" [tag, Avar "."]]+ Ast "child_step" [tag, Avar "."] | effective_axis /= ""- -> compile (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last ""+ -> compile (Ast effective_axis [tag, Avar "."]) context position last "" Ast "step" ((Ast "descendant_any" (body:tags)):predicates) -> let bc = compile body context position last effective_axis ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)@@ -438,12 +476,23 @@ tc = litE (stringL tag) in [| foldr (\x r -> $(compilePredicates predicates [| $(findV path_step paths) $tc x |] True)++r) [] $bc |]+ Ast "descendant_any" (body:tags)+ -> let bc = compile body context position last effective_axis+ ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)+ in [| foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] $bc |]+ Ast path_step [Astring tag,body]+ | memV path_step paths+ -> let bc = compile body context position last effective_axis+ tc = litE (stringL tag)+ in [| foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] $bc |] Ast "step" [exp] -> compile exp context position last effective_axis Ast "step" (exp:predicates) -> compilePredicates predicates (compile exp context position last effective_axis) True Ast "predicate" [condition,body] -> compilePredicates [condition] (compile body context position last effective_axis) True+ Ast "append" args+ -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |] Ast "call" ((Avar f):args) -> callF f (map (\x -> compile x context position last effective_axis) args) Ast "construction" [Astring tag,Ast "attributes" [],body]@@ -454,7 +503,7 @@ -> let alc = foldr (\(Ast "pair" [a,v]) r -> let ac = compile a context position last effective_axis vc = compile v context position last effective_axis- in [| (qName $ac,showXS (text $vc)) : $r |]) [| [] |] al+ in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al ct = compile tag context position last effective_axis bc = compile body context position last effective_axis in [| [ XElem (qName $ct) $alc 0 $bc ] |]@@ -473,7 +522,7 @@ f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| \r -> $b ++ r |]) p = maxPosition (Avar ivar) body ns = if p > 0 -- there is a top-k like restriction- then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]+ then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]] else source s = compile ns context position last effective_axis in [| foldir (\x i -> $f [x] [XInt i]) [] $s 1 |]@@ -553,9 +602,9 @@ -> [| return $position |] Ast "call" [Avar "last"] -> [| return $last |]- Ast "step" [Ast "child_step" [tag, Avar "."]]+ Ast "child_step" [tag, Avar "."] | effective_axis /= ""- -> compileM (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last ""+ -> compileM (Ast effective_axis [tag, Avar "."]) context position last "" Ast "step" ((Ast "descendant_any" (body:tags)):predicates) -> let bc = compileM body context position last effective_axis ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)@@ -571,6 +620,17 @@ foldr (\x r -> (liftM2 (++)) $(compilePredicatesM predicates [| $(findV path_step paths) $tc x |] True) r) (return []) vs |]+ Ast "descendant_any" (body:tags)+ -> let bc = compileM body context position last effective_axis+ ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)+ in [| do vs <- $bc+ return (foldr (\x r -> (descendant_any_with_tagged_children $ts x)++r) [] vs) |]+ Ast path_step [Astring tag,body]+ | memV path_step paths+ -> let bc = compileM body context position last effective_axis+ tc = litE (stringL tag)+ in [| do vs <- $bc+ return (foldr (\x r -> ($(findV path_step paths) $tc x)++r) [] vs) |] Ast "step" [exp] -> compileM exp context position last effective_axis Ast "step" (exp:predicates)@@ -582,6 +642,10 @@ Ast "executeSQL" [Avar stmt,args] -> [| do as <- $(compileM args context position last effective_axis) $(varE (mkName "executeSQL")) $(varE (mkName stmt)) as |]+ Ast "append" args+ -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args+ in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])+ [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds Ast "call" ((Avar f):args) -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])@@ -596,7 +660,7 @@ -> [| do ac <- $(compileM a context position last effective_axis) vc <- $(compileM v context position last effective_axis) s <- $r- return ((qName ac,showXS (text vc)):s) |]) [| return [] |] al+ return ((qName ac,showXS vc):s) |]) [| return [] |] al ct = compileM tag context position last effective_axis bc = compileM body context position last effective_axis in [| do a <- $alc@@ -618,7 +682,7 @@ f = lamE [varP (mkName var)] (lamE [varP (mkName ivar)] [| (liftM2 (++)) $b |]) p = maxPosition (Avar ivar) body ns = if p > 0 -- there is a top-k like restriction- then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]+ then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]] else source s = compileM ns context position last effective_axis in [| do vs <- $s@@ -647,7 +711,7 @@ -- functions that need IO interaction (document reader, DB access, etc) ioSources :: [ String ]-ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql"]+ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"] -- collect all input documents and assign them a unique number@@ -657,6 +721,10 @@ Ast "call" [Avar nm,file] | elem nm ["doc","fn:doc"] -> (Avar ("_doc"++(show count)), count+1, [("_doc"++(show count),file)])+ Ast "call" [Avar nm,sql]+ | elem nm ["sql","fn:sql"]+ -> (Ast "executeSQL" [Avar ("_sql"++(show count)),Ast "call" [Avar "empty"]], count+1,+ [("_sql"++(show count),Ast "prepareSQL" [sql])]) Ast "call" [Avar nm,sql,args] | elem nm ["sql","fn:sql"] -> (Ast "executeSQL" [Avar ("_sql"++(show count)),args], count+1,@@ -683,6 +751,7 @@ liftIOSources query = let (ast,_,ns) = pullIOSources query 0 f x = case x of+ Ast nm _ | elem nm ["attributes"] -> x Ast _ _ | noIO x -> Ast "nonIO" [x] _ -> case x of Ast "call" ((Avar nm):args)@@ -714,8 +783,8 @@ = letE [valD (varP (mkName v)) (normalB (compileAst u)) []] (compileQuery xs) compileQuery [query]- = let (ast,ns) = liftIOSources query- code = compileAstM ast+ = let (ast,ns) = liftIOSources (optimize query)+ code = compileM ast undef1 undef2 undef3 "" in foldl (\r (n,e) -> let d = lamE [varP (mkName n)] r in case e of Avar m -> [| $d $(varE (mkName m)) |]@@ -729,7 +798,7 @@ [| $code |] ns --- | Debugging: display the AST and the Haskell code of an input XQuery+-- Debugging: display the AST and the Haskell code of an input XQuery cq :: String -> IO () cq query = do putStrLn "Abstract Syntax Tree:" let ast = parse (scan query)@@ -737,9 +806,9 @@ let opt = optimize (last ast) putStrLn "Optimized AST:" putStrLn (show opt)- putStrLn "Haskell Code:"- let code = compileQuery ast- runQ code >>= putStrLn.pprint+ --putStrLn "Haskell Code:"+ --let code = compileQuery ast+ --runQ code >>= putStrLn.pprint -- | Run an XQuery expression that does not read XML documents.@@ -757,4 +826,4 @@ -- | Run an XQuery that reads XML documents and queries databases. -- When evaluated, it returns (IConnection conn) => conn -> IO XSeq. xqdb :: String -> Q Exp-xqdb query = (lamE [varP (mkName "_db")] (xq query))+xqdb query = lamE [varP (mkName "_db")] (compileQuery (parse (scan query)))
XML/HXQ/DB.hs view
@@ -1,10 +1,10 @@ {------------------------------------------------------------------------------------- --- HDBC connectivity+- Database connectivity using HDBC - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/12/08, last update: 05/12/08+- Creation: 05/12/08, last update: 06/12/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -16,8 +16,13 @@ module XML.HXQ.DB where +import Char(isSpace,toLower)+import Control.Monad.State import Database.HDBC import XML.HXQ.XTree+import XMLParse(XMLEvent(..),parseDocument)+import HXML(AttList)+import XML.HXQ.Parser sql2xml :: SqlValue -> XTree@@ -46,6 +51,8 @@ XInt n -> SqlInteger (toInteger n) XFloat n -> SqlString (show n) XBool n -> SqlBool n+ XElem n _ _ [x] -> xml2sql x+ _ -> error ("Cannot convert "++show e++" into sql") executeSQL :: Statement -> XSeq -> IO XSeq@@ -57,3 +64,363 @@ prepareSQL :: (IConnection conn) => conn -> String -> IO Statement prepareSQL db sql = handleSqlError (prepare db sql)+++{---------------------------------------------------------------------------------------+-- extract the structural summary of an XML file that contains statistics+----------------------------------------------------------------------------------------}+++-- structural summary: tag id max# hasText children+data SSnode = SSnode String !Int !Int !Int !Bool [SSnode]+ deriving (Eq,Show)+++insertSS :: String -> [SSnode] -> State Int (Int,SSnode,[SSnode])+insertSS tag ((SSnode n i j l b ts):s)+ | n == tag+ = return (i,SSnode n i j (l+1) b ts,s)+insertSS tag (x:xs)+ = do (i,t,ts) <- insertSS tag xs+ return (i,t,x:ts)+insertSS tag []+ = do count <- get+ put (count+1)+ return (count+1,SSnode tag (count+1) 1 1 False [],[])+++insSS :: String -> [SSnode] -> State Int [SSnode]+insSS tag ns = do (k,t,s) <- insertSS tag ns+ return (t:s)+++getSS :: [XMLEvent] -> [SSnode] -> State Int [SSnode]+getSS ((EmptyEvent n atts):xs) rs+ = getSS ((StartEvent n atts):(EndEvent n):xs) rs+getSS ((StartEvent n atts):xs) ((SSnode m i j l b ns):rs)+ = do (k,SSnode m' i' j' l' b' ks,ts) <- insertSS n ns+ as <- foldM (\r (a,_) -> insSS ('@':a) r) ks atts+ getSS xs (reset(SSnode m' i' j' l' b' as):(SSnode m i j l b ts):rs)+ where r (SSnode m i j _ b ts) = SSnode m i j 0 b ts+ reset (SSnode m i j l b ts) = SSnode m i j l b (map r ts)+getSS ((EndEvent n):xs) (t:(SSnode m i j l b ns):rs)+ = getSS xs ((SSnode m i j l b (set t:ns):rs))+ where s (SSnode m i j l b ts) = SSnode m i (max j l) 0 b ts+ set (SSnode m i j l b ts) = SSnode m i j l b (map s ts)+getSS ((TextEvent t):xs) ((SSnode m i j l False ns):rs)+ | any (not . isSpace) t+ = getSS xs ((SSnode m i j l True ns):rs)+getSS (_:xs) rs = getSS xs rs+getSS [] rs = return rs+++{---------------------------------------------------------------------------------------+-- Derive a good relational schema based on the structural summary (using hybrid inlining)+----------------------------------------------------------------------------------------}+++type Path = [Tag]+++data Table = Table String Path Bool [Table]+ | Column String Path+ deriving (Show,Read)+++printPath :: Path -> String+printPath [] = ""+printPath [p] = p+printPath (p:ps) = printPath ps++"/"++p+++pathCons p ps = if p=="root" then ps else p:ps+++schema :: SSnode -> String -> [String] -> [Table]+schema (SSnode n i _ (-1) _ ts) prefix path+ = [ Table (prefix++show i) (pathCons n path) True+ ((reverse (concatMap (\t -> schema t prefix []) ts))+ ++[ Column "value" [] ]) ]+schema (SSnode n i j _ _ []) prefix path+ | j == 1 || head n == '@'+ = [ Column (prefix++show i) (pathCons n path) ]+schema (SSnode n i 1 _ _ ts) prefix path+ = concatMap (\t -> schema t prefix (pathCons n path)) ts+schema (SSnode n i _ _ b ts) prefix path+ = [ Table (prefix++show i) (pathCons n path) False+ ((reverse (concatMap (\t -> schema t prefix []) ts))+ ++(if b && all (\(SSnode x _ _ _ _ _)-> head x == '@') ts+ then [ Column "value" [] ] else [])) ]+++fixSS :: SSnode -> SSnode+fixSS (SSnode n i j l True ts)+ | any (\(SSnode x _ _ _ _ _)-> head x /= '@') ts+ = SSnode n i j (-1) True (filter (\(SSnode x _ _ _ _ _)-> head x == '@') ts)+fixSS (SSnode n i j l b ts)+ = SSnode n i j l b (map fixSS ts)+++deriveSchema :: String -> String -> IO Table+deriveSchema file prefix+ = do doc <- readFile file+ let ts = parseDocument doc+ d = getSS ts [SSnode "root" 1 1 1 False []]+ [SSnode _ _ _ _ _ [t]] = evalState d 1+ nt@(SSnode m i j l b s) = fixSS t+ return (Table prefix [] False (reverse (schema (SSnode m i 2 l b s) prefix [])))+++relationalSchema :: Table -> String -> [String]+relationalSchema (Table n path b ts) parent+ = ("create table "++n++" ( /* "++printPath path+ ++(if b then " (mixed content)" else "")++" */\n"+ ++n++"_id int,\n"+ ++(if parent /= "" then (n++"_parent int references "++parent++"("++parent++"_id),\n") else "")+ ++(concat [ m++" varchar, /* "++printPath p++" */\n" | Column m p <- ts ])+ ++"primary key ("++n++"_id))\n")+ :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]+++getTableNames :: Table -> [String]+getTableNames (Table n _ _ ts) = n:(concatMap getTableNames ts)+getTableNames _ = []+++initializeDB :: (IConnection conn) => conn -> IO ()+initializeDB db+ = do tables <- getTables db+ if elem "HXQCatalog" tables+ then return ()+ else do let s = "create table HXQCatalog ( name varchar primary key, path varchar, summary varchar )"+ handleSqlError (run db s [])+ commit db+++createSchema :: (IConnection conn) => conn -> String -> String -> IO Table+createSchema db file name+ = do initializeDB db+ stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")+ _ <- handleSqlError (execute stmt [SqlString name])+ result <- handleSqlError (fetchAllRowsAL stmt)+ if length result > 0+ then do let [[(_,SqlString s)]] = result+ summary = (read s)::Table+ tables = getTableNames summary+ _ <- mapM (\t -> handleSqlError (run db ("drop table if exists "++t) [])) tables+ _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name])+ commit db+ else return ()+ t <- deriveSchema file name+ let schema = relationalSchema t ""+ -- mapM putStrLn schema+ _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?)"+ [SqlString name, SqlString file, SqlString (show t)])+ _ <- mapM (\s -> handleSqlError (run db s [])) schema+ commit db+ return t+++findSchema :: (IConnection conn) => conn -> String -> IO Table+findSchema db name+ = do initializeDB db+ stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")+ _ <- handleSqlError (execute stmt [SqlString name])+ result <- handleSqlError (fetchAllRowsAL stmt)+ if length result == 1+ then let [[(_,SqlString s)]] = result+ in return ((read s)::Table)+ else error ("Schema "++name++" doesn't exist")+++{---------------------------------------------------------------------------------------+-- Populate the database from the XML file and its derived structural summary+----------------------------------------------------------------------------------------}+++findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)+findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)+findPath (t@(Column _ p):ts) path n | p == path = Just (n,t)+findPath ((Table _ _ _ _):ts) path n = findPath ts path n+findPath (_:ts) path n = findPath ts path (n+1)+findPath [] _ _ = Nothing+++populate :: [XMLEvent] -> [Table] -> Int -> [[String]] -> [(Int,String)]+populate ((EmptyEvent tag atts):xs) ts n ps+ = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps+populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps)+ = case findPath s (tag:p) 0 of+ Just (n,nt@(Table m _ True as))+ -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")+ where showXTree ((EmptyEvent tag atts):xs) i s+ = showXTree xs i (s++"<"++tag++showAL atts++"/>")+ showXTree ((StartEvent tag atts):xs) i s+ = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")+ showXTree ((EndEvent tag):xs) i s+ = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))+ else showXTree xs (i-1) (s++"</"++tag++">")+ showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)+ showXTree (_:xs) i s = showXTree xs i s+ Just (n,nt@(Table m _ _ as))+ -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps)))+ Just (n,nt)+ -> populate xs (nt:t:ts) n ((tag:p):ps)+ Nothing -> populate xs (t:ts) 0 ((tag:p):ps)+ where popAtts ((a,v):as) ks+ = let Just(m,_) = findPath ks ['@':a] 0+ in (m,v):(popAtts as ks)+ popAtts [] _ = []+populate ((EndEvent tag):xs) ((t@(Table n path _ s)):ts) _ ([]:ps)+ = (-2,n):populate xs ts 0 ps+populate ((EndEvent tag):xs) ((Column m path):ts) n (p:ps)+ = populate xs ts 0 (tail p:ps)+populate ((EndEvent text):xs) ts _ (p:ps)+ = populate xs ts 0 (tail p:ps)+populate ((TextEvent text):xs) ts n ps+ | any (not . isSpace) text+ = (n,text):populate xs ts n ps+populate (x:xs) ts n ps+ = populate xs ts n ps+populate [] ts n ps = []+++insert :: (IConnection conn) => conn -> [(Int,String)] -> [(String,Int,Statement)] -> IO ()+insert db xs stmts = let (s,_,_,_) = m xs 0 0 in s+ where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i+ in (s >> insertTuple m el i p,[],xs',i')+ m ((k,m):xs) i p = (return (),[(k,m)],xs,i)+ ml [] i p = (return (),[],[],i)+ ml ((-2,m):xs) i p = (return (),[],xs,i)+ ml xs i p = let (s,el,xs',i') = m xs i p+ (s',el',xs'',i'') = ml xs' i' p+ in (s >> s',el++el',xs'',i'')+ find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs+ insertTuple m e i p+ = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "") stmts+ tuple = map (\c -> find c e) [0..len]+ lift x = if x=="\NUL" then SqlNull else SqlString x+ in do _ <- handleSqlError (execute stmt+ (if i==0+ then SqlInteger i:(map lift tuple)+ else SqlInteger i:SqlInteger p:(map lift tuple)))+ if mod i 100 == 99 then commit db else return ()+ return ()+++-- | Store an XML document into the database under the given name.+shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred db file name+ = do let prefix = map toLower name+ let tableStmt (Table n _ _ ts)+ = do let len = length[ 1 | Column _ _ <- ts]-1+ stmt <- handleSqlError (prepare db ("insert into "++n++" values ("+ ++(if n==prefix then "" else "?,")++"?"+ ++(concatMap (\_ -> ",?") [0..len])++")"))+ l <- mapM tableStmt ts+ return ((n,len,stmt):(concat l))+ tableStmt _ = return []+ t <- createSchema db file prefix+ stmts <- tableStmt t+ doc <- readFile file+ let ts = parseDocument doc+ let ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])+ insert db ic stmts+ commit db+ return ()+++-- | Create a secondary index on tagname for the shredded document under the given name..+createIndex :: (IConnection conn) => conn -> String -> String -> IO ()+createIndex db name tagname+ = do let prefix = map toLower name+ table <- findSchema db name+ let indexes = getIndexes "" table+ _ <- if null indexes+ then error ("there is no tagname: "++tagname)+ else mapM (\(t,c) -> do stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")"))+ handleSqlError (execute stmt [])) indexes+ commit db+ return ()+ where getIndexes _ (Table n _ _ ts) = concatMap (getIndexes n) ts+ getIndexes table (Column n path) | (head path)==tagname = [(table,n)]+ getIndexes _ _ = []+++{----------------------------------------------------------------------------------------------------+-- Convert XQuery to SQL+----------------------------------------------------------------------------------------------------}+++publishES :: [String] -> [String] -> String+publishES (p:ps) xs+ | head p == '@'+ = "attribute "++(tail p)++" {"++publishES ps xs++"}"+publishES (p:ps) xs+ = "<"++p++">{"++publishES ps xs++"}</"++p++">"+publishES [] [x] = x+publishES [] (x:xs) = x++","++publishES [] xs+++publishS :: Table -> String -> String+publishS (Table n path b ts) "error"+ = "for $"++n++" in SQL(select(),from($"++n++"),true()) return "+ ++publishES (reverse path) (map (\t -> publishS t n) ts)+publishS (Table n path b ts) parent+ = "for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"+ ++parent++"/"++parent++"_id) return "+ ++publishES (reverse path) (map (\t -> publishS t n) ts)+publishS (Column n path) parent+ = publishES (reverse path) ["$"++parent++"/"++n++"/text()"]+++publishTable :: Table -> String+publishTable table = "<root>{" ++ publishS table "error" ++ "}</root>"+++sqlFunctions = [("=","="),("eq","="),("<=","<="),(">=",">="),("!=","!="),(">",">"),+ ("<","<"),("ne","!="),("gt",">"),("lt","<"),("ge",">="),("le","<="),+ ("and","and"),("or","or")]++-- Convert a predicate AST to an SQL predicate that uses the tables+toSQL :: [String] -> Ast -> (String,[Ast])+toSQL tables e+ = case e of+ Astring s -> ("\'"++s++"\'",[])+ Aint n -> (show n,[])+ Ast "child_step" [Astring c,Avar v]+ -> if elem v tables+ then (v++"."++c,[])+ else ("?",[e])+ Ast "construction" [_,_,Ast "append" [x]]+ -> toSQL tables x+ Ast "call" [Avar "text",x]+ -> toSQL tables x+ Ast "call" [Avar cmp,x,y]+ | any (\(f,_) -> f==cmp) sqlFunctions+ -> let (nx,vx) = toSQL tables x+ (ny,vy) = toSQL tables y+ in (nx ++ " " ++ snd (head (filter (\(f,_) -> f==cmp) sqlFunctions)) ++ " " ++ ny,vx++vy)+ _ -> error ("Cannot convert to SQL: "++show e)+++-- Convert an AST to an SQL+makeSQL :: [Ast] -> Ast -> [Ast] -> (String,[Ast])+makeSQL tables pred cols+ = let tnames = [ x | Avar x <- tables ]+ ts = combine tnames+ cs = combine [ x | Avar x <- cols ]+ vars (Ast n args) = concatMap vars args+ vars (Avar v) | not (elem v tnames) = [v]+ vars _ = []+ combine [] = ""+ combine [x] = x+ combine (x:xs) = x++", "++combine xs+ in if pred == Ast "call" [Avar "true"]+ then (if null cs+ then "select * from "++ts+ else "select "++cs++" from "++ts,[])+ else let (p,args) = toSQL tnames pred+ in (if null cs+ then "select * from "++ts++" where "++p+ else "select "++cs++" from "++ts++" where "++p,args)
+ XML/HXQ/DBConnect.hs view
@@ -0,0 +1,26 @@+{-------------------------------------------------------------------------------------+-+- HDBC driver. Currently, Sqlite3.+- Programmer: Leonidas Fegaras+- Email: fegaras@cse.uta.edu+- Web: http://lambda.uta.edu/+- Creation: 05/30/08, last update: 05/30/08+- +- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.+- This material is provided as is, with absolutely no warranty expressed or implied.+- Any use is at your own risk. Permission is hereby granted to use or copy this program+- for any purpose, provided the above notices are retained on all copies.+-+--------------------------------------------------------------------------------------}+++module XML.HXQ.DBConnect where+++import Database.HDBC.Sqlite3++++-- | Connect to the relational database in filepath using the HDBC Sqlite3 driver+connect :: FilePath -> IO Connection+connect filepath = connectSqlite3 filepath
XML/HXQ/Interpreter.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 05/02/08+- Creation: 03/22/08, last update: 05/30/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# OPTIONS_GHC -fth -fglasgow-exts #-} module XML.HXQ.Interpreter where@@ -27,19 +27,25 @@ import XML.HXQ.XTree import XML.HXQ.Optimizer import XML.HXQ.Compiler+import Database.HDBC+import XML.HXQ.DB+import XML.HXQ.DBConnect -- system functions (=, concat, etc) systemFunctions :: [(String,Int,[XSeq]->XSeq)] systemFunctions = $(iFunctions) + -- XPath step functions (child, descendant, etc) pathFunctions :: [(String,Tag->XTree->XSeq)] pathFunctions = $(pFunctions) + -- run-time bindings of FLOWR variables type Environment = [(String,XSeq)] + -- a user-defined function is (fname,parameters,body) type Functions = [(String,[String],Ast)] @@ -49,6 +55,7 @@ undefv3 = error "Undefined last()" + -- Each XPath predicate must calculate position() and last() from its input XSeq -- if last() is used, then the evaluation is blocking (need to store the whole input XSeq) applyPredicates :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> XSeq@@ -62,16 +69,14 @@ | containsLast pred -- blocking: use only when last() is used in the predicate = let last = length xs in applyPredicates preds- (foldir (\x i r -> if case eval pred x i last "" env fncs of- [XInt k] -> k == i -- indexing- b -> conditionTest b- then x:r else r) [] xs 1) True env fncs+ (foldir (\x i r -> case eval pred x i last "" env fncs of+ [XInt k] -> if k == i then x:r else r -- indexing+ b -> if conditionTest b then x:r else r) [] xs 1) True env fncs applyPredicates (pred:preds) xs _ env fncs = applyPredicates preds- (foldir (\x i r -> if case eval pred x i undefv3 "" env fncs of- [XInt k] -> k == i -- indexing- b -> conditionTest b- then x:r else r) [] xs 1) True env fncs+ (foldir (\x i r -> case eval pred x i undefv3 "" env fncs of+ [XInt k] -> if k == i then x:r else r -- indexing+ b -> if conditionTest b then x:r else r) [] xs 1) True env fncs -- The XQuery interpreter@@ -95,9 +100,9 @@ [] (eval v context position last effective_axis env fncs) Ast "call" [Avar "position"] -> [XInt position] Ast "call" [Avar "last"] -> [XInt last]- Ast "step" [Ast "child_step" [tag, Avar "."]]+ Ast "child_step" [tag, Avar "."] | effective_axis /= ""- -> eval (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last "" env fncs+ -> eval (Ast effective_axis [tag, Avar "."]) context position last "" env fncs Ast "step" ((Ast "descendant_any" (body:tags)):predicates) -> let ts = map (\(Avar tag) -> tag) tags in foldr (\x r -> (applyPredicates predicates (descendant_any_with_tagged_children ts x) True env fncs)++r)@@ -106,12 +111,22 @@ | memV path_step pathFunctions -> foldr (\x r -> (applyPredicates predicates ((findV path_step pathFunctions) tag x) True env fncs)++r) [] (eval body context position last effective_axis env fncs)+ Ast "descendant_any" (body:tags)+ -> let ts = map (\(Avar tag) -> tag) tags+ in foldr (\x r -> (descendant_any_with_tagged_children ts x)++r)+ [] (eval body context position last effective_axis env fncs)+ Ast path_step [Astring tag,body]+ | memV path_step pathFunctions+ -> foldr (\x r -> ((findV path_step pathFunctions) tag x)++r)+ [] (eval body context position last effective_axis env fncs) Ast "step" [exp] -> eval exp context position last effective_axis env fncs Ast "step" (exp:predicates) -> applyPredicates predicates (eval exp context position last effective_axis env fncs) True env fncs Ast "predicate" [condition,body] -> applyPredicates [condition] (eval body context position last effective_axis env fncs) True env fncs+ Ast "append" args+ -> appendText (map (\x -> eval x context position last effective_axis env fncs) args) Ast "call" ((Avar fname):args) -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of [(_,len,f)] -> if (length args) == len@@ -130,7 +145,7 @@ -> let alc = map (\(Ast "pair" [a,v]) -> let ac = eval a context position last effective_axis env fncs vc = eval v context position last effective_axis env fncs- in (qName ac,showXS (text vc))) al+ in (qName ac,showXS vc)) al ct = eval tag context position last effective_axis env fncs bc = eval body context position last effective_axis env fncs in [ XElem (qName ct) alc 0 bc ]@@ -143,7 +158,7 @@ Ast "for" [Avar var,Avar ivar,source,body] -- a for-loop with an index -> let p = maxPosition (Avar ivar) body ns = if p > 0 -- there is a top-k like restriction- then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]+ then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]] else source in foldir (\a i r -> (eval body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs)++r) [] (eval ns context position last effective_axis env fncs) 1@@ -209,9 +224,9 @@ (return []) vs Ast "call" [Avar "position"] -> return [XInt position] Ast "call" [Avar "last"] -> return [XInt last]- Ast "step" [Ast "child_step" [tag, Avar "."]]+ Ast "child_step" [tag, Avar "."] | effective_axis /= ""- -> evalM (Ast "step" [Ast effective_axis [tag, Avar "."]]) context position last "" env fncs+ -> evalM (Ast effective_axis [tag, Avar "."]) context position last "" env fncs Ast "step" ((Ast "descendant_any" (body:tags)):predicates) -> do vs <- evalM body context position last effective_axis env fncs let ts = map (\(Avar tag) -> tag) tags@@ -222,6 +237,14 @@ -> do vs <- evalM body context position last effective_axis env fncs foldr (\x r -> (liftM2 (++)) (applyPredicatesM predicates ((findV path_step pathFunctions) tag x) True env fncs) r) (return []) vs+ Ast "descendant_any" (body:tags)+ -> do vs <- evalM body context position last effective_axis env fncs+ let ts = map (\(Avar tag) -> tag) tags+ return (foldr (\x r -> (descendant_any_with_tagged_children ts x)++r) [] vs)+ Ast path_step [Astring tag,body]+ | memV path_step pathFunctions+ -> do vs <- evalM body context position last effective_axis env fncs+ return (foldr (\x r -> ((findV path_step pathFunctions) tag x)++r) [] vs) Ast "step" [exp] -> evalM exp context position last effective_axis env fncs Ast "step" (exp:predicates)@@ -230,10 +253,16 @@ Ast "predicate" [condition,body] -> do vs <- evalM body context position last effective_axis env fncs applyPredicatesM [condition] vs True env fncs+ Ast "executeSQL" [Avar var,args]+ -> do as <- evalM args context position last effective_axis env fncs+ let [XStmt stmt] = findV var env+ executeSQL stmt as Ast "call" [Avar nm,c,t,e] -- this is the only lazy function | elem nm ["if","fn:if"] -> do ce <- evalM c context position last effective_axis env fncs evalM (if conditionTest ce then t else e) context position last effective_axis env fncs+ Ast "append" args+ -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs) args) Ast "call" ((Avar fname):args) -- Note: strict function application -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of [(_,len,f)] -> if (length args) == len@@ -253,7 +282,7 @@ -> do alc <- mapM (\(Ast "pair" [a,v]) -> do ac <- evalM a context position last effective_axis env fncs vc <- evalM v context position last effective_axis env fncs- return (qName ac,showXS (text vc))) al+ return (qName ac,showXS vc)) al ct <- evalM tag context position last effective_axis env fncs bc <- evalM body context position last effective_axis env fncs return [ XElem (qName ct) alc 0 bc ]@@ -267,7 +296,7 @@ Ast "for" [Avar var,Avar ivar,source,body] -- a for-loop with an index -> do let p = maxPosition (Avar ivar) body ns = if p > 0 -- there is a top-k like restriction- then Ast "step" [source,Ast "call" [Avar "<=",Ast "step" [pathPosition],Aint p]]+ then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]] else source vs <- evalM ns context position last effective_axis env fncs foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs) r)@@ -316,8 +345,8 @@ evalInput eval nvs nfs -xqueryE :: String -> Environment -> Functions -> IO (XSeq,Environment,Functions)-xqueryE query variables functions+xqueryE :: String -> Environment -> Functions -> (String -> IO XSeq) -> Bool -> IO (XSeq,Environment,Functions)+xqueryE query variables functions dbmapper verbose = do let asts = parse (scan query) fncs = foldr (\e r -> case e of Ast "function" ((Avar f):b:args) -> (f,map (\(Avar v) -> v) args,optimize b):r@@ -329,24 +358,52 @@ return ((v,uv):s) _ -> r) (return variables) asts let exprp e = case e of Ast f _ | elem f ["function","variable"] -> True; _ -> False- (ast,ns) = liftIOSources (concatenateAll (dropWhile exprp asts))+ exps = concatenateAll (dropWhile exprp asts)+ opt_exps = optimize exps+ (ast,ns) = liftIOSources opt_exps+ if verbose+ then do putStrLn "Abstract Syntax Tree (AST):"+ putStrLn (ppAst exps)+ putStrLn "Optimized AST:"+ putStrLn (ppAst opt_exps)+ putStrLn "Result:"+ else return () env <- foldr (\(n,s) r -> case s of+ Avar m -> do env <- r+ return ((n,findV m env):env)+ Ast "prepareSQL" [Astring sql]+ -> do env <- r+ t <- dbmapper sql+ return ((n,t):env) Astring file -> do doc <- readFile file env <- r- return ((n,[materialize (parseDocument doc)]):env)- Avar m -> do env <- r- return ((n,findV m env):env))+ return ((n,[materialize (parseDocument doc)]):env)) (return []) ns- e <- evalM (optimize ast) undefv1 undefv2 undefv3 "" (env++vars) fncs+ e <- evalM ast undefv1 undefv2 undefv3 "" (env++vars) fncs return (e,vars,fncs) --- | Evaluate the XQuery using interpreter.+-- | Evaluate the XQuery using the interpreter. xquery :: String -> IO XSeq-xquery query = do (u,_,_) <- xqueryE query [] []; return u+xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> return []) False+ return u --- | Read an XQuery fom a file and run it using the interpreter.+-- | Read an XQuery from a file and run it using the interpreter. xfile :: String -> IO XSeq xfile file = do query <- readFile file xquery query+++-- | Evaluate the XQuery with database connectivity using the interpreter.+xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq+xqueryDB query db = do (u,_,_) <- xqueryE query [] []+ (\sql -> do stmt <- prepareSQL db sql+ return [XStmt stmt]) False+ return u+++-- | Read an XQuery with database connectivity from a file and run it using the interpreter.+xfileDB :: (IConnection conn) => String -> conn -> IO XSeq+xfileDB file db = do query <- readFile file+ xqueryDB query db
XML/HXQ/Optimizer.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 05/01/08+- Creation: 05/01/08, last update: 06/10/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -16,17 +16,42 @@ module XML.HXQ.Optimizer(optimize) where -import XML.HXQ.Parser(Ast(..))+import System.IO.Unsafe+import Control.Monad+import Char(toLower)+import List(sortBy)+import Database.HDBC+import HXML(AttList)+import XML.HXQ.Parser import XML.HXQ.XTree+import XML.HXQ.DB+import XML.HXQ.DBConnect -paths = [ "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ] +paths = [ "current_step", "child_step", "descendant_step", "attribute_step", "attribute_descendant_step" ] + distinct :: Eq a => [a] -> [a] distinct = foldl (\r a -> if elem a r then r else r++[a]) [] +{-# NOINLINE publishXmlDoc #-}+-- get an XML document stored in a relational database+publishXmlDoc :: FilePath -> String -> Ast+publishXmlDoc filepath name+ = let query = unsafePerformIO (publishWrapper filepath name)+ [ast] = parse (scan query)+ in ast+ where publishWrapper filepath name+ = do let prefix = map toLower name+ db <- connect filepath+ table <- findSchema db prefix+ let query = publishTable table+ disconnect db+ return query++ -- collect attribute constructions inside element constructions collect_attributes :: Ast -> (Ast,[Ast]) collect_attributes (Ast "attribute_construction" [attr,value])@@ -35,6 +60,9 @@ = let (cx,ax) = collect_attributes x (cy,ay) = collect_attributes y in (Ast "call" [Avar "concatenate",cx,cy],ax++ay)+collect_attributes (Ast "append" es)+ = let (s,a) = foldr (\e (r,ar) -> let (cx,ax) = collect_attributes e in (cx:r,ax++ar)) ([],[]) es+ in (Ast "append" s,a) collect_attributes (Ast "step" (e:es)) = let (ce,ae) = collect_attributes e in (Ast "step" (ce:es),ae)@@ -95,26 +123,30 @@ tagged_children context (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Avar v):_)]):_)) | v == context = [tag]+tagged_children _ (Ast "step" ((Ast "descendant_any" _):_)) = [] tagged_children _ (Ast "step" ((Ast step _):_)) | elem step paths = [] tagged_children context (Ast _ xs) = concatMap (tagged_children context) xs tagged_children _ _ = [] -optimize :: Ast -> Ast+empty = Ast "call" [Avar "empty"]+++simplify :: Ast -> Ast -- must be done bottom-up: /../..-optimize (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])- = let nx = optimize (Ast "step" [Ast "parent_step" x])- in optimize (Ast "step" [Ast "parent_step" [nx]])+simplify (Ast "step" [Ast "parent_step" [Ast "step" [Ast "parent_step" x]]])+ = let nx = simplify (Ast "step" [Ast "parent_step" x])+ in simplify (Ast "step" [Ast "parent_step" [nx]]) -- get rid of a parent step-optimize (Ast "step" [Ast "parent_step" [x]])- = let (nx,cond,_,_) = removeParent x- in Ast "predicate" [optimize nx,optimize cond]+simplify (Ast "step" [Ast "parent_step" [x]])+ = let (cond,nx,_,_) = removeParent x+ in Ast "predicate" [simplify cond,simplify nx] -- remove $var/.. in a let-FLWOR-optimize (Ast "let" [Avar var,source,body])+simplify (Ast "let" [Avar var,source,body]) | parentOfVar body var- = let (nx,cond,childp,tag) = removeParent source- in optimize (Ast "let" [Avar (var++"_parent"),Ast "predicate" [nx,cond],+ = let (cond,nx,childp,tag) = removeParent source+ in simplify (Ast "let" [Avar (var++"_parent"),Ast "predicate" [cond,nx], Ast "let" [Avar var, Ast "step" [ Ast (if childp then "child_step"@@ -122,10 +154,10 @@ [tag,Avar (var++"_parent")] ], replaceParentOfVar body var (var++"_parent")]]) -- remove $var/.. from a for-FLWOR-optimize (Ast "for" [Avar var,Avar "$",source,body])+simplify (Ast "for" [Avar var,Avar "$",source,body]) | parentOfVar body var- = let (nx,cond,childp,tag) = removeParent source- in optimize (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [nx,cond],+ = let (cond,nx,childp,tag) = removeParent source+ in simplify (Ast "for" [Avar (var++"_parent"),Avar "$",Ast "predicate" [cond,nx], Ast "for" [Avar var,Avar "$", Ast "step" [ Ast (if childp then "child_step"@@ -133,24 +165,288 @@ [tag,Avar (var++"_parent")] ], replaceParentOfVar body var (var++"_parent")]]) -- pull out attributes from a general element construction-optimize (Ast "element_construction" [tag,content])+simplify (Ast "element_construction" [tag,Ast "attributes" as,content]) = let (nc,attrs) = collect_attributes content- in optimize (Ast "construction" [tag,Ast "attributes" attrs,nc])+ in simplify (Ast "construction" [tag,Ast "attributes" (as++attrs),nc]) -- if //* collect all children tagnames to use descendant_any_with_tagged_children-optimize (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body])+simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)],body]) | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds = let ctags = distinct ((tagged_children var body)++(concatMap (tagged_children ".") preds)) tags = map Avar ctags- in optimize (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])-optimize (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2))+ in simplify (Ast "for" [Avar var,i,Ast "step" [Ast "step" ((Ast "descendant_any" (path:tags)):preds)],body])+simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)]):preds2)) = let ctags = distinct(tag:(concatMap (tagged_children ".") preds)) tags = map Avar ctags- in optimize (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))-optimize (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds))+ in simplify (Ast "step" ((Ast "child_step" [Astring tag,Ast "step" ((Ast "descendant_any" (path:tags)):preds)]):preds2))+simplify (Ast "step" ((Ast "descendant_step" [Astring "*",path]):preds)) | any (not . null . (tagged_children ".")) preds = let ctags = distinct (concatMap (tagged_children ".") preds) tags = map Avar ctags- in optimize (Ast "step" ((Ast "descendant_any" (path:tags)):preds))--- needs more rules-optimize (Ast n args) = Ast n (map optimize args)-optimize e = e+ in simplify (Ast "step" ((Ast "descendant_any" (path:tags)):preds))+-- expand the wrapper of a stored document+simplify (Ast "call" [Avar "publish",Astring dbpath,Astring name])+ = simplify (publishXmlDoc dbpath name)+-- default+simplify (Ast n args) = Ast n (map simplify args)+simplify e = e+++taggedElement :: [Ast] -> String -> Maybe [Ast]+taggedElement (e@(Ast "construction" [Astring ctag,_,x]):xs) tag+ | ctag == tag || tag == "*"+ = case taggedElement xs tag of+ Nothing -> Nothing+ Just s -> Just (e:s)+taggedElement ((Ast "construction" [_,_,_]):xs) tag+ = taggedElement xs tag+taggedElement ((Ast "call" [Avar "concatenate",x,y]):xs) tag+ = case (taggedElement (x:xs) tag,taggedElement (y:xs) tag) of+ (Just tx,Just ty) -> Just (tx++ty)+ _ -> Nothing+taggedElement ((Astring _):xs) tag+ = taggedElement xs tag+taggedElement ((Aint _):xs) tag+ = taggedElement xs tag+taggedElement (e:xs) tag = Nothing+taggedElement [] _ = Just []+++findAttr :: String -> [Ast] -> Ast+findAttr tag ((Ast "pair" [Astring a,v]):_) | a==tag || tag=="*" = v+findAttr tag (_:xs) = findAttr tag xs+findAttr _ [] = empty+++andAll :: [Ast] -> Ast+andAll [x] = x+andAll (x:xs) = foldl (\a r -> call "and" [a,r]) x xs+++substContext :: Ast -> Ast -> Maybe Ast+substContext context e+ = case e of+ Ast "call" ((Avar f):xs)+ -> do ys <- mapM (substContext context) xs+ return (Ast "call" ((Avar f):ys))+ Ast "descendant_any" (x:tags)+ -> do nx <- substContext context x+ return (Ast "descendant_any" (nx:tags))+ Ast step [tag,x]+ | elem step paths+ -> do nx <- substContext context x+ return (Ast step [tag,nx])+ Avar "." -> Just context+ Astring _ -> Just e+ Aint _ -> Just e+ Afloat _ -> Just e+ Avar _ -> Just e+ _ -> Nothing+++occurs :: String -> Ast -> Int+occurs v e+ = case e of+ Avar w | v==w -> 1+ Ast "let" [Avar w,_,_] | v==w -> 0+ Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> 0+ Ast n xs -> sum (map (occurs v) xs)+ _ -> 0+++subst :: String -> Ast -> Ast -> Ast+subst v e b+ = case b of+ Avar w | v==w -> e+ Ast "let" [Avar w,_,_] | v==w -> b+ Ast "for" [Avar w,Avar i,_,_] | v==w || v==i -> b+ Ast n xs -> Ast n (map (subst v e) xs)+ _ -> b+++sqlPredicate :: Ast -> Bool+sqlPredicate e+ = case e of+ Astring s -> True+ Aint n -> True+ Ast "child_step" [Astring c,Avar v] -> True+ Ast "construction" [_,_,Ast "append" [x]]+ -> sqlPredicate x+ Ast "call" [Avar "text",x]+ -> sqlPredicate x+ Ast "call" [Avar cmp,x,y]+ | any (\(f,_) -> f==cmp) sqlFunctions+ -> (sqlPredicate x) && (sqlPredicate y)+ _ -> False+++usesCurrentContext :: Ast -> Bool+usesCurrentContext (Ast _ xs) = any usesCurrentContext xs+usesCurrentContext (Avar ".") = True+usesCurrentContext _ = False+++-- Normalization+normalize :: Ast -> Bool -> (Ast,Bool)+normalize exp changed+ = case exp of+ Ast "step" [x]+ -> normalize x True+ Ast "step" (x:(Ast "call" [Avar "true"]):xs)+ -> normalize (Ast "step" (x:xs)) True+ Ast "step" (x:(Ast "call" [Avar "false"]):xs)+ -> (empty,True)+ Ast "for" [v,i,Ast "call" [Avar "empty"],b]+ -> (empty,True)+ Ast "for" [v,i,s,Ast "call" [Avar "empty"]]+ -> (empty,True)+ Ast "descendant_any" ((Astring _):_)+ -> (empty,True)+ Ast "descendant_any" ((Aint _):_)+ -> (empty,True)+ Ast "descendant_any" ((Afloat _):_)+ -> (empty,True)+ Ast "descendant_any" ((Ast "call" [Avar "text",_]):_)+ -> (empty,True)+ Ast "descendant_any" ((Ast "call" [Avar "empty"]):_)+ -> (empty,True)+ Ast step [_,Astring _]+ | elem step paths+ -> (empty,True)+ Ast step [_,Aint _]+ | elem step paths+ -> (empty,True)+ Ast step [_,Afloat _]+ | elem step paths+ -> (empty,True)+ Ast step [_,Ast "call" [Avar "text",_]]+ | elem step paths+ -> (empty,True)+ Ast step [_,Ast "call" [Avar "empty"]]+ | elem step paths+ -> (empty,True)+ Ast "call" [Avar "and",Ast "call" [Avar "true"],x]+ -> normalize x True+ Ast "call" [Avar "and",x,Ast "call" [Avar "true"]]+ -> normalize x True+ -- (x,()) -> x+ Ast "call" [Avar "concatenate",x,Ast "call" [Avar "empty"]]+ -> normalize x True+ -- ((),x) -> x+ Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x]+ -> normalize x True+ -- for $v1 in (for $v2 in s2 return b2) return b1 --> for $v2 in s2, for $v1 in b2 return b1+ Ast "for" [v1,i1,Ast "for" [v2,i2,s2,b2],b1]+ -> normalize (Ast "for" [v2,i2,s2,Ast "for" [v1,i1,b2,b1]]) True+ -- (for $v in s return b)/tag --> for $v in s return b/tag --> + Ast "descendant_any" ((Ast "for" [v,i,s,b]):tags)+ -> normalize (Ast "for" [v,i,s,Ast "descendant_any" (b:tags)]) True+ Ast step [tag,Ast "for" [v,i,s,b]]+ | elem step paths+ -> normalize (Ast "for" [v,i,s,Ast step [tag,b]]) True+ -- (x,y)/tag --> (x/tag,y/tag)+ Ast "descendant_any" ((Ast "call" [Avar "concatenate",x,y]):tags)+ -> normalize (Ast "call" [Avar "concatenate",Ast "descendant_any" (x:tags),Ast "descendant_any" (y:tags)]) True+ Ast step [tag,Ast "call" [Avar "concatenate",x,y]]+ | elem step paths+ -> normalize (Ast "call" [Avar "concatenate",Ast step [tag,x],Ast step [tag,y]]) True+ -- for $v in (x,y) return b --> (for $v in x return b,for $v in y return b)+ Ast "for" [v,i,Ast "call" [Avar "concatenate",x,y],b]+ -> normalize (Ast "call" [Avar "concatenate",Ast "for" [v,i,x,b],Ast "for" [v,i,y,b]]) True+ Ast "for" [Avar v,Avar i,e,b]+ | case e of Ast "construction" _ -> True; Ast _ _ -> False; _ -> True+ -> normalize (if i == "$"+ then subst v e b+ else subst v e (subst i (Aint 1) b)) True+ -- unfold linear let+ Ast "let" [Avar v,e,b]+ | occurs v b < 2+ -> normalize (subst v e b) True+ -- (if c then t else e)/A --> if c then t/A else e/A+ Ast "descendant_any" ((Ast "predicate" [c,e]):tags)+ | not (usesCurrentContext c)+ -> normalize (Ast "predicate" [c,Ast "descendant_any" (e:tags)]) True+ Ast step [tag,Ast "predicate" [c,e]]+ | elem step paths && not (usesCurrentContext c)+ -> normalize (Ast "predicate" [c,Ast step [tag,e]]) True+ -- normalize predicate+ Ast "predicate" [Ast "call"[Avar "true"],x]+ -> (empty,True)+ Ast "predicate" [x,Ast "call"[Avar "empty"]]+ -> (empty,True)+ Ast "step" ((Ast "call" [Avar "empty"]):xs)+ -> (empty,True)+ Ast "step" ((Ast "call" [Avar "concatenate",x,y]):xs)+ -> normalize (Ast "call" [Avar "concatenate",Ast "step" (x:xs),Ast "step" (y:xs)]) True+ Ast "step" ((Ast "for" [v,i,s,b]):xs)+ -> normalize (Ast "for" [v,i,s,Ast "step" (b:xs)]) True+ Ast "step" (e@(Ast "construction" [_,_,_]):xs)+ -> case mapM (substContext e) xs of+ Just es -> normalize (Ast "predicate" [andAll es,e]) True+ Nothing -> let (r,b) = foldr (\a (r,b) -> let (c,s) = normalize a b in (c:r,s))+ ([],changed) (e:xs)+ in (Ast "step" r,b)+ Ast "call" [Avar "=",x,y]+ | x == empty || y == empty+ -> (Ast "call"[Avar "true"],True)+ -- (<ctag>...<tag>...</tag>...</ctag>)/tag --> ...<tag>...</tag>...+ Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]+ | taggedElement x tag /= Nothing+ -> case taggedElement x tag of+ Just [] -> (empty,True)+ Just s -> normalize (concatenateAll s) True+ Ast "child_step" [Astring tag,Ast "construction" [_,_,Ast "append" x]]+ -> normalize (Ast "current_step" [Astring tag,concatenateAll x]) True+ Ast "current_step" [Astring tag1,e@(Ast "construction" [Astring tag2,_,Ast "append" x])]+ -> if tag1 == tag2 || tag1 == "*"+ then normalize e True+ else (empty,True)+ -- (<tag>x</tag>)//tag --> (x,x//tag)+ Ast "descendant_any" (z@(Ast "construction" [Astring ctag,_,Ast "append" x]):tags)+ -> normalize (Ast "call" [Avar "concatenate",z,Ast "descendant_any" ((concatenateAll x):tags)]) True+ Ast "descendant_step" [Astring tag,z@(Ast "construction" [Astring ctag,_,Ast "append" x])]+ -> normalize (if tag == ctag || tag == "*"+ then Ast "call" [Avar "concatenate",z,Ast "descendant_step" [Astring tag,concatenateAll x]]+ else Ast "descendant_step" [Astring tag,concatenateAll x]) True+ -- (<tag A=s>x</tag>)/@A --> s+ Ast "attribute_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,x]]+ -> (findAttr tag as,True)+ -- (<tag A=s>x</tag>)//@A --> (s,x//@A)+ Ast "attribute_descendant_step" [Astring tag,Ast "construction" [ctag,Ast "attributes" as,Ast "append" x]]+ -> normalize (Ast "call" [Avar "concatenate",findAttr tag as,+ Ast "attribute_descendant_step" [Astring tag,concatenateAll x]]) True+ -- SQL folding+ Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],+ Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],b]]+ -> normalize (Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),+ Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],b])+ True+ Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):f),pred1],+ Ast "predicate" [pred2,x]]+ | sqlPredicate pred2+ -> normalize (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),+ Ast "call" ((Avar "from"):f),Ast "call" [Avar "and",pred1,pred2]],x]) True+ -- default+ Ast n args+ -> let (r,b) = foldr (\a (r,b) -> let (c,s) = normalize a b in (c:r,s)) ([],changed) args+ in (Ast n r,b)+ _ -> (exp,changed)+++foldSQL :: Ast -> Ast+foldSQL e+ = case e of+ Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]+ -> let (sql,args) = makeSQL tables pred cols+ in Ast "call" [Avar "sql",Astring sql,concatenateAll args]+ Ast n args -> Ast n (map foldSQL args)+ _ -> e+++optimizeLoop :: Ast -> Ast+optimizeLoop e = let (ne,b) = normalize e False+ in if b+ then optimizeLoop ne+ else ne++optimize :: Ast -> Ast+optimize e = foldSQL (optimizeLoop (simplify e))
XML/HXQ/Parser.hs view
@@ -122,48 +122,60 @@ happyOut20 :: (HappyAbsSyn ) -> ([ Ast ]) happyOut20 x = unsafeCoerce# x {-# INLINE happyOut20 #-}-happyIn21 :: ([ Ast ]) -> (HappyAbsSyn )+happyIn21 :: (Ast) -> (HappyAbsSyn ) happyIn21 x = unsafeCoerce# x {-# INLINE happyIn21 #-}-happyOut21 :: (HappyAbsSyn ) -> ([ Ast ])+happyOut21 :: (HappyAbsSyn ) -> (Ast) happyOut21 x = unsafeCoerce# x {-# INLINE happyOut21 #-}-happyIn22 :: (Ast) -> (HappyAbsSyn )+happyIn22 :: ([Ast]) -> (HappyAbsSyn ) happyIn22 x = unsafeCoerce# x {-# INLINE happyIn22 #-}-happyOut22 :: (HappyAbsSyn ) -> (Ast)+happyOut22 :: (HappyAbsSyn ) -> ([Ast]) happyOut22 x = unsafeCoerce# x {-# INLINE happyOut22 #-}-happyIn23 :: (Ast -> Ast) -> (HappyAbsSyn )+happyIn23 :: ([ Ast ]) -> (HappyAbsSyn ) happyIn23 x = unsafeCoerce# x {-# INLINE happyIn23 #-}-happyOut23 :: (HappyAbsSyn ) -> (Ast -> Ast)+happyOut23 :: (HappyAbsSyn ) -> ([ Ast ]) happyOut23 x = unsafeCoerce# x {-# INLINE happyOut23 #-}-happyIn24 :: (Ast -> Ast) -> (HappyAbsSyn )+happyIn24 :: (Ast) -> (HappyAbsSyn ) happyIn24 x = unsafeCoerce# x {-# INLINE happyIn24 #-}-happyOut24 :: (HappyAbsSyn ) -> (Ast -> Ast)+happyOut24 :: (HappyAbsSyn ) -> (Ast) happyOut24 x = unsafeCoerce# x {-# INLINE happyOut24 #-}-happyIn25 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn )+happyIn25 :: (Ast -> Ast) -> (HappyAbsSyn ) happyIn25 x = unsafeCoerce# x {-# INLINE happyIn25 #-}-happyOut25 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ])+happyOut25 :: (HappyAbsSyn ) -> (Ast -> Ast) happyOut25 x = unsafeCoerce# x {-# INLINE happyOut25 #-}-happyIn26 :: (String -> Ast -> Ast) -> (HappyAbsSyn )+happyIn26 :: (Ast -> Ast) -> (HappyAbsSyn ) happyIn26 x = unsafeCoerce# x {-# INLINE happyIn26 #-}-happyOut26 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)+happyOut26 :: (HappyAbsSyn ) -> (Ast -> Ast) happyOut26 x = unsafeCoerce# x {-# INLINE happyOut26 #-}-happyIn27 :: (String -> Ast -> Ast) -> (HappyAbsSyn )+happyIn27 :: (String -> Ast -> [ Ast ]) -> (HappyAbsSyn ) happyIn27 x = unsafeCoerce# x {-# INLINE happyIn27 #-}-happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)+happyOut27 :: (HappyAbsSyn ) -> (String -> Ast -> [ Ast ]) happyOut27 x = unsafeCoerce# x {-# INLINE happyOut27 #-}+happyIn28 :: (String -> Ast -> Ast) -> (HappyAbsSyn )+happyIn28 x = unsafeCoerce# x+{-# INLINE happyIn28 #-}+happyOut28 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)+happyOut28 x = unsafeCoerce# x+{-# INLINE happyOut28 #-}+happyIn29 :: (String -> Ast -> Ast) -> (HappyAbsSyn )+happyIn29 x = unsafeCoerce# x+{-# INLINE happyIn29 #-}+happyOut29 :: (HappyAbsSyn ) -> (String -> Ast -> Ast)+happyOut29 x = unsafeCoerce# x+{-# INLINE happyOut29 #-} happyInTok :: Token -> (HappyAbsSyn ) happyInTok x = unsafeCoerce# x {-# INLINE happyInTok #-}@@ -173,21 +185,21 @@ happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\xbe\x00\xbe\x00\x00\x00\x00\x00\x74\x02\x70\x00\x00\x00\x00\x00\xeb\xff\x00\x00\xfd\xff\x00\x00\x00\x00\x69\x01\x69\x01\xfa\x00\x82\x00\xfa\x00\xfa\x00\x00\x00\x70\x01\xfa\x00\x67\x01\x67\x01\x1c\x00\x16\x00\x37\x00\x84\x01\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\x47\x01\x00\x00\x3b\x00\x4f\x01\x46\x01\xff\xff\xfd\xff\x4d\x01\xfa\x00\x7d\x01\x4b\x01\xfa\x00\x7b\x01\x0c\x01\x11\x01\xe0\xff\x0f\x01\x00\x00\xf9\x00\x00\x00\x00\x00\x74\x02\x29\x00\x00\x00\x5a\x01\xf4\xff\xef\xff\x2b\x01\x00\x00\xfa\x00\x4d\x00\x24\x00\x00\x00\x02\x01\xed\x00\xed\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\xfa\x00\x90\x02\x90\x02\x90\x02\xc2\x02\x90\x02\xa9\x02\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x50\x01\x00\x00\x00\x00\x00\x00\x00\x00\x25\x01\x25\x01\xda\x02\x74\x02\x04\x01\x00\x01\x2c\x01\xee\x00\x00\x00\x19\x00\xfa\x00\x0e\x00\xfb\xff\xe2\x00\x00\x00\x00\x00\x16\x01\x37\x00\x5b\x00\x00\x00\xa2\x01\x00\x00\xd5\x00\xfa\x00\xfa\x00\xfa\x00\x00\x00\xfa\x00\xdb\x00\xfe\x00\xfa\x00\xd2\x00\xd2\x00\xfa\x00\xfa\x00\x1e\x02\x05\x01\xfa\x00\xff\x01\x03\x01\xc6\x00\x08\x00\x00\x00\xd0\x00\xf0\x00\xb2\x00\x00\x00\x04\x00\xfa\x00\x00\x00\x00\x00\xeb\x00\x5f\x00\x00\x00\xe7\x00\x5c\x00\x74\x02\xc2\x00\xb7\x00\x74\x02\x09\x00\xcc\x00\x74\x02\x7f\x01\x74\x02\x74\x02\xde\xff\x00\x00\xda\x00\x37\x00\xda\x00\xc3\x00\x50\x00\x00\x00\xfa\x00\x9f\x00\x00\x00\x00\x00\xfa\x00\xfa\x00\x74\x02\x34\x01\xaa\x00\xc0\x00\x26\x00\x00\x00\x00\x00\xca\x00\xfa\x00\x8f\x00\xfa\x00\xfa\xff\xfa\x00\x00\x00\xfa\x00\xfa\x00\x00\x00\xfa\x00\x00\x00\xfa\x00\x74\x02\x02\x00\x00\x00\xba\x00\xfa\x00\xb8\x00\x7b\x00\x0c\x00\xfe\xff\x74\x02\x74\x02\x58\x02\xfa\x00\x00\x00\x74\x02\x90\x00\x74\x02\x00\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x00\x00\x34\x01\xfa\x00\x3b\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x00\xe0\x01\x00\x00\xc1\x01\x00\x00\x74\x02\x00\x00\x00\x00\x00\x00"#+happyActOffsets = HappyA# "\xce\x00\xce\x00\x00\x00\x00\x00\x47\x02\x9c\x00\x00\x00\x00\x00\x40\x00\x00\x00\x06\x00\x00\x00\xfd\xff\x00\x00\x00\x00\x7e\x01\x7e\x01\x13\x01\x89\x00\x13\x01\x13\x01\x13\x01\x00\x00\x68\x01\x13\x01\x5f\x01\x5f\x01\x1c\x00\x17\x00\x63\x00\x97\x01\xa9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xff\x5c\x01\x00\x00\x44\x00\x64\x01\x5b\x01\xff\xff\xfd\xff\x43\x01\x13\x01\x71\x01\x41\x01\x13\x01\x6f\x01\x4c\x01\x4b\x01\xec\xff\x2a\x01\x00\x00\x3c\x01\x00\x00\x00\x00\x47\x02\x64\x00\x10\x00\x00\x00\x73\x01\x3a\x00\x38\x00\x1b\x01\x00\x00\x13\x01\x28\x00\x13\x01\x00\x00\x16\x00\x00\x00\x23\x01\x0f\x01\x0f\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x13\x01\x63\x02\x63\x02\x63\x02\x95\x02\x63\x02\x7c\x02\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x1c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08\x01\x08\x01\x56\x08\x47\x02\x24\x01\x22\x01\x4e\x01\x14\x01\x00\x00\xfa\xff\x13\x01\x01\x00\xfb\xff\x12\x01\x00\x00\x00\x00\x59\x00\x3a\x01\x63\x00\x62\x00\x00\x00\xb7\x01\x00\x00\xf9\x00\x13\x01\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x00\x01\x25\x01\x13\x01\xf4\x00\xf4\x00\x13\x01\x13\x01\x2b\x02\x29\x01\x13\x01\x0e\x02\x27\x01\xef\x00\x0e\x00\x00\x00\x03\x01\x1e\x01\xe3\x00\x00\x00\x0c\x00\x13\x01\x00\x00\x00\x00\x1a\x01\x57\x00\x00\x00\x19\x01\x51\x00\x47\x02\xf0\x00\xe6\x00\x47\x02\xfc\xff\xfb\x00\x47\x02\x96\x01\x47\x02\x47\x02\xe8\xff\x00\x00\xf8\x00\x63\x00\xf8\x00\x00\x00\xf5\x00\x4f\x00\x00\x00\x13\x01\xc2\x00\x00\x00\x00\x00\x13\x01\x13\x01\x47\x02\x4d\x01\xdb\x00\xd9\x00\x49\x00\x00\x00\x00\x00\xe7\x00\x13\x01\xa1\x00\x13\x01\xfc\xff\x00\x00\x13\x01\x13\x01\x00\x00\x13\x01\x00\x00\x13\x01\x47\x02\x08\x00\x00\x00\xcf\x00\x13\x01\xca\x00\x85\x00\x24\x00\x12\x00\x47\x02\x47\x02\x00\x00\x47\x02\x97\x00\x47\x02\x00\x00\x00\x00\x13\x01\x00\x00\x00\x00\x00\x00\x4d\x01\x13\x01\x00\x00\x00\x00\x00\x00\x13\x01\xf1\x01\x00\x00\xd4\x01\x47\x02\x00\x00\x00\x00\x00\x00"# happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\xa4\x00\x0d\x01\x00\x00\x00\x00\x00\x00\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x9b\x00\x79\x00\x5a\x06\x9c\x03\x4d\x06\x40\x06\x00\x00\x00\x00\x33\x06\x73\x00\x67\x00\x00\x00\x00\x00\x15\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x00\x00\x00\xa0\x00\x87\x03\x98\x00\x00\x00\x26\x06\x00\x00\x00\x00\x19\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x0c\x06\x12\x01\xbd\x00\x00\x00\x86\x00\x6b\x00\x5d\x00\xff\x05\xf2\x05\xe5\x05\xd8\x05\xcb\x05\xbe\x05\xb1\x05\xa4\x05\x97\x05\x8a\x05\x7d\x05\x70\x05\x63\x05\x56\x05\x49\x05\x3c\x05\x2f\x05\x22\x05\x15\x05\x08\x05\xfb\x04\xee\x04\xe1\x04\xd4\x04\xc7\x04\xba\x04\xad\x04\xa0\x04\x93\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x72\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x00\xd9\x00\x00\x00\x00\x00\x00\x00\x71\x00\x86\x04\x79\x04\x6c\x04\x00\x00\x5f\x04\x00\x00\x00\x00\x52\x04\x60\x00\x5a\x00\x45\x04\x5d\x03\x00\x00\x00\x00\x48\x03\x00\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x38\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x03\x00\x00\x00\x00\x00\x00\x1e\x03\x2b\x04\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x04\x2b\x00\x11\x04\x00\x00\x04\x04\x00\x00\xf7\x03\xea\x03\x00\x00\x11\x03\x00\x00\xfc\x02\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x03\x00\x00\x00\x00\x00\x00\x07\x00\xb6\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyGotoOffsets = HappyA# "\xa7\x00\x31\x01\x00\x00\x00\x00\x00\x00\xb1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x01\x00\x00\x00\x00\xd8\x00\xd1\x00\x4a\x08\x9e\x03\x87\x03\x33\x08\x1c\x08\x00\x00\x00\x00\x05\x08\xc1\x00\x7f\x00\x00\x00\x00\x00\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x00\x00\xb4\x00\x70\x03\xdf\x00\x00\x00\xee\x07\x00\x00\x00\x00\xd7\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\xc0\x07\xd3\x00\x59\x03\x00\x00\x0d\x00\x00\x00\x9f\x00\x8e\x00\x71\x00\xa9\x07\x92\x07\x7b\x07\x64\x07\x4d\x07\x36\x07\x1f\x07\x08\x07\xf1\x06\xda\x06\xc3\x06\xac\x06\x95\x06\x7e\x06\x67\x06\x50\x06\x39\x06\x22\x06\x0b\x06\xf4\x05\xdd\x05\xc6\x05\xaf\x05\x98\x05\x81\x05\x6a\x05\x53\x05\x3c\x05\x25\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x42\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x00\xc9\x00\x00\x00\x00\x00\x00\x00\x9b\x00\x0e\x05\xf7\x04\xe0\x04\x00\x00\xc9\x04\x00\x00\x00\x00\x00\x00\xb2\x04\x93\x00\x77\x00\x9b\x04\x2b\x03\x00\x00\x00\x00\x14\x03\x00\x00\x00\x00\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x84\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x02\x00\x00\x00\x00\x00\x00\xe6\x02\x6d\x04\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x04\x20\x00\x3f\x04\x4d\x00\x00\x00\x28\x04\x11\x04\x00\x00\xcf\x02\x00\x00\xb8\x02\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x03\x00\x00\x00\x00\x00\x00\x1f\x00\xcc\x03\x00\x00\x00\x00\x00\x00\xb5\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8e\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xef\xff\x9e\xff\x93\xff\x91\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\xff\x00\x00\x8d\xff\xf4\xff\xcc\xff\xcb\xff\xcd\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x8b\xff\x00\x00\x00\x00\x00\x00\x9c\xff\x9a\xff\x00\x00\x00\x00\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x98\xff\x00\x00\x00\x00\x94\xff\x00\x00\x99\xff\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xff\x00\x00\x89\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x8a\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x92\xff\x96\xff\x00\x00\x97\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x95\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x00\x00\x00\x00\xa0\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\x00\x00\xa1\xff\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\x9f\xff\xc1\xff\xb9\xff\xf8\xff"#+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8b\xff\xfa\xff\xbd\xff\xed\xff\xee\xff\x00\x00\xcd\xff\xa2\xff\xef\xff\x9b\xff\x90\xff\x8e\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xff\x00\x00\x8a\xff\xf4\xff\xcc\xff\xcb\xff\xa1\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xc8\xff\xce\xff\xac\xff\xcf\xff\xd0\xff\xca\xff\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x99\xff\x97\xff\x00\x00\x00\x00\x00\x00\x9f\xff\x00\x00\xb1\xff\xbb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xeb\xff\xec\xff\xbe\xff\xc5\xff\xc6\xff\x00\x00\x00\x00\xa7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8\xff\xa9\xff\x00\x00\x95\xff\x00\x00\x00\x00\x91\xff\x00\x00\x96\xff\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x00\x00\xa0\xff\xab\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x86\xff\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x87\xff\xb4\xff\x00\x00\x00\x00\xb5\xff\x00\x00\x00\x00\xc0\xff\x00\x00\x00\x00\xc4\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xf1\xff\xf2\xff\x00\x00\x8f\xff\x93\xff\x00\x00\x94\xff\x9e\xff\x00\x00\x00\x00\xa3\xff\x00\x00\x00\x00\xa4\xff\xa5\xff\x00\x00\x00\x00\xf3\xff\xb6\xff\xbc\xff\x00\x00\x00\x00\xaa\xff\xb2\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xff\x00\x00\x00\x00\xae\xff\x00\x00\xad\xff\x00\x00\xf9\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xff\xc3\xff\x9c\xff\xf0\xff\x00\x00\xc2\xff\xa6\xff\xb3\xff\x00\x00\xba\xff\xb8\xff\xb7\xff\xb6\xff\x00\x00\xb0\xff\xaf\xff\xf5\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xc1\xff\xb9\xff\xf8\xff"# happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x1a\x00\x0b\x00\x0d\x00\x09\x00\x0a\x00\x0c\x00\x2d\x00\x0a\x00\x2d\x00\x0a\x00\x10\x00\x11\x00\x12\x00\x0a\x00\x0c\x00\x43\x00\x03\x00\x0d\x00\x18\x00\x0c\x00\x0b\x00\x49\x00\x0e\x00\x0f\x00\x2e\x00\x40\x00\x09\x00\x40\x00\x0b\x00\x2e\x00\x38\x00\x0b\x00\x09\x00\x27\x00\x0b\x00\x39\x00\x0c\x00\x2b\x00\x2c\x00\x2e\x00\x39\x00\x03\x00\x0b\x00\x2e\x00\x18\x00\x0c\x00\x0a\x00\x35\x00\x36\x00\x2e\x00\x3c\x00\x3b\x00\x3a\x00\x2e\x00\x3c\x00\x18\x00\x02\x00\x03\x00\x04\x00\x09\x00\x42\x00\x48\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x44\x00\x12\x00\x3c\x00\x10\x00\x11\x00\x12\x00\x35\x00\x36\x00\x37\x00\x48\x00\x3c\x00\x18\x00\x2e\x00\x14\x00\x09\x00\x2e\x00\x3c\x00\x35\x00\x36\x00\x37\x00\x0c\x00\x03\x00\x45\x00\x12\x00\x03\x00\x48\x00\x27\x00\x03\x00\x09\x00\x08\x00\x2b\x00\x2c\x00\x0c\x00\x45\x00\x03\x00\x0c\x00\x48\x00\x12\x00\x03\x00\x08\x00\x35\x00\x36\x00\x07\x00\x3c\x00\x03\x00\x3a\x00\x03\x00\x3c\x00\x3d\x00\x42\x00\x07\x00\x44\x00\x03\x00\x42\x00\x2e\x00\x44\x00\x07\x00\x46\x00\x47\x00\x48\x00\x02\x00\x03\x00\x04\x00\x3a\x00\x3b\x00\x3c\x00\x2e\x00\x09\x00\x0a\x00\x2e\x00\x41\x00\x42\x00\x0a\x00\x44\x00\x10\x00\x11\x00\x12\x00\x3a\x00\x11\x00\x3c\x00\x02\x00\x03\x00\x18\x00\x2b\x00\x2c\x00\x42\x00\x03\x00\x44\x00\x30\x00\x14\x00\x07\x00\x03\x00\x00\x00\x01\x00\x09\x00\x03\x00\x04\x00\x27\x00\x06\x00\x13\x00\x14\x00\x2b\x00\x2c\x00\x13\x00\x14\x00\x0d\x00\x0e\x00\x0f\x00\x3e\x00\x3f\x00\x12\x00\x35\x00\x36\x00\x15\x00\x16\x00\x17\x00\x3a\x00\x2d\x00\x3c\x00\x44\x00\x02\x00\x03\x00\x04\x00\x0b\x00\x42\x00\x0b\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x0e\x00\x0f\x00\x10\x00\x10\x00\x11\x00\x12\x00\x07\x00\x01\x00\x44\x00\x03\x00\x04\x00\x18\x00\x06\x00\x2e\x00\x03\x00\x1a\x00\x3c\x00\x03\x00\x1a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x16\x00\x12\x00\x2d\x00\x27\x00\x15\x00\x16\x00\x17\x00\x2b\x00\x2c\x00\x15\x00\x16\x00\x17\x00\x15\x00\x16\x00\x17\x00\x2f\x00\x0b\x00\x35\x00\x36\x00\x03\x00\x0b\x00\x45\x00\x3a\x00\x09\x00\x3c\x00\x3d\x00\x02\x00\x03\x00\x04\x00\x2f\x00\x42\x00\x3b\x00\x44\x00\x09\x00\x46\x00\x47\x00\x48\x00\x15\x00\x16\x00\x17\x00\x10\x00\x11\x00\x12\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x18\x00\x06\x00\x16\x00\x03\x00\x44\x00\x3c\x00\x03\x00\x44\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x3c\x00\x12\x00\x32\x00\x27\x00\x15\x00\x16\x00\x17\x00\x2b\x00\x2c\x00\x15\x00\x16\x00\x17\x00\x15\x00\x16\x00\x17\x00\x01\x00\x2e\x00\x35\x00\x36\x00\x44\x00\x2e\x00\x31\x00\x3a\x00\x3c\x00\x3c\x00\x12\x00\x13\x00\x14\x00\x15\x00\x2f\x00\x42\x00\x2e\x00\x44\x00\x2e\x00\x46\x00\x47\x00\x48\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x05\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x3b\x00\x33\x00\x34\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x06\x00\x0b\x00\x3c\x00\x0b\x00\x3c\x00\x44\x00\x3c\x00\x45\x00\x09\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x08\x00\x44\x00\x3c\x00\x44\x00\xff\xff\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0c\x00\xff\xff\xff\xff\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\xff\xff\x27\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\xff\xff\xff\xff\x27\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x03\x00\x04\x00\x12\x00\x06\x00\xff\xff\x15\x00\x16\x00\x17\x00\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\xff\xff\x12\x00\xff\xff\xff\xff\x15\x00\x16\x00\x17\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"#+happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x16\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x16\x00\x0b\x00\x0a\x00\x2b\x00\x03\x00\x16\x00\x0a\x00\x2b\x00\x0a\x00\x41\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x47\x00\x09\x00\x0b\x00\x0b\x00\x03\x00\x25\x00\x09\x00\x3e\x00\x0b\x00\x29\x00\x2a\x00\x3e\x00\x0c\x00\x16\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x3a\x00\x39\x00\x38\x00\x10\x00\x3a\x00\x2c\x00\x3a\x00\x2c\x00\x43\x00\x2c\x00\x40\x00\x46\x00\x42\x00\x46\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x35\x00\x46\x00\x09\x00\x42\x00\x0b\x00\x2c\x00\x3a\x00\x0e\x00\x0f\x00\x10\x00\x0c\x00\x3a\x00\x0c\x00\x18\x00\x43\x00\x16\x00\x0c\x00\x46\x00\x0c\x00\x11\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x0c\x00\x2c\x00\x0c\x00\x2c\x00\x3f\x00\x40\x00\x25\x00\x42\x00\x09\x00\x09\x00\x29\x00\x2a\x00\x37\x00\x0c\x00\x37\x00\x10\x00\x10\x00\x03\x00\x2c\x00\x36\x00\x33\x00\x34\x00\x08\x00\x03\x00\x2c\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x11\x00\x12\x00\x03\x00\x2c\x00\x40\x00\x2c\x00\x42\x00\x08\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x02\x00\x03\x00\x2c\x00\x03\x00\x09\x00\x0a\x00\x0b\x00\x07\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x03\x00\x3a\x00\x3a\x00\x03\x00\x16\x00\x0e\x00\x0f\x00\x40\x00\x40\x00\x42\x00\x42\x00\x16\x00\x00\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x13\x00\x06\x00\x25\x00\x17\x00\x18\x00\x19\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x03\x00\x11\x00\x12\x00\x09\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2b\x00\x3a\x00\x03\x00\x29\x00\x2a\x00\x42\x00\x07\x00\x40\x00\x2e\x00\x42\x00\x03\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x03\x00\x03\x00\x0b\x00\x03\x00\x09\x00\x07\x00\x0b\x00\x0b\x00\x03\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x17\x00\x18\x00\x19\x00\x42\x00\x16\x00\x3c\x00\x3d\x00\x17\x00\x18\x00\x19\x00\x17\x00\x18\x00\x19\x00\x01\x00\x07\x00\x03\x00\x04\x00\x18\x00\x06\x00\x25\x00\x15\x00\x16\x00\x03\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x3a\x00\x11\x00\x12\x00\x07\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x2c\x00\x3a\x00\x3b\x00\x17\x00\x18\x00\x19\x00\x18\x00\x40\x00\x14\x00\x42\x00\x2b\x00\x44\x00\x45\x00\x46\x00\x02\x00\x03\x00\x04\x00\x10\x00\x11\x00\x12\x00\x13\x00\x09\x00\x2d\x00\x0b\x00\x15\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x0b\x00\x43\x00\x09\x00\x39\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x2d\x00\x0a\x00\x01\x00\x0a\x00\x03\x00\x04\x00\x42\x00\x06\x00\x25\x00\x14\x00\x3a\x00\x42\x00\x29\x00\x2a\x00\x0d\x00\x0e\x00\x0f\x00\x07\x00\x11\x00\x12\x00\x30\x00\x14\x00\x33\x00\x34\x00\x17\x00\x18\x00\x19\x00\x38\x00\x3a\x00\x3a\x00\x2c\x00\x01\x00\x2c\x00\x42\x00\x2f\x00\x40\x00\x39\x00\x42\x00\x2c\x00\x44\x00\x45\x00\x46\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x3a\x00\x2c\x00\x05\x00\x2d\x00\x0b\x00\x3a\x00\x0b\x00\x3a\x00\x31\x00\x32\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x06\x00\x42\x00\x3a\x00\x43\x00\x09\x00\x42\x00\x3a\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x08\x00\x42\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\xff\xff\x25\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xff\xff\xff\xff\x25\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\x05\x00\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x03\x00\x04\x00\xff\xff\x06\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0e\x00\x0f\x00\xff\xff\x11\x00\x12\x00\xff\xff\x14\x00\xff\xff\xff\xff\x17\x00\x18\x00\x19\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\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"# happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x0e\x00\x0f\x00\x10\x00\x41\x00\x43\x00\x2c\x00\xee\x00\x11\x00\xa8\x00\xfd\x00\xd6\x00\xe7\x00\x9c\x00\xe5\x00\x12\x00\x13\x00\x14\x00\xaf\x00\x05\x01\x26\x00\xfe\x00\xda\x00\x15\x00\xfe\x00\x2f\x00\xff\xff\xc6\x00\x08\x00\x94\x00\xd7\x00\x2b\x00\x9d\x00\x2c\x00\x94\x00\x44\x00\xc8\x00\x2e\x00\x16\x00\x2f\x00\x95\x00\xf5\x00\x17\x00\x18\x00\x99\x00\x96\x00\xf0\x00\x88\x00\xe8\x00\x15\x00\xf3\x00\x98\x00\x19\x00\x1a\x00\x99\x00\x2d\x00\x42\x00\x1b\x00\x99\x00\x1c\x00\x15\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x1e\x00\xef\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\x1f\x00\x14\x00\x30\x00\x12\x00\x13\x00\x14\x00\x89\x00\x8a\x00\xc9\x00\xdb\x00\x2d\x00\x15\x00\x99\x00\x92\x00\x11\x00\x99\x00\x30\x00\x89\x00\x8a\x00\x8b\x00\xd3\x00\xb6\x00\xca\x00\x14\x00\x30\x00\xcb\x00\x16\x00\xb7\x00\x11\x00\x81\x00\x17\x00\x18\x00\xde\x00\x8c\x00\x30\x00\xe0\x00\x8d\x00\x14\x00\x32\x00\x31\x00\x19\x00\x1a\x00\x82\x00\x1c\x00\xbf\x00\x1b\x00\x32\x00\x1c\x00\x1d\x00\x1e\x00\x33\x00\x1f\x00\x32\x00\x1e\x00\x99\x00\x1f\x00\x3c\x00\x20\x00\x21\x00\x22\x00\x0e\x00\x0f\x00\x10\x00\x8f\x00\x90\x00\x1c\x00\x99\x00\x11\x00\x3b\x00\x99\x00\x91\x00\x1e\x00\x83\x00\x1f\x00\x12\x00\x13\x00\x14\x00\xc3\x00\x99\x00\x1c\x00\xe2\x00\xe3\x00\x15\x00\x46\x00\x47\x00\x1e\x00\x32\x00\x1f\x00\x48\x00\x92\x00\x3d\x00\xa8\x00\x22\x00\x23\x00\x44\x00\x03\x00\x04\x00\x16\x00\x05\x00\xa5\x00\x3f\x00\x17\x00\x18\x00\x3e\x00\x3f\x00\x06\x00\x07\x00\x08\x00\x27\x00\x28\x00\x09\x00\x19\x00\x1a\x00\x0a\x00\x0b\x00\x0c\x00\x1b\x00\xfa\x00\x1c\x00\x1f\x00\x0e\x00\x0f\x00\x10\x00\x00\x01\x1e\x00\xe6\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\x85\x00\x08\x00\x86\x00\x12\x00\x13\x00\x14\x00\x41\x00\xaa\x00\x1f\x00\x03\x00\x04\x00\x15\x00\x05\x00\xf5\x00\x03\x00\xf4\x00\xd1\x00\x03\x00\xd4\x00\x06\x00\x07\x00\x08\x00\x41\x00\xd9\x00\x09\x00\xdc\x00\x16\x00\x0a\x00\x0b\x00\x0c\x00\x17\x00\x18\x00\xd4\x00\x0b\x00\x0c\x00\xc1\x00\x0b\x00\x0c\x00\xdd\x00\xdf\x00\x19\x00\x1a\x00\x03\x00\xe1\x00\xac\x00\x1b\x00\xad\x00\x1c\x00\x1d\x00\x0e\x00\x0f\x00\x10\x00\xae\x00\x1e\x00\x42\x00\x1f\x00\x11\x00\x20\x00\x21\x00\x22\x00\xc3\x00\x0b\x00\x0c\x00\x12\x00\x13\x00\x14\x00\xb0\x00\x02\x00\xb3\x00\x03\x00\x04\x00\x15\x00\x05\x00\xba\x00\x03\x00\x1f\x00\xbb\x00\x03\x00\x1f\x00\x06\x00\x07\x00\x08\x00\x41\x00\xc5\x00\x09\x00\xcc\x00\x16\x00\x0a\x00\x0b\x00\x0c\x00\x17\x00\x18\x00\x8d\x00\x0b\x00\x0c\x00\x29\x00\x0b\x00\x0c\x00\xcd\x00\x94\x00\x19\x00\x1a\x00\x1f\x00\x9e\x00\x85\x00\x1b\x00\x9b\x00\x1c\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x9f\x00\x1e\x00\x94\x00\x1f\x00\x9e\x00\x20\x00\x21\x00\x22\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\x97\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x42\x00\xf7\x00\xf8\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\xd8\x00\xa0\x00\xa2\x00\xa3\x00\xa5\x00\x1f\x00\xaa\x00\x25\x00\x29\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\xc1\x00\x1f\x00\x36\x00\x1f\x00\x00\x00\x00\x00\x00\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\x07\x01\x00\x00\x00\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\x02\x01\x00\x00\x00\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\xb1\x00\x00\x00\x00\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\xb4\x00\x00\x00\x00\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\x04\x01\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\xfc\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\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\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\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\x00\x00\x61\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\x00\x00\x00\x00\x00\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\x03\x00\x38\x00\xe8\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xe9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xce\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\xcf\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xd1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xb1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xb4\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xc5\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\xa6\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x03\x00\x38\x00\x39\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x02\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x04\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xf8\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xfa\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x00\x01\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xea\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xeb\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xec\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xef\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xf1\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xcd\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xe1\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xb5\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xb8\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbb\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbc\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbd\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xbe\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x64\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x65\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x66\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x67\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x68\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x69\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6a\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6c\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6d\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6e\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x6f\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x70\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x71\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x72\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x73\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x74\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x75\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x76\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x77\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x78\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x79\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7a\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7c\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7d\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7e\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x7f\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x80\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x91\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xa0\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\xa3\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x34\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x36\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x37\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x03\x00\x3b\x00\x09\x00\x05\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x45\x00\xd1\x00\x2f\x00\x14\x00\x13\x00\xb0\x00\x14\x00\x99\x00\x32\x00\x15\x00\x16\x00\x17\x00\x18\x00\x47\x00\xef\x00\xdf\x00\x02\x01\x18\x00\xed\x00\xa4\x00\xb7\x00\x29\x00\x9f\x00\x8b\x00\x08\x00\x8c\x00\x01\x01\xff\xff\x2e\x00\x8e\x00\x2f\x00\xf6\x00\x19\x00\x31\x00\xe0\x00\x32\x00\x1a\x00\x1b\x00\xa5\x00\x08\x01\x18\x00\x8f\x00\x90\x00\xd2\x00\x02\x01\x13\x00\x1c\x00\x1d\x00\xf0\x00\x30\x00\x46\x00\x1e\x00\x17\x00\x1f\x00\xa0\x00\x33\x00\xa0\x00\xd3\x00\xa0\x00\x21\x00\xd4\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x8f\x00\x90\x00\x91\x00\x48\x00\x13\x00\x22\x00\x14\x00\xa0\x00\x30\x00\x15\x00\x16\x00\x17\x00\xf9\x00\x33\x00\xfb\x00\x49\x00\x92\x00\x18\x00\xdc\x00\x93\x00\xe6\x00\xf4\x00\x0a\x00\x96\x00\x97\x00\x1f\x00\xe8\x00\x9b\x00\xcd\x00\x9b\x00\x98\x00\x21\x00\x19\x00\x22\x00\x13\x00\x13\x00\x1a\x00\x1b\x00\x9c\x00\xa1\x00\x9d\x00\x17\x00\x17\x00\x33\x00\xa0\x00\x4a\x00\x1c\x00\x1d\x00\x87\x00\xbe\x00\xa0\x00\x1e\x00\xa0\x00\x1f\x00\x20\x00\xe2\x00\x0a\x00\x33\x00\xa0\x00\x21\x00\xa0\x00\x22\x00\x34\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\xea\x00\xeb\x00\xa0\x00\x35\x00\x13\x00\x3f\x00\x14\x00\x88\x00\xbf\x00\x15\x00\x16\x00\x17\x00\xcb\x00\x03\x00\x1f\x00\x1f\x00\xc7\x00\x18\x00\xcf\x00\x08\x00\x21\x00\x21\x00\x22\x00\x22\x00\x99\x00\x25\x00\x26\x00\x89\x00\x03\x00\x04\x00\xa1\x00\x05\x00\x19\x00\xdd\x00\x0d\x00\x0e\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xb0\x00\x09\x00\x0a\x00\x4a\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\x00\x01\x1f\x00\x35\x00\x4c\x00\x4d\x00\x22\x00\x36\x00\x21\x00\x4e\x00\x22\x00\x03\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x03\x00\x35\x00\x04\x01\x03\x00\x13\x00\x40\x00\x14\x00\xee\x00\x35\x00\x15\x00\x16\x00\x17\x00\x41\x00\xc9\x00\x0d\x00\x0e\x00\x22\x00\x18\x00\x2a\x00\x2b\x00\xcb\x00\x0d\x00\x0e\x00\x94\x00\x0d\x00\x0e\x00\xb2\x00\x45\x00\x03\x00\x04\x00\xfa\x00\x05\x00\x19\x00\xad\x00\x43\x00\x03\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\xda\x00\x09\x00\x0a\x00\x45\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xfb\x00\x1f\x00\x20\x00\x2c\x00\x0d\x00\x0e\x00\xdd\x00\x21\x00\xe2\x00\x22\x00\xe4\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x52\x00\x53\x00\x54\x00\x55\x00\x13\x00\xe5\x00\x14\x00\x42\x00\x43\x00\x15\x00\x16\x00\x17\x00\xe7\x00\xe9\x00\xb4\x00\xb5\x00\x46\x00\x18\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xb6\x00\xb8\x00\x02\x00\xbb\x00\x03\x00\x04\x00\x22\x00\x05\x00\x19\x00\xc2\x00\xc3\x00\x22\x00\x1a\x00\x1b\x00\x06\x00\x07\x00\x08\x00\x45\x00\x09\x00\x0a\x00\xd5\x00\x0b\x00\x1c\x00\x1d\x00\x0c\x00\x0d\x00\x0e\x00\x1e\x00\xce\x00\x1f\x00\x9b\x00\xd6\x00\xa6\x00\x22\x00\x8b\x00\x21\x00\x46\x00\x22\x00\x9b\x00\x23\x00\x24\x00\x25\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\xa3\x00\xa6\x00\x9e\x00\xa7\x00\xa8\x00\xaa\x00\xab\x00\xad\x00\xfd\x00\xfe\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\xe1\x00\x22\x00\xb2\x00\x28\x00\x2c\x00\x22\x00\x39\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\xc9\x00\x22\x00\x00\x00\x00\x00\x00\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\x0a\x01\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\x06\x01\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\xb9\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\xbc\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\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\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\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\x00\x00\x67\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\x00\x00\x00\x00\x00\x00\x03\x00\x3b\x00\xf0\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xf1\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xda\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xb9\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xbc\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xce\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x93\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\xae\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3c\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3b\x00\x3d\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x06\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x07\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xfe\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x04\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf2\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xf7\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xd6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xe9\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xbd\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc0\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc3\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc4\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xc6\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x6f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x70\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x71\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x72\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x73\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x74\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x75\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x76\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x77\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x78\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x79\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7b\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7c\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7d\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x7f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x80\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x81\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x82\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x83\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x84\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x85\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x86\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x98\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xa8\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\xab\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x37\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x39\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3a\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\x00\x03\x00\x3f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x07\x00\x08\x00\x00\x00\x09\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x0c\x00\x0d\x00\x0e\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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 = array (1, 118) [+happyReduceArr = array (1, 121) [ (1 , happyReduce_1), (2 , happyReduce_2), (3 , happyReduce_3),@@ -305,11 +317,14 @@ (115 , happyReduce_115), (116 , happyReduce_116), (117 , happyReduce_117),- (118 , happyReduce_118)+ (118 , happyReduce_118),+ (119 , happyReduce_119),+ (120 , happyReduce_120),+ (121 , happyReduce_121) ] -happy_n_terms = 74 :: Int-happy_n_nonterms = 24 :: Int+happy_n_terms = 72 :: Int+happy_n_nonterms = 26 :: Int happyReduce_1 = happySpecReduce_1 0# happyReduction_1 happyReduction_1 happy_x_1@@ -482,7 +497,7 @@ happyReduce_16 = happySpecReduce_1 4# happyReduction_16 happyReduction_16 happy_x_1- = case happyOut22 happy_x_1 of { happy_var_1 -> + = case happyOut24 happy_x_1 of { happy_var_1 -> happyIn8 (happy_var_1 )}@@ -807,9 +822,9 @@ happyReduce_50 = happySpecReduce_1 4# happyReduction_50 happyReduction_50 happy_x_1- = case happyOutTok happy_x_1 of { (TString happy_var_1) -> + = case happyOut21 happy_x_1 of { happy_var_1 -> happyIn8- (Astring happy_var_1+ (happy_var_1 )} happyReduce_51 = happySpecReduce_1 4# happyReduction_51@@ -1060,8 +1075,9 @@ case happyOutTok happy_x_5 of { (QName happy_var_5) -> happyIn18 (if head happy_var_1 == Astring happy_var_5- then Ast "construction" (happy_var_1++[concatAll happy_var_3])- else error("Unmatched tags in element construction: "++(show (head happy_var_1))++" '"++happy_var_5++"'")+ then Ast "element_construction" (happy_var_1++[Ast "append" happy_var_3])+ else parseError [TError ("Unmatched tags in element construction: "+ ++(show (head happy_var_1))++" '"++happy_var_5++"'")] ) `HappyStk` happyRest}}} happyReduce_77 = happyReduce 5# 14# happyReduction_77@@ -1075,8 +1091,9 @@ case happyOutTok happy_x_4 of { (QName happy_var_4) -> happyIn18 (if head happy_var_1 == Astring happy_var_4- then Ast "construction" (happy_var_1++[call "empty" []])- else error("Unmatched tags in element construction: "++(show (head happy_var_1))++" '"++happy_var_4++"'")+ then Ast "element_construction" (happy_var_1++[Ast "append" []])+ else parseError [TError ("Unmatched tags in element construction: "+ ++(show (head happy_var_1))++" '"++happy_var_4++"'")] ) `HappyStk` happyRest}} happyReduce_78 = happySpecReduce_2 14# happyReduction_78@@ -1084,7 +1101,7 @@ happy_x_1 = case happyOut19 happy_x_1 of { happy_var_1 -> happyIn18- (Ast "construction" (happy_var_1++[call "empty" []])+ (Ast "element_construction" (happy_var_1++[Ast "append" []]) )} happyReduce_79 = happyReduce 7# 14# happyReduction_79@@ -1099,7 +1116,7 @@ = case happyOut8 happy_x_3 of { happy_var_3 -> case happyOut9 happy_x_6 of { happy_var_6 -> happyIn18- (Ast "element_construction" [happy_var_3,concatenateAll happy_var_6]+ (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6] ) `HappyStk` happyRest}} happyReduce_80 = happyReduce 7# 14# happyReduction_80@@ -1127,7 +1144,7 @@ = case happyOutTok happy_x_2 of { (QName happy_var_2) -> case happyOut9 happy_x_4 of { happy_var_4 -> happyIn18- (Ast "element_construction" [Astring happy_var_2,concatenateAll happy_var_4]+ (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4] ) `HappyStk` happyRest}} happyReduce_82 = happyReduce 5# 14# happyReduction_82@@ -1156,7 +1173,7 @@ happy_x_2 happy_x_1 = case happyOutTok happy_x_2 of { (QName happy_var_2) -> - case happyOut21 happy_x_3 of { happy_var_3 -> + case happyOut23 happy_x_3 of { happy_var_3 -> happyIn19 ([Astring happy_var_2,Ast "attributes" happy_var_3] )}}@@ -1230,248 +1247,262 @@ (happy_var_1++[happy_var_2] )}} -happyReduce_93 = happySpecReduce_3 17# happyReduction_93-happyReduction_93 happy_x_3+happyReduce_93 = happySpecReduce_1 17# happyReduction_93+happyReduction_93 happy_x_1+ = case happyOut22 happy_x_1 of { happy_var_1 -> + happyIn21+ (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1+ )}++happyReduce_94 = happySpecReduce_1 18# happyReduction_94+happyReduction_94 happy_x_1+ = case happyOutTok happy_x_1 of { (TString happy_var_1) -> + happyIn22+ (if happy_var_1=="" then [] else [Astring happy_var_1]+ )}++happyReduce_95 = happySpecReduce_3 18# happyReduction_95+happyReduction_95 happy_x_3 happy_x_2 happy_x_1- = case happyOutTok happy_x_1 of { (QName happy_var_1) -> - case happyOutTok happy_x_3 of { (TString happy_var_3) -> - happyIn21- ([Ast "pair" [Astring happy_var_1,Astring happy_var_3]]+ = case happyOut9 happy_x_2 of { happy_var_2 -> + happyIn22+ ([concatenateAll happy_var_2]+ )}++happyReduce_96 = happySpecReduce_2 18# happyReduction_96+happyReduction_96 happy_x_2+ happy_x_1+ = case happyOut22 happy_x_1 of { happy_var_1 -> + case happyOutTok happy_x_2 of { (TString happy_var_2) -> + happyIn22+ (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2] )}} -happyReduce_94 = happyReduce 5# 17# happyReduction_94-happyReduction_94 (happy_x_5 `HappyStk`- happy_x_4 `HappyStk`+happyReduce_97 = happyReduce 4# 18# happyReduction_97+happyReduction_97 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest)- = case happyOutTok happy_x_1 of { (QName happy_var_1) -> - case happyOut8 happy_x_4 of { happy_var_4 -> - happyIn21- ([Ast "pair" [Astring happy_var_1,happy_var_4]]+ = case happyOut22 happy_x_1 of { happy_var_1 -> + case happyOut9 happy_x_3 of { happy_var_3 -> + happyIn22+ (happy_var_1++[concatenateAll happy_var_3] ) `HappyStk` happyRest}} -happyReduce_95 = happyReduce 4# 17# happyReduction_95-happyReduction_95 (happy_x_4 `HappyStk`- happy_x_3 `HappyStk`- happy_x_2 `HappyStk`- happy_x_1 `HappyStk`- happyRest)- = case happyOut21 happy_x_1 of { happy_var_1 -> - case happyOutTok happy_x_2 of { (QName happy_var_2) -> - case happyOutTok happy_x_4 of { (TString happy_var_4) -> - happyIn21- (happy_var_1++[Ast "pair" [Astring happy_var_2,Astring happy_var_4]]- ) `HappyStk` happyRest}}}+happyReduce_98 = happySpecReduce_3 19# happyReduction_98+happyReduction_98 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { (QName happy_var_1) -> + case happyOut21 happy_x_3 of { happy_var_3 -> + happyIn23+ ([Ast "pair" [Astring happy_var_1,happy_var_3]]+ )}} -happyReduce_96 = happyReduce 6# 17# happyReduction_96-happyReduction_96 (happy_x_6 `HappyStk`- happy_x_5 `HappyStk`- happy_x_4 `HappyStk`+happyReduce_99 = happyReduce 4# 19# happyReduction_99+happyReduction_99 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest)- = case happyOut21 happy_x_1 of { happy_var_1 -> + = case happyOut23 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (QName happy_var_2) -> - case happyOut8 happy_x_5 of { happy_var_5 -> - happyIn21- (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_5]]+ case happyOut21 happy_x_4 of { happy_var_4 -> + happyIn23+ (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]] ) `HappyStk` happyRest}}} -happyReduce_97 = happySpecReduce_1 18# happyReduction_97-happyReduction_97 happy_x_1- = case happyOut25 happy_x_1 of { happy_var_1 -> - happyIn22+happyReduce_100 = happySpecReduce_1 20# happyReduction_100+happyReduction_100 happy_x_1+ = case happyOut27 happy_x_1 of { happy_var_1 -> + happyIn24 (Ast "step" (happy_var_1 "child_step" (Avar ".")) )} -happyReduce_98 = happySpecReduce_2 18# happyReduction_98-happyReduction_98 happy_x_2+happyReduce_101 = happySpecReduce_2 20# happyReduction_101+happyReduction_101 happy_x_2 happy_x_1- = case happyOut25 happy_x_2 of { happy_var_2 -> - happyIn22+ = case happyOut27 happy_x_2 of { happy_var_2 -> + happyIn24 (Ast "step" (happy_var_2 "attribute_step" (Avar ".")) )} -happyReduce_99 = happySpecReduce_2 18# happyReduction_99-happyReduction_99 happy_x_2+happyReduce_102 = happySpecReduce_2 20# happyReduction_102+happyReduction_102 happy_x_2 happy_x_1- = case happyOut25 happy_x_1 of { happy_var_1 -> - case happyOut23 happy_x_2 of { happy_var_2 -> - happyIn22+ = case happyOut27 happy_x_1 of { happy_var_1 -> + case happyOut25 happy_x_2 of { happy_var_2 -> + happyIn24 (Ast "step" [happy_var_2 (Ast "step" (happy_var_1 "child_step" (Avar ".")))] )}} -happyReduce_100 = happySpecReduce_3 18# happyReduction_100-happyReduction_100 happy_x_3+happyReduce_103 = happySpecReduce_3 20# happyReduction_103+happyReduction_103 happy_x_3 happy_x_2 happy_x_1- = case happyOut25 happy_x_2 of { happy_var_2 -> - case happyOut23 happy_x_3 of { happy_var_3 -> - happyIn22+ = case happyOut27 happy_x_2 of { happy_var_2 -> + case happyOut25 happy_x_3 of { happy_var_3 -> + happyIn24 (Ast "step" (map happy_var_3 (happy_var_2 "attribute_step" (Avar "."))) )}} -happyReduce_101 = happySpecReduce_1 19# happyReduction_101-happyReduction_101 happy_x_1- = case happyOut24 happy_x_1 of { happy_var_1 -> - happyIn23+happyReduce_104 = happySpecReduce_1 21# happyReduction_104+happyReduction_104 happy_x_1+ = case happyOut26 happy_x_1 of { happy_var_1 -> + happyIn25 (happy_var_1 )} -happyReduce_102 = happySpecReduce_2 19# happyReduction_102-happyReduction_102 happy_x_2+happyReduce_105 = happySpecReduce_2 21# happyReduction_105+happyReduction_105 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+ = case happyOut25 happy_x_1 of { happy_var_1 -> + case happyOut26 happy_x_2 of { happy_var_2 -> + happyIn25 (happy_var_2 . happy_var_1 )}} -happyReduce_103 = happySpecReduce_2 20# happyReduction_103-happyReduction_103 happy_x_2+happyReduce_106 = happySpecReduce_2 22# happyReduction_106+happyReduction_106 happy_x_2 happy_x_1- = case happyOut25 happy_x_2 of { happy_var_2 -> - happyIn24+ = case happyOut27 happy_x_2 of { happy_var_2 -> + happyIn26 (\e -> Ast "step" (happy_var_2 "child_step" e) )} -happyReduce_104 = happySpecReduce_3 20# happyReduction_104-happyReduction_104 happy_x_3+happyReduce_107 = happySpecReduce_3 22# happyReduction_107+happyReduction_107 happy_x_3 happy_x_2 happy_x_1- = case happyOut25 happy_x_3 of { happy_var_3 -> - happyIn24+ = case happyOut27 happy_x_3 of { happy_var_3 -> + happyIn26 (\e -> Ast "step" (happy_var_3 "attribute_step" e) )} -happyReduce_105 = happySpecReduce_3 20# happyReduction_105-happyReduction_105 happy_x_3+happyReduce_108 = happySpecReduce_3 22# happyReduction_108+happyReduction_108 happy_x_3 happy_x_2 happy_x_1- = case happyOut25 happy_x_3 of { happy_var_3 -> - happyIn24+ = case happyOut27 happy_x_3 of { happy_var_3 -> + happyIn26 (\e -> Ast "step" (happy_var_3 "descendant_step" e) )} -happyReduce_106 = happyReduce 4# 20# happyReduction_106-happyReduction_106 (happy_x_4 `HappyStk`+happyReduce_109 = happyReduce 4# 22# happyReduction_109+happyReduction_109 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest)- = case happyOut25 happy_x_4 of { happy_var_4 -> - happyIn24+ = case happyOut27 happy_x_4 of { happy_var_4 -> + happyIn26 (\e -> Ast "step" (happy_var_4 "attribute_descendant_step" e) ) `HappyStk` happyRest} -happyReduce_107 = happySpecReduce_2 20# happyReduction_107-happyReduction_107 happy_x_2+happyReduce_110 = happySpecReduce_2 22# happyReduction_110+happyReduction_110 happy_x_2 happy_x_1- = happyIn24+ = happyIn26 (\e -> Ast "step" [Ast "parent_step" [e]] ) -happyReduce_108 = happySpecReduce_1 21# happyReduction_108-happyReduction_108 happy_x_1- = case happyOut26 happy_x_1 of { happy_var_1 -> - happyIn25+happyReduce_111 = happySpecReduce_1 23# happyReduction_111+happyReduction_111 happy_x_1+ = case happyOut28 happy_x_1 of { happy_var_1 -> + happyIn27 (\t e -> [happy_var_1 t e] )} -happyReduce_109 = happyReduce 4# 21# happyReduction_109-happyReduction_109 (happy_x_4 `HappyStk`+happyReduce_112 = happyReduce 4# 23# happyReduction_112+happyReduction_112 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest)- = case happyOut25 happy_x_1 of { happy_var_1 -> + = case happyOut27 happy_x_1 of { happy_var_1 -> case happyOut8 happy_x_3 of { happy_var_3 -> - happyIn25+ happyIn27 (\t e -> (happy_var_1 t e)++[happy_var_3] ) `HappyStk` happyRest}} -happyReduce_110 = happySpecReduce_1 22# happyReduction_110-happyReduction_110 happy_x_1- = case happyOut27 happy_x_1 of { happy_var_1 -> - happyIn26+happyReduce_113 = happySpecReduce_1 24# happyReduction_113+happyReduction_113 happy_x_1+ = case happyOut29 happy_x_1 of { happy_var_1 -> + happyIn28 (\t e -> happy_var_1 t e )} -happyReduce_111 = happySpecReduce_1 22# happyReduction_111-happyReduction_111 happy_x_1- = happyIn26+happyReduce_114 = happySpecReduce_1 24# happyReduction_114+happyReduction_114 happy_x_1+ = happyIn28 (\t e -> Ast t [Astring "*",e] ) -happyReduce_112 = happySpecReduce_1 22# happyReduction_112-happyReduction_112 happy_x_1+happyReduce_115 = happySpecReduce_1 24# happyReduction_115+happyReduction_115 happy_x_1 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> - happyIn26+ happyIn28 (\t e -> Ast t [Astring happy_var_1,e] )} -happyReduce_113 = happySpecReduce_1 23# happyReduction_113-happyReduction_113 happy_x_1+happyReduce_116 = happySpecReduce_1 25# happyReduction_116+happyReduction_116 happy_x_1 = case happyOut7 happy_x_1 of { happy_var_1 -> - happyIn27+ happyIn29 (\_ _ -> happy_var_1 )} -happyReduce_114 = happySpecReduce_1 23# happyReduction_114-happyReduction_114 happy_x_1- = happyIn27+happyReduce_117 = happySpecReduce_1 25# happyReduction_117+happyReduction_117 happy_x_1+ = happyIn29 (\_ e -> e ) -happyReduce_115 = happySpecReduce_3 23# happyReduction_115-happyReduction_115 happy_x_3+happyReduce_118 = happySpecReduce_3 25# happyReduction_118+happyReduction_118 happy_x_3 happy_x_2 happy_x_1 = case happyOut9 happy_x_2 of { happy_var_2 -> - happyIn27+ happyIn29 (\t e -> if e == Avar "." then concatenateAll happy_var_2 else Ast "context" [e,Astring t,concatenateAll happy_var_2] )} -happyReduce_116 = happySpecReduce_2 23# happyReduction_116-happyReduction_116 happy_x_2+happyReduce_119 = happySpecReduce_2 25# happyReduction_119+happyReduction_119 happy_x_2 happy_x_1- = happyIn27+ = happyIn29 (\_ _ -> call "empty" [] ) -happyReduce_117 = happyReduce 4# 23# happyReduction_117-happyReduction_117 (happy_x_4 `HappyStk`+happyReduce_120 = happyReduce 4# 25# happyReduction_120+happyReduction_120 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOutTok happy_x_1 of { (QName happy_var_1) -> case happyOut9 happy_x_3 of { happy_var_3 -> - happyIn27- (\_ e -> if e == Avar "."+ happyIn29+ (\t e -> if e == Avar "." then call happy_var_1 happy_var_3- else Ast "context" [e,call happy_var_1 happy_var_3]+ else Ast "context" [e,Astring t,call happy_var_1 happy_var_3] ) `HappyStk` happyRest}} -happyReduce_118 = happySpecReduce_3 23# happyReduction_118-happyReduction_118 happy_x_3+happyReduce_121 = happySpecReduce_3 25# happyReduction_121+happyReduction_121 happy_x_3 happy_x_2 happy_x_1 = case happyOutTok happy_x_1 of { (QName happy_var_1) -> - happyIn27- (if elem happy_var_1 ["text"]- then \_ e -> call happy_var_1 [e]- else \_ _ -> call happy_var_1 []+ happyIn29+ (\_ e -> call happy_var_1 (if e == Avar "." then [] else [e]) )} happyNewToken action sts stk [] =- happyDoAction 73# notHappyAtAll action sts stk []+ happyDoAction 71# notHappyAtAll action sts stk [] happyNewToken action sts stk (tk:tks) = let cont i = happyDoAction i tk action sts stk tks in@@ -1488,66 +1519,64 @@ RP -> cont 10#; LSB -> cont 11#; RSB -> cont 12#;- LESCAPE -> cont 13#;- RESCAPE -> cont 14#;- TO -> cont 15#;- PLUS -> cont 16#;- MINUS -> cont 17#;- TIMES -> cont 18#;- DIV -> cont 19#;- IDIV -> cont 20#;- MOD -> cont 21#;- TEQ -> cont 22#;- TNE -> cont 23#;- TLT -> cont 24#;- TLE -> cont 25#;- TGT -> cont 26#;- TGE -> cont 27#;- PRE -> cont 28#;- POST -> cont 29#;- IS -> cont 30#;- SEQ -> cont 31#;- SNE -> cont 32#;- SLT -> cont 33#;- SLE -> cont 34#;- SGT -> cont 35#;- SGE -> cont 36#;- AND -> cont 37#;- OR -> cont 38#;- NOT -> cont 39#;- UNION -> cont 40#;- INTERSECT -> cont 41#;- EXCEPT -> cont 42#;- FOR -> cont 43#;- LET -> cont 44#;- IN -> cont 45#;- COMMA -> cont 46#;- ASSIGN -> cont 47#;- WHERE -> cont 48#;- ORDER -> cont 49#;- BY -> cont 50#;- ASCENDING -> cont 51#;- DESCENDING -> cont 52#;- ELEMENT -> cont 53#;- ATTRIBUTE -> cont 54#;- STAG -> cont 55#;- ETAG -> cont 56#;- SATISFIES -> cont 57#;- ATSIGN -> cont 58#;- SLASH -> cont 59#;- QName happy_dollar_dollar -> cont 60#;- DECLARE -> cont 61#;- FUNCTION -> cont 62#;- VARIABLE -> cont 63#;- AT -> cont 64#;- DOTS -> cont 65#;- DOT -> cont 66#;- SEMI -> cont 67#;- Variable happy_dollar_dollar -> cont 68#;- XMLtext happy_dollar_dollar -> cont 69#;- TInteger happy_dollar_dollar -> cont 70#;- TFloat happy_dollar_dollar -> cont 71#;- TString happy_dollar_dollar -> cont 72#;+ TO -> cont 13#;+ PLUS -> cont 14#;+ MINUS -> cont 15#;+ TIMES -> cont 16#;+ DIV -> cont 17#;+ IDIV -> cont 18#;+ MOD -> cont 19#;+ TEQ -> cont 20#;+ TNE -> cont 21#;+ TLT -> cont 22#;+ TLE -> cont 23#;+ TGT -> cont 24#;+ TGE -> cont 25#;+ PRE -> cont 26#;+ POST -> cont 27#;+ IS -> cont 28#;+ SEQ -> cont 29#;+ SNE -> cont 30#;+ SLT -> cont 31#;+ SLE -> cont 32#;+ SGT -> cont 33#;+ SGE -> cont 34#;+ AND -> cont 35#;+ OR -> cont 36#;+ NOT -> cont 37#;+ UNION -> cont 38#;+ INTERSECT -> cont 39#;+ EXCEPT -> cont 40#;+ FOR -> cont 41#;+ LET -> cont 42#;+ IN -> cont 43#;+ COMMA -> cont 44#;+ ASSIGN -> cont 45#;+ WHERE -> cont 46#;+ ORDER -> cont 47#;+ BY -> cont 48#;+ ASCENDING -> cont 49#;+ DESCENDING -> cont 50#;+ ELEMENT -> cont 51#;+ ATTRIBUTE -> cont 52#;+ STAG -> cont 53#;+ ETAG -> cont 54#;+ SATISFIES -> cont 55#;+ ATSIGN -> cont 56#;+ SLASH -> cont 57#;+ QName happy_dollar_dollar -> cont 58#;+ DECLARE -> cont 59#;+ FUNCTION -> cont 60#;+ VARIABLE -> cont 61#;+ AT -> cont 62#;+ DOTS -> cont 63#;+ DOT -> cont 64#;+ SEMI -> cont 65#;+ Variable happy_dollar_dollar -> cont 66#;+ XMLtext happy_dollar_dollar -> cont 67#;+ TInteger happy_dollar_dollar -> cont 68#;+ TFloat happy_dollar_dollar -> cont 69#;+ TString happy_dollar_dollar -> cont 70#; _ -> happyError' (tk:tks) } @@ -1588,8 +1617,8 @@ instance Show Ast where show (Ast s []) = s ++ "()"- show (Ast s (x:xs)) = s ++ "(" ++ (show x)- ++ (foldr (\a r -> ","++(show a)++r) "" xs)+ show (Ast s (x:xs)) = s ++ "(" ++ show x+ ++ foldr (\a r -> ","++show a++r) "" xs ++ ")" show (Avar s) = s show (Aint n) = show n@@ -1597,23 +1626,45 @@ show (Astring s) = "\'" ++ s ++ "\'" +screenSize = 80::Int++prettyAst :: Ast -> Int -> (String,Int)+prettyAst (Avar s) p = (s,(length s)+p)+prettyAst (Aint n) p = let s = show n in (s,(length s)+p)+prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)+prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)+prettyAst (Ast s args) p+ = let (ps,np) = prettyArgs args+ in (s++"("++ps++")",np+1)+ where prettyArgs [] = ("",p+1)+ prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)+ np = (length s)+p+1+ in if (length ss)+p < screenSize+ then (ss,(length ss)+p)+ else let ds = map (\x -> let (s,ep) = prettyAst x np+ in (s ++ ",\n" ++ space np,ep)) (init xs)+ (ls,lp) = prettyAst (last xs) np+ in (concatMap fst ds ++ ls,lp)+ space n = replicate n ' '+++ppAst :: Ast -> String+ppAst e = let (s,_) = prettyAst e 0 in s++ call :: String -> [Ast] -> Ast call name args = Ast "call" ((Avar name):args) concatenateAll :: [Ast] -> Ast+concatenateAll [x] = x concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs concatenateAll _ = call "empty" [] -concatAll :: [Ast] -> Ast-concatAll (x:xs) = foldl (\a r -> call "concat" [a,r]) x xs-concatAll _ = call "empty" []-- data Token = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB- | LESCAPE | RESCAPE | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD+ | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT@@ -1631,6 +1682,7 @@ show (TInteger n) = "Integer("++(show n)++")" show (TFloat n) = "Double("++(show n)++")" show (TString s) = "String("++s++")"+ show (TError s) = "'"++s++"'" show t = case filter (\(n,_) -> n==t) tokenList of (_,b):_ -> b _ -> "Illegal token"@@ -1638,7 +1690,7 @@ tokenList :: [(Token,String)] tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),- (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),(LESCAPE,"\"{"),(RESCAPE,"}\""),+ (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"), (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"), (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"), (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),@@ -1650,50 +1702,60 @@ (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")] -parseError [] = error "Reached end-of-input"-parseError [_] = error "Reached end-of-input"-parseError tk = error("Parse error: "++(show (take 10 (init tk))))+parseError tk = error (case tk of+ ((TError s):_) -> "Parse error: "++s+ _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk))) scan :: String -> [Token]-scan cs = lexer cs [0]+scan cs = lexer cs "" + xmlText :: String -> [Token] xmlText "" = [] xmlText text = [XMLtext text] + -- scans XML syntax and returns an XMLtext token with the text-xml :: String -> String -> [Int] -> [Token]-xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs (0:n))-xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs n)+xml :: String -> String -> String -> [Token]+xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))+xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n)) xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n-xml ('<':cs) text (k:n) = (xmlText text)++(TLT : lexer cs (k+2:n))-xml ('\'':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)-xml ('\"':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)+xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n)) xml ('(':':':cs) text n = xqComment cs text n xml (c:cs) text n = xml cs (text++[c]) n xml [] text _ = xmlText text -xqComment :: String -> String -> [Int] -> [Token]++xqComment :: String -> String -> String -> [Token] xqComment (':':')':cs) text n = xml cs text n xqComment (_:cs) text n = xqComment cs text n xqComment [] text _ = xmlText text -xmlComment :: String -> String -> [Int] -> [Token]++xmlComment :: String -> String -> String -> [Token] xmlComment ('-':'>':cs) text n = xml cs (text++"->") n xmlComment (c:cs) text n = xmlComment cs (text++[c]) n xmlComment [] text _ = xmlText text + isQN :: Char -> Bool isQN c = elem c "_:-" || isDigit c || isAlpha c + isVar :: Char -> Bool isVar c = elem c "_" || isDigit c || isAlpha c ++inXML :: String -> Bool+inXML ('>':'<':_) = True+inXML _ = False++ -- the XQuery scanner-lexer :: String -> [Int] -> [Token]-lexer [] [0] = []-lexer [] _ = error "Unbalanced tags"+lexer :: String -> String -> [Token]+lexer [] "" = []+lexer [] _ = [ TError "Unexpected end of input" ] lexer (' ':'>':' ':cs) n = TGT : lexer cs n lexer (c:cs) n | isSpace c = lexer cs n@@ -1702,46 +1764,50 @@ lexer ('$':c:cs) n | isAlpha c = let (var,rest) = span isVar (c:cs) in (Variable var) : lexer rest n-lexer ('\'':'{':cs) n = LESCAPE : lexer cs n-lexer ('\"':'{':cs) n = LESCAPE : lexer cs n lexer (':':'=':cs) n = ASSIGN : lexer cs n-lexer ('<':'/':cs) n = STAG : lexer cs n+lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n) lexer ('<':'=':cs) n = TLE : lexer cs n lexer ('>':'=':cs) n = TGE : lexer cs n lexer ('<':'<':cs) n = PRE : lexer cs n lexer ('>':'>':cs) n = POST : lexer cs n-lexer ('/':'>':cs) (k:n) = ETAG : lexer cs (k-2:n)+lexer ('/':'>':cs) m = case m of+ '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)+ _ -> [ TError "Unexpected token: '/>'" ] lexer ('(':':':cs) n = lexComment cs n lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n lexer ('.':'.':cs) n = DOTS : lexer cs n lexer ('.':cs) n = DOT : lexer cs n-lexer ('}':'\'':cs) n = RESCAPE : lexer cs n-lexer ('}':'\"':cs) n = RESCAPE : lexer cs n lexer ('!':'=':cs) n = TNE : lexer cs n-lexer ('\'':cs) n = lexString cs n-lexer ('\"':cs) n = lexString2 cs n+lexer ('\'':cs) n = lexString cs "" ('\'':n)+lexer ('\"':cs) n = lexString cs "" ('\"': n) lexer ('[':cs) n = LB : lexer cs n lexer (']':cs) n = RB : lexer cs n lexer ('(':cs) n = LP : lexer cs n lexer (')':cs) n = RP : lexer cs n-lexer ('}':cs) [_,n] = RSB : lexer cs [n]-lexer ('}':cs) (_:n:ns) = RSB : (if n==0 then lexer cs (n:ns) else xml cs "" (n:ns))+lexer ('}':cs) m = case m of+ '{':'\"':n -> RSB : lexString cs "" ('\"':n)+ '{':'\'':n -> RSB : lexString cs "" ('\'':n)+ '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)+ _ -> [ TError "Unexpected token: '}'" ] lexer ('+':cs) n = PLUS : lexer cs n lexer ('-':cs) n = MINUS : lexer cs n lexer ('*':cs) n = TIMES : lexer cs n lexer ('=':cs) n = TEQ : lexer cs n-lexer ('<':c:cs) n | not(isAlpha c) = TLT : lexer (c:cs) n-lexer ('<':cs) (k:n) = TLT : lexer cs (k+2:n)-lexer ('>':cs) (k:n) = TGT : (if k==1 then lexer cs (0:n) else xml cs "" (k-1:n))+lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))+lexer ('>':cs) m = case m of+ '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)+ '<':n -> TGT : xml cs "" ('>':m) + _ -> TGT : lexer cs m lexer (',':cs) n = COMMA : lexer cs n lexer ('@':cs) n = ATSIGN : lexer cs n lexer ('/':cs) n = SLASH : lexer cs n-lexer ('{':cs) n = LSB : lexer cs (0:n)+lexer ('{':cs) n = LSB : lexer cs ('{':n) lexer ('|':cs) n = UNION : lexer cs n lexer (';':cs) n = SEMI : lexer cs n-lexer (c:cs) n = error("Illegal character "++[c])+lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n -lexNum :: String -> [Int] -> [Token]++lexNum :: String -> String -> [Token] lexNum cs n = if null rest || head rest /= '.' then TInteger (read k) : lexer rest n else let (m,rest2) = span isDigit (tail rest)@@ -1752,68 +1818,75 @@ _ -> (TFloat val) : lexer rest2 n where (k,rest) = span isDigit cs -lexString :: String -> [Int] -> [Token]-lexString cs n = TString s : lexer (tail rest) n- where (s,rest) = span inString cs- inString c = c /= '\'' -lexString2 :: String -> [Int] -> [Token]-lexString2 cs n = TString s : lexer (tail rest) n- where (s,rest) = span inString cs- inString c = c /= '\"'+lexString :: String -> String -> String -> [Token]+lexString ('\"':cs) s m = case m of+ '\"':n -> (TString s) : (lexer cs n)+ _ -> lexString cs (s++"\"") m+lexString ('\'':cs) s m = case m of+ '\'':n -> (TString s) : (lexer cs n)+ _ -> lexString cs (s++"\'") m+lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))+lexString (c:cs) s n = lexString cs (s++[c]) n+lexString [] s n = [ TError "End of input while in string" ] -lexComment :: String -> [Int] -> [Token]++lexComment :: String -> String -> [Token] lexComment (':':')':cs) n = lexer cs n lexComment (_:cs) n = lexComment cs n-lexComment [] n = []+lexComment [] n = [ TError "End of input while in comment" ] -lexXmlComment :: String -> String -> [Int] -> [Token]++lexXmlComment :: String -> String -> String -> [Token] lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n) lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n lexXmlComment [] text _ = xmlText text -lexVar :: String -> [Int] -> [Token]++lexVar :: String -> String -> [Token] lexVar cs n =- case span isQN cs of- ("return",rest) -> RETURN : lexer rest n- ("some",rest) -> SOME : lexer rest n- ("every",rest) -> EVERY : lexer rest n- ("if",rest) -> IF : lexer rest n- ("then",rest) -> THEN : lexer rest n- ("else",rest) -> ELSE : lexer rest n- ("to",rest) -> TO : lexer rest n- ("div",rest) -> DIV : lexer rest n- ("idiv",rest) -> IDIV : lexer rest n- ("mod",rest) -> MOD : lexer rest n- ("and",rest) -> AND : lexer rest n- ("or",rest) -> OR : lexer rest n- ("not",rest) -> NOT : lexer rest n- ("union",rest) -> UNION : lexer rest n- ("intersect",rest) -> INTERSECT : lexer rest n- ("except",rest) -> EXCEPT : lexer rest n- ("for",rest) -> FOR : lexer rest n- ("let",rest) -> LET : lexer rest n- ("in",rest) -> IN : lexer rest n- ("where",rest) -> WHERE : lexer rest n- ("order",rest) -> ORDER : lexer rest n- ("by",rest) -> BY : lexer rest n- ("ascending",rest) -> ASCENDING : lexer rest n- ("descending",rest) -> DESCENDING : lexer rest n- ("element",rest) -> ELEMENT : lexer rest n- ("attribute",rest) -> ATTRIBUTE : lexer rest n- ("satisfies",rest) -> SATISFIES : lexer rest n- ("declare",rest) -> DECLARE : lexer rest n- ("function",rest) -> FUNCTION : lexer rest n- ("variable",rest) -> VARIABLE : lexer rest n- ("at",rest) -> AT : lexer rest n- ("eq",rest) -> SEQ : lexer rest n- ("ne",rest) -> SNE : lexer rest n- ("lt",rest) -> SLT : lexer rest n- ("le",rest) -> SLE : lexer rest n- ("gt",rest) -> SGT : lexer rest n- ("ge",rest) -> SGE : lexer rest n- ("is",rest) -> IS : lexer rest n- (var,rest) -> QName var : lexer rest n+ let (nm,rest) = span isQN cs+ in (case nm of+ "return" -> RETURN+ "some" -> SOME+ "every" -> EVERY+ "if" -> IF+ "then" -> THEN+ "else" -> ELSE+ "to" -> TO+ "div" -> DIV+ "idiv" -> IDIV+ "mod" -> MOD+ "and" -> AND+ "or" -> OR+ "not" -> NOT+ "union" -> UNION+ "intersect" -> INTERSECT+ "except" -> EXCEPT+ "for" -> FOR+ "let" -> LET+ "in" -> IN+ "where" -> WHERE+ "order" -> ORDER+ "by" -> BY+ "ascending" -> ASCENDING+ "descending" -> DESCENDING+ "element" -> ELEMENT+ "attribute" -> ATTRIBUTE+ "satisfies" -> SATISFIES+ "declare" -> DECLARE+ "function" -> FUNCTION+ "variable" -> VARIABLE+ "at" -> AT+ "eq" -> SEQ+ "ne" -> SNE+ "lt" -> SLT+ "le" -> SLE+ "gt" -> SGT+ "ge" -> SGE+ "is" -> IS+ var -> QName var+ ) : lexer rest n {-# LINE 1 "templates/GenericTemplate.hs" #-} {-# LINE 1 "templates/GenericTemplate.hs" #-} {-# LINE 1 "<built-in>" #-}
XML/HXQ/XQuery.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 05/06/08+- Creation: 03/22/08, last update: 05/30/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -13,10 +13,11 @@ - --------------------------------------------------------------------------------------} + -- | HXQ is a fast and space-efficient compiler from XQuery (the standard -- query language for XML) to embedded Haskell code. The translation is -- based on Haskell templates. It also provides an interpreter for--- evaluating ad-hoc XQueries read from input or from files.+-- evaluating ad-hoc XQueries read from input or from files and database connectivity using HDBC. -- For more information, look at <http://lambda.uta.edu/HXQ/>. module XML.HXQ.XQuery ( -- * The XML Data Representation@@ -24,10 +25,19 @@ -- * The XQuery Compiler xq, xe, -- * The XQuery Interpreter- xquery, xfile+ xquery, xfile,+ -- * The XQuery Compiler with Database Connectivity+ xqdb, connect, disconnect, prepareSQL, executeSQL,+ -- * The XQuery Interpreter with Database Connectivity+ xqueryDB, xfileDB,+ -- * Shredding and Publishing XML Documents Using a Relational Database+ shred, createIndex ) where import HXML(AttList) import XML.HXQ.XTree import XML.HXQ.Compiler import XML.HXQ.Interpreter+import XML.HXQ.DB+import XML.HXQ.DBConnect+import Database.HDBC(disconnect)
− XML/HXQ/XQueryDB.hs
@@ -1,38 +0,0 @@-{----------------------------------------------------------------------------------------- The XQuery Compiler and Interpreter with HDBC connectivity-- Programmer: Leonidas Fegaras-- Email: fegaras@cse.uta.edu-- Web: http://lambda.uta.edu/-- Creation: 05/12/08, last update: 05/12/08-- -- Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved.-- This material is provided as is, with absolutely no warranty expressed or implied.-- Any use is at your own risk. Permission is hereby granted to use or copy this program-- for any purpose, provided the above notices are retained on all copies.-----------------------------------------------------------------------------------------}----- | HXQ is a fast and space-efficient compiler from XQuery (the standard--- query language for XML) to embedded Haskell code. The translation is--- based on Haskell templates. It also provides an interpreter for--- evaluating ad-hoc XQueries read from input or from files.--- For more information, look at <http://lambda.uta.edu/HXQ/>.-module XML.HXQ.XQueryDB (- -- * The XML Data Representation- XTree(..), XSeq, Tag, AttList, putXSeq,- -- * The XQuery Compiler- xq, xe,- -- * The XQuery Interpreter- xquery, xfile,- -- * The XQuery Compiler with Database Connectivity- xqdb, disconnect, prepareSQL, executeSQL- ) where--import HXML(AttList)-import XML.HXQ.XTree-import XML.HXQ.Compiler-import XML.HXQ.Interpreter-import XML.HXQ.DB-import Database.HDBC(disconnect)
XML/HXQ/XTree.hs view
@@ -1,10 +1,10 @@ {------------------------------------------------------------------------------------- --- XML Trees (rose trees)+- XML Trees (represented as rose trees) - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 05/05/08+- Creation: 05/01/08, last update: 05/30/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -22,8 +22,13 @@ import System.IO import XMLParse(XMLEvent(..)) import HXML(AttList)+import XML.HXQ.Parser(Ast(..))+import Database.HDBC(Statement) +instance Eq Statement where x == y = False++ type Tag = String @@ -38,23 +43,26 @@ | XGERef Tag -- ^ general entity reference | XComment String -- ^ comment | XError String -- ^ error report+ | XStmt Statement -- ^ used internally to wrap an SQL statement+ | XNoPad -- ^ marker for no padding in XSeq deriving Eq + type XSeq = [XTree] showAL :: AttList -> String-showAL = foldr(\(a,v) r -> " "++a++"=\""++v++"\""++r) []+showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) [] showXT :: XTree -> Bool -> String showXT e pad = case e of- XElem tag al _ [] -> "<"++tag++(showAL al)++"/>"- XElem tag al _ xs -> "<"++tag++(showAL al)++">"++(showXS xs)++"</"++tag++">"- XText text -> text- XInt n -> p++(show n)- XFloat n -> p++(show n)- XBool v -> p++(if v then "true" else "false")+ XElem tag al _ [] -> "<"++tag++showAL al++"/>"+ XElem tag al _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">"+ XText text -> p++text+ XInt n -> p++show n+ XFloat n -> p++show n+ XBool v -> p++if v then "true" else "false" XComment s -> "<!--"++s++"-->" XPI n s -> "<?"++n++" "++s++">" XError s -> error s@@ -63,15 +71,19 @@ showXS :: XSeq -> String showXS [] = ""-showXS (x:xs) = (showXT x False) ++ (concatMap (\x -> showXT x True) xs)+showXS (x:xs) = showXT x False ++ sXS xs+ where sXS (XNoPad:x:xs) = (showXT x False) ++ sXS xs+ sXS (x:xs) = (showXT x True) ++ sXS xs+ sXS _ = "" instance Show XTree where show t = showXT t False --- | Print the XQuery result (which is a sequence of XML fragments) with no waiting+-- | Print the XQuery result (which is a sequence of XML fragments) without buffering. putXSeq :: XSeq -> IO () putXSeq xs = hSetBuffering stdout NoBuffering >> putStrLn (showXS xs)+ {--------------- Build the rose tree from the XML stream ----------------------------}
XQueryParser.y view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 02/15/08, last update: 05/01/08+- Creation: 02/15/08, last update: 05/15/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -35,9 +35,7 @@ ')' { RP } '{' { LSB } '}' { RSB }- '\'{' { LESCAPE }- '}\'' { RESCAPE }- 'to' { TO }+ 'to' { TO } '+' { PLUS } '-' { MINUS } '*' { TIMES }@@ -175,7 +173,7 @@ | '+' expr %prec UMINUS { call "uplus" [$2] } | '-' expr %prec UMINUS { call "uminus" [$2] } | 'not' expr %prec UMINUS { call "not" [$2] }- | 'String' { Astring $1 }+ | string { $1 } | 'Integer' { Aint $1 } | 'Double' { Afloat $1 } @@ -225,15 +223,17 @@ element :: { Ast } element : stag '>' content '</' 'QName' '>' { if head $1 == Astring $5- then Ast "construction" ($1++[concatAll $3])- else error("Unmatched tags in element construction: "++(show (head $1))++" '"++$5++"'") }+ then Ast "element_construction" ($1++[Ast "append" $3])+ else parseError [TError ("Unmatched tags in element construction: "+ ++(show (head $1))++" '"++$5++"'")] } | stag '>' '</' 'QName' '>' { if head $1 == Astring $4- then Ast "construction" ($1++[call "empty" []])- else error("Unmatched tags in element construction: "++(show (head $1))++" '"++$4++"'") }- | stag '/>' { Ast "construction" ($1++[call "empty" []]) }- | 'element' '{' expr '}' '{' expl '}' { Ast "element_construction" [$3,concatenateAll $6] }+ then Ast "element_construction" ($1++[Ast "append" []])+ else parseError [TError ("Unmatched tags in element construction: "+ ++(show (head $1))++" '"++$4++"'")] }+ | stag '/>' { Ast "element_construction" ($1++[Ast "append" []]) }+ | 'element' '{' expr '}' '{' expl '}' { Ast "element_construction" [$3,Ast "attributes" [],concatenateAll $6] } | 'attribute' '{' expr '}''{' expl '}'{ Ast "attribute_construction" [$3,concatenateAll $6] }- | 'element' 'QName' '{' expl '}' { Ast "element_construction" [Astring $2,concatenateAll $4] }+ | 'element' 'QName' '{' expl '}' { Ast "element_construction" [Astring $2,Ast "attributes" [],concatenateAll $4] } | 'attribute' 'QName' '{' expl '}' { Ast "attribute_construction" [Astring $2,concatenateAll $4] } stag :: { [ Ast ] }@@ -250,12 +250,18 @@ | content 'XMLtext' { $1++[Astring $2] } | content element { $1++[$2] } +string :: { Ast }+string : stringc { if length $1 == 1 then head $1 else Ast "append" $1 }++stringc :: { [Ast] }+stringc : 'String' { if $1=="" then [] else [Astring $1] }+ | '{' expl '}' { [concatenateAll $2] }+ | stringc 'String' { if $2=="" then $1 else $1++[Astring $2] }+ | stringc '{' expl '}' { $1++[concatenateAll $3] }+ attributes :: { [ Ast ] }-attributes : 'QName' '=' 'String' { [Ast "pair" [Astring $1,Astring $3]] }- | 'QName' '=' '\'{' expr '}\'' { [Ast "pair" [Astring $1,$4]] }- | attributes 'QName' '=' 'String' { $1++[Ast "pair" [Astring $2,Astring $4]] }- | attributes 'QName' '='- '\'{' expr '}\'' { $1++[Ast "pair" [Astring $2,$5]] }+attributes : 'QName' '=' string { [Ast "pair" [Astring $1,$3]] }+ | attributes 'QName' '=' string { $1++[Ast "pair" [Astring $2,$4]] } full_path :: { Ast } full_path : predicate_step { Ast "step" ($1 "child_step" (Avar ".")) }@@ -290,13 +296,10 @@ then concatenateAll $2 else Ast "context" [e,Astring t,concatenateAll $2] } | '(' ')' { \_ _ -> call "empty" [] }- | 'QName' '(' expl ')' { \_ e -> if e == Avar "."+ | 'QName' '(' expl ')' { \t e -> if e == Avar "." then call $1 $3- else Ast "context" [e,call $1 $3] }- | 'QName' '(' ')' { if elem $1 ["text"]- then \_ e -> call $1 [e]- else \_ _ -> call $1 [] }-+ else Ast "context" [e,Astring t,call $1 $3] }+ | 'QName' '(' ')' { \_ e -> call $1 (if e == Avar "." then [] else [e]) } { @@ -311,8 +314,8 @@ instance Show Ast where show (Ast s []) = s ++ "()"- show (Ast s (x:xs)) = s ++ "(" ++ (show x)- ++ (foldr (\a r -> ","++(show a)++r) "" xs)+ show (Ast s (x:xs)) = s ++ "(" ++ show x+ ++ foldr (\a r -> ","++show a++r) "" xs ++ ")" show (Avar s) = s show (Aint n) = show n@@ -320,23 +323,45 @@ show (Astring s) = "\'" ++ s ++ "\'" +screenSize = 80::Int++prettyAst :: Ast -> Int -> (String,Int)+prettyAst (Avar s) p = (s,(length s)+p)+prettyAst (Aint n) p = let s = show n in (s,(length s)+p)+prettyAst (Afloat n) p = let s = show n in (s,(length s)+p)+prettyAst (Astring s) p = ("\'" ++ s ++ "\'",(length s)+p+2)+prettyAst (Ast s args) p+ = let (ps,np) = prettyArgs args+ in (s++"("++ps++")",np+1)+ where prettyArgs [] = ("",p+1)+ prettyArgs xs = let ss = show (head xs) ++ foldr (\a r -> ","++show a++r) "" (tail xs)+ np = (length s)+p+1+ in if (length ss)+p < screenSize+ then (ss,(length ss)+p)+ else let ds = map (\x -> let (s,ep) = prettyAst x np+ in (s ++ ",\n" ++ space np,ep)) (init xs)+ (ls,lp) = prettyAst (last xs) np+ in (concatMap fst ds ++ ls,lp)+ space n = replicate n ' '+++ppAst :: Ast -> String+ppAst e = let (s,_) = prettyAst e 0 in s++ call :: String -> [Ast] -> Ast call name args = Ast "call" ((Avar name):args) concatenateAll :: [Ast] -> Ast+concatenateAll [x] = x concatenateAll (x:xs) = foldl (\a r -> call "concatenate" [a,r]) x xs concatenateAll _ = call "empty" [] -concatAll :: [Ast] -> Ast-concatAll (x:xs) = foldl (\a r -> call "concat" [a,r]) x xs-concatAll _ = call "empty" []-- data Token = RETURN | SOME | EVERY | IF | THEN | ELSE | LB | RB | LP | RP | LSB | RSB- | LESCAPE | RESCAPE | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD+ | TO | PLUS | MINUS | TIMES | DIV | IDIV | MOD | TEQ | TNE | TLT | TLE | TGT | TGE | SEQ | SNE | SLT | SLE | SGT | SGE | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT@@ -354,6 +379,7 @@ show (TInteger n) = "Integer("++(show n)++")" show (TFloat n) = "Double("++(show n)++")" show (TString s) = "String("++s++")"+ show (TError s) = "'"++s++"'" show t = case filter (\(n,_) -> n==t) tokenList of (_,b):_ -> b _ -> "Illegal token"@@ -361,7 +387,7 @@ tokenList :: [(Token,String)] tokenList = [(RETURN,"return"),(SOME,"some"),(EVERY,"every"),(IF,"if"),(THEN,"then"),(ELSE,"else"),- (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"),(LESCAPE,"\"{"),(RESCAPE,"}\""),+ (LB,"["),(RB,"]"),(LP,"("),(RP,")"),(LSB,"{"),(RSB,"}"), (TO,"to"),(PLUS,"+"),(MINUS,"-"),(TIMES,"*"),(DIV,"div"),(IDIV,"idiv"),(MOD,"mod"), (TEQ,"="),(TNE,"!="),(TLT,"<"),(TLE,"<="),(TGT,">"),(TGE,">="),(PRE,"<<"),(POST,">>"), (IS,"is"),(SEQ,"eq"),(SNE,"ne"),(SLT,"lt"),(SLE,"le"),(SGT,"gt"),(SGE,"ge"),(AND,"and"),@@ -373,50 +399,60 @@ (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";")] -parseError [] = error "Reached end-of-input"-parseError [_] = error "Reached end-of-input"-parseError tk = error("Parse error: "++(show (take 10 (init tk))))+parseError tk = error (case tk of+ ((TError s):_) -> "Parse error: "++s+ _ -> "Parse error: "++(foldr (\a r -> (show a)++" "++r) "" (take 20 tk))) scan :: String -> [Token]-scan cs = lexer cs [0]+scan cs = lexer cs "" + xmlText :: String -> [Token] xmlText "" = [] xmlText text = [XMLtext text] + -- scans XML syntax and returns an XMLtext token with the text-xml :: String -> String -> [Int] -> [Token]-xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs (0:n))-xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs n)+xml :: String -> String -> String -> [Token]+xml ('{':cs) text n = (xmlText text)++(LSB : lexer cs ('{':n))+xml ('<':'/':cs) text n = (xmlText text)++(STAG : lexer cs ('<':'/':n)) xml ('<':'!':'-':cs) text n = xmlComment cs (text++"<!-") n-xml ('<':cs) text (k:n) = (xmlText text)++(TLT : lexer cs (k+2:n))-xml ('\'':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)-xml ('\"':'{':cs) text n = (xmlText text)++(LESCAPE : lexer cs n)+xml ('<':cs) text n = (xmlText text)++(TLT : lexer cs ('<':n)) xml ('(':':':cs) text n = xqComment cs text n xml (c:cs) text n = xml cs (text++[c]) n xml [] text _ = xmlText text -xqComment :: String -> String -> [Int] -> [Token]++xqComment :: String -> String -> String -> [Token] xqComment (':':')':cs) text n = xml cs text n xqComment (_:cs) text n = xqComment cs text n xqComment [] text _ = xmlText text -xmlComment :: String -> String -> [Int] -> [Token]++xmlComment :: String -> String -> String -> [Token] xmlComment ('-':'>':cs) text n = xml cs (text++"->") n xmlComment (c:cs) text n = xmlComment cs (text++[c]) n xmlComment [] text _ = xmlText text + isQN :: Char -> Bool isQN c = elem c "_:-" || isDigit c || isAlpha c + isVar :: Char -> Bool isVar c = elem c "_" || isDigit c || isAlpha c ++inXML :: String -> Bool+inXML ('>':'<':_) = True+inXML _ = False++ -- the XQuery scanner-lexer :: String -> [Int] -> [Token]-lexer [] [0] = []-lexer [] _ = error "Unbalanced tags"+lexer :: String -> String -> [Token]+lexer [] "" = []+lexer [] _ = [ TError "Unexpected end of input" ] lexer (' ':'>':' ':cs) n = TGT : lexer cs n lexer (c:cs) n | isSpace c = lexer cs n@@ -425,46 +461,50 @@ lexer ('$':c:cs) n | isAlpha c = let (var,rest) = span isVar (c:cs) in (Variable var) : lexer rest n-lexer ('\'':'{':cs) n = LESCAPE : lexer cs n-lexer ('\"':'{':cs) n = LESCAPE : lexer cs n lexer (':':'=':cs) n = ASSIGN : lexer cs n-lexer ('<':'/':cs) n = STAG : lexer cs n+lexer ('<':'/':cs) n = STAG : lexer cs ('<':'/':n) lexer ('<':'=':cs) n = TLE : lexer cs n lexer ('>':'=':cs) n = TGE : lexer cs n lexer ('<':'<':cs) n = PRE : lexer cs n lexer ('>':'>':cs) n = POST : lexer cs n-lexer ('/':'>':cs) (k:n) = ETAG : lexer cs (k-2:n)+lexer ('/':'>':cs) m = case m of+ '<':n -> ETAG : (if inXML n then xml cs "" n else lexer cs n)+ _ -> [ TError "Unexpected token: '/>'" ] lexer ('(':':':cs) n = lexComment cs n lexer ('<':'!':'-':cs) n = lexXmlComment cs "<!-" n lexer ('.':'.':cs) n = DOTS : lexer cs n lexer ('.':cs) n = DOT : lexer cs n-lexer ('}':'\'':cs) n = RESCAPE : lexer cs n-lexer ('}':'\"':cs) n = RESCAPE : lexer cs n lexer ('!':'=':cs) n = TNE : lexer cs n-lexer ('\'':cs) n = lexString cs n-lexer ('\"':cs) n = lexString2 cs n+lexer ('\'':cs) n = lexString cs "" ('\'':n)+lexer ('\"':cs) n = lexString cs "" ('\"': n) lexer ('[':cs) n = LB : lexer cs n lexer (']':cs) n = RB : lexer cs n lexer ('(':cs) n = LP : lexer cs n lexer (')':cs) n = RP : lexer cs n-lexer ('}':cs) [_,n] = RSB : lexer cs [n]-lexer ('}':cs) (_:n:ns) = RSB : (if n==0 then lexer cs (n:ns) else xml cs "" (n:ns))+lexer ('}':cs) m = case m of+ '{':'\"':n -> RSB : lexString cs "" ('\"':n)+ '{':'\'':n -> RSB : lexString cs "" ('\'':n)+ '{':n -> RSB : (if inXML n then xml cs "" n else lexer cs n)+ _ -> [ TError "Unexpected token: '}'" ] lexer ('+':cs) n = PLUS : lexer cs n lexer ('-':cs) n = MINUS : lexer cs n lexer ('*':cs) n = TIMES : lexer cs n lexer ('=':cs) n = TEQ : lexer cs n-lexer ('<':c:cs) n | not(isAlpha c) = TLT : lexer (c:cs) n-lexer ('<':cs) (k:n) = TLT : lexer cs (k+2:n)-lexer ('>':cs) (k:n) = TGT : (if k==1 then lexer cs (0:n) else xml cs "" (k-1:n))+lexer ('<':c:cs) n = TLT : (lexer (c:cs) (if isAlpha c then ('<':n) else n))+lexer ('>':cs) m = case m of+ '<':'/':'>':'<':n -> TGT : (if inXML n then xml cs "" n else lexer cs n)+ '<':n -> TGT : xml cs "" ('>':m) + _ -> TGT : lexer cs m lexer (',':cs) n = COMMA : lexer cs n lexer ('@':cs) n = ATSIGN : lexer cs n lexer ('/':cs) n = SLASH : lexer cs n-lexer ('{':cs) n = LSB : lexer cs (0:n)+lexer ('{':cs) n = LSB : lexer cs ('{':n) lexer ('|':cs) n = UNION : lexer cs n lexer (';':cs) n = SEMI : lexer cs n-lexer (c:cs) n = error("Illegal character "++[c])+lexer (c:cs) n = TError ("Illegal character: '"++[c,'\'']) : lexer cs n -lexNum :: String -> [Int] -> [Token]++lexNum :: String -> String -> [Token] lexNum cs n = if null rest || head rest /= '.' then TInteger (read k) : lexer rest n else let (m,rest2) = span isDigit (tail rest)@@ -475,66 +515,73 @@ _ -> (TFloat val) : lexer rest2 n where (k,rest) = span isDigit cs -lexString :: String -> [Int] -> [Token]-lexString cs n = TString s : lexer (tail rest) n- where (s,rest) = span inString cs- inString c = c /= '\'' -lexString2 :: String -> [Int] -> [Token]-lexString2 cs n = TString s : lexer (tail rest) n- where (s,rest) = span inString cs- inString c = c /= '\"'+lexString :: String -> String -> String -> [Token]+lexString ('\"':cs) s m = case m of+ '\"':n -> (TString s) : (lexer cs n)+ _ -> lexString cs (s++"\"") m+lexString ('\'':cs) s m = case m of+ '\'':n -> (TString s) : (lexer cs n)+ _ -> lexString cs (s++"\'") m+lexString ('{':cs) s n = (TString s) : LSB : (lexer cs ('{':n))+lexString (c:cs) s n = lexString cs (s++[c]) n+lexString [] s n = [ TError "End of input while in string" ] -lexComment :: String -> [Int] -> [Token]++lexComment :: String -> String -> [Token] lexComment (':':')':cs) n = lexer cs n lexComment (_:cs) n = lexComment cs n-lexComment [] n = []+lexComment [] n = [ TError "End of input while in comment" ] -lexXmlComment :: String -> String -> [Int] -> [Token]++lexXmlComment :: String -> String -> String -> [Token] lexXmlComment ('-':'>':cs) text n = (xmlText (text++"->"))++(lexer cs n) lexXmlComment (c:cs) text n = lexXmlComment cs (text++[c]) n lexXmlComment [] text _ = xmlText text -lexVar :: String -> [Int] -> [Token]++lexVar :: String -> String -> [Token] lexVar cs n =- case span isQN cs of- ("return",rest) -> RETURN : lexer rest n- ("some",rest) -> SOME : lexer rest n- ("every",rest) -> EVERY : lexer rest n- ("if",rest) -> IF : lexer rest n- ("then",rest) -> THEN : lexer rest n- ("else",rest) -> ELSE : lexer rest n- ("to",rest) -> TO : lexer rest n- ("div",rest) -> DIV : lexer rest n- ("idiv",rest) -> IDIV : lexer rest n- ("mod",rest) -> MOD : lexer rest n- ("and",rest) -> AND : lexer rest n- ("or",rest) -> OR : lexer rest n- ("not",rest) -> NOT : lexer rest n- ("union",rest) -> UNION : lexer rest n- ("intersect",rest) -> INTERSECT : lexer rest n- ("except",rest) -> EXCEPT : lexer rest n- ("for",rest) -> FOR : lexer rest n- ("let",rest) -> LET : lexer rest n- ("in",rest) -> IN : lexer rest n- ("where",rest) -> WHERE : lexer rest n- ("order",rest) -> ORDER : lexer rest n- ("by",rest) -> BY : lexer rest n- ("ascending",rest) -> ASCENDING : lexer rest n- ("descending",rest) -> DESCENDING : lexer rest n- ("element",rest) -> ELEMENT : lexer rest n- ("attribute",rest) -> ATTRIBUTE : lexer rest n- ("satisfies",rest) -> SATISFIES : lexer rest n- ("declare",rest) -> DECLARE : lexer rest n- ("function",rest) -> FUNCTION : lexer rest n- ("variable",rest) -> VARIABLE : lexer rest n- ("at",rest) -> AT : lexer rest n- ("eq",rest) -> SEQ : lexer rest n- ("ne",rest) -> SNE : lexer rest n- ("lt",rest) -> SLT : lexer rest n- ("le",rest) -> SLE : lexer rest n- ("gt",rest) -> SGT : lexer rest n- ("ge",rest) -> SGE : lexer rest n- ("is",rest) -> IS : lexer rest n- (var,rest) -> QName var : lexer rest n+ let (nm,rest) = span isQN cs+ in (case nm of+ "return" -> RETURN+ "some" -> SOME+ "every" -> EVERY+ "if" -> IF+ "then" -> THEN+ "else" -> ELSE+ "to" -> TO+ "div" -> DIV+ "idiv" -> IDIV+ "mod" -> MOD+ "and" -> AND+ "or" -> OR+ "not" -> NOT+ "union" -> UNION+ "intersect" -> INTERSECT+ "except" -> EXCEPT+ "for" -> FOR+ "let" -> LET+ "in" -> IN+ "where" -> WHERE+ "order" -> ORDER+ "by" -> BY+ "ascending" -> ASCENDING+ "descending" -> DESCENDING+ "element" -> ELEMENT+ "attribute" -> ATTRIBUTE+ "satisfies" -> SATISFIES+ "declare" -> DECLARE+ "function" -> FUNCTION+ "variable" -> VARIABLE+ "at" -> AT+ "eq" -> SEQ+ "ne" -> SNE+ "lt" -> SLT+ "le" -> SLE+ "gt" -> SGT+ "ge" -> SGE+ "is" -> IS+ var -> QName var+ ) : lexer rest n }
data/q1.xq view
@@ -4,8 +4,8 @@ declare function f ( $name, $gpa ) { <student>{ $name/firstname/text(),- ' ',$name/lastname/text(),- ': ',$gpa+ $name/lastname/text(),+ ':',$gpa }</student> };
+ data/q3.xq view
@@ -0,0 +1,8 @@+<result>{+let $a := distinct-values(doc("data/cs.xml")//gradstudent)+for $s in $a+return <st>{+ doc("data/cs.xml")//gradstudent[.//lastname = $s//lastname]//name,+ count(.//*)+ }</st>+}</result>
hxml-0.2/XMLScanner.hs view
@@ -168,7 +168,8 @@ doEntityRef entities k r = doSpan (';'/=) (++) replacement (k . drop1) r where replacement ename = case DTD.expandInternalEntity entities ename of Just s -> s- _ -> error ("entity " ++ ename ++ " not defined")+-- changed by Leonidas Fegaras 5/27/08+ _ -> "" -- error ("entity " ++ ename ++ " not defined") -- [...] markupMode [] = []
index.html view
@@ -26,24 +26,26 @@ Also <a href="http://xqilla.sourceforge.net/HomePage">XQilla</a>, which is written in C++, took 1 minute and 10 secs (using 1150MB of heap space). (All results are taken on an Intel Core 2 Duo 2.2GHz 2GB running ghc-6.8.2 on Linux 2.6.23 kernel.) <p>-HXQ uses the <a href="http://www.flightlab.com/~joe/hxml/">HXML parser for XML</a> (developed by Joe English),-which is included in the source.-I have also tried hexpat, tagsoup, HXT, and HaXML Xtract, but they all have space leaks.-For example, when I replaced the HXML parser with <a href="http://www-users.cs.york.ac.uk/~ndm/tagsoup/">tagsoup</a>-in HXQ, it required more than 3GB heap space for the above query-and gave partial results.+Finally, HXQ can store XML documents in a relational database (currently SQLite), by shredding XML into relational+tuples, and by translating XQueries over the shredded documents into optimized SQL queries. <p> <h2>Installation Instructions</h2> <p> First, you need to install the Glasgow Haskell Compiler, <a href="http://www.haskell.org/ghc/">ghc</a>,-and the parser generator for Haskell,-<a href="http://www.haskell.org/happy/">happy</a>.-For example, in Fedora Linux, you install both using:+the parser generator for Haskell,+<a href="http://www.haskell.org/happy/">happy</a>,+and <a href="http://sqlite.org/">SQLite</a> for database connectivity (optional).+For example, in Fedora Linux, you install them using: <pre>-yum install ghc happy+yum install ghc happy sqlite </pre>-Then download <a href="/HXQ-0.8.tar.gz">HXQ</a> and untar it.+Then, you need to install the haskell packages: <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC">HDBC</a>+and the+<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a> driver+to connect to SQLite relational databases.+<p>+Finally, download <a href="/HXQ-0.8.3.tar.gz">HXQ</a> and untar it. You can use either make or cabal to build it. To build it with cabal, you do: <pre> runhaskell Setup.lhs configure --prefix=$HOME@@ -51,7 +53,7 @@ runhaskell Setup.lhs install </pre> (The last command must be run as root.)-It will create the executable <tt>xquery</tt>, which is the XQuery interepreter, and the HXQ library.+It will create the executable <tt>xquery</tt>, which is the XQuery interpreter, and the HXQ library. To use the library, you run ghc or ghci with <tt>-package HXQ</tt>. <p> <h2>Current Status</h2>@@ -64,9 +66,12 @@ Some, but not all, parent axis steps are removed using optimization rules; all others cause a compilation error. Finally, the XQuery semantics requires duplicate elimination and sorting by document order for every XPath step, which is very expensive and unnecessary in most cases.-For exmple, <tt>e//*//*</tt> may return duplicate elements in HXQ.+For example, <tt>e//*//*</tt> may return duplicate elements in HXQ. This will be addressed in the future (needs a static analysis to determine when duplicate elimination is necessary). <p>+HXQ uses the <a href="http://www.flightlab.com/~joe/hxml/">HXML parser for XML</a> (developed by Joe English),+which is included in the source. I have also tried hexpat, tagsoup, HXT, and HaXML Xtract, but they all have space leaks.+<p> <h2>Using the Compiler</h2> <p> The main functions for embedding XQueries in Haskell are:@@ -131,16 +136,34 @@ <tt>xquery -p "//inproceedings[100]" data/dblp.xml</tt>. With <tt>xquery -help</tt> you get the list of system functions and usage information. <p>-<h2>Experimental Features</h2>+<h2>Database Connectivity</h2> <p>-There is an experimental interface to HDBC to query relational data inside an XQuery.-To use it, you need to install <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC">HDBC</a>-and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a>-(or some other HDBC driver, such ODBC). The main function is-<tt>$(xqdb query) :: (IConnection conn) => conn -> IO XSeq</tt>.-The XQuery may contain multiple SQL queries in the form <tt>sql(query,args)</tt>,-where <tt>query</tt> is the sql query that may contain parameters (denoted by ?), which are bound to the values in <tt>args</tt>.-An example can be found in <a href="TestDB.hs">TestDB.hs</a>. To run it, you need+HXQ provides an interface to HDBC to query relational data inside an XQuery.+For the HXQ compiler, the main function that allows database connectivity is:+<pre>+$(xqdb query) :: (IConnection conn) => conn -> IO XSeq+</pre>+For example, if the database name is "myDB", then+<pre>+do db <- connect "myDB"+ result <- $(xqdb xquery) db+</pre>+For the HXQ interpreter, the function is:+<pre>+xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq+</pre>+The xquery executable can also run xqueries that use a database by specifying the database name using the -db option.+<p>+Currently, HXQ works with <a href="http://sqlite.org/">SQLite</a> only, but is very easy to make it work+with any relational database that supports ODBC: simply install +<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-odbc">HDBC-odbc</a>+and change the file <a href="XML/HXQ/DBConnect.hs">XML/HXQ/DBConnect.hs</a> accordingly.+<p>+<h3>Querying an Existing Database</h3>+<p>+An XQuery may contain multiple SQL queries in the form <tt>sql(query,args)</tt>,+where <tt>query</tt> is the sql query that may contain parameters (denoted by ?), which are bound to the values in <tt>args</tt> (an XSeq).+An example can be found in <a href="TestDB.hs">TestDB.hs</a>. To run this example, you need to install the <a href="data/company.sql">company</a> database. For example, using the sqlite3 interpreter, you do: <pre>@@ -148,17 +171,52 @@ .read data/company.sql .quit </pre>-and then you do <tt>make testdb</tt> on linux.+and then compile and run <tt>TestDB.hs</tt> (or just do <tt>make test3</tt> on linux). <p>-Finally, there is an experimental+<h3>Shredding</h3>+<p>+To store an XML document into a relational database, use the following Haskell function:+<pre>+shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred db file name+</pre>+that shreds and stores the XML document located at the file pathname in the database db under a unique name.+HXQ will find a good relational schema (using hybrid inlining) to store the XML data by first scanning the document to+extract its structural summary, then deriving a good relational schema, and finally scanning the document+for a second time to store its data into the relational tables. For example,+<pre>+do db <- connect "myDB"+ shred db "data/cs.xml" "c"+</pre>+<p>+The haskell function+<pre>+createIndex db name tagname+</pre>+creates a secondary index on tagname for the shredded document under the given name.+<p>+<h3>Publishing</h3>+<p>+You can query a shredded XML document using the XQuery function:+<pre>+publish(dbame,name)+</pre>+where dbname is the database file name and name is the unique name assigned to the XML document when was shredded.+The translation from XQuery to SQL is done at compile-time, so both dbname and name must be constant strings.+HXQ will do its best to push relevant predicates to the generated SQL query (using partial evaluation and code folding),+thus deriving an efficient execution. One example is <a href="TestDB2.hs">TestDB2.hs</a> (do <tt>make test4</tt> to run it on linux).+<p>+<h2>Experimental Features</h2>+<p>+There is an experimental program, called <tt>hxqc</tt>, that works like <tt>xquery</tt> but is faster because it uses the-HXQ compiler instead of the interpreter. It's constracted with the Unix Makefile (<tt>make hxqc</tt>).+HXQ compiler instead of the interpreter. It's constructed with the Unix Makefile (<tt>make hxqc</tt>). It is unstable and the <tt>hxqc</tt> executable is 10 times larger than <tt>xquery</tt> since it uses the ghc libraries at run-time. Also, although it is faster than the interpreter, it is slower than a-compiled xquery since it uses part of the heap for the ghc compiler to compile Haskell code on-the-fly.+compiled xquery because it uses part of the heap for the ghc compiler to compile Haskell code on-the-fly. <p> </body> <p> <hr> <p>-<address>Last modified: 05/13/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 06/12/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
− profile.hs
@@ -1,20 +0,0 @@-{-# OPTIONS_GHC -fth #-}--module Main where--import XML.HXQ.XTree-import XML.HXQ.Parser-import XML.HXQ.Compiler-import XMLParse(parseDocument)-import IO--main = do let [XText f_0] = [XText "data/dblp.xml"]- doc_1 <- readFile f_0- res <- (\_doc0 -> return (foldr (\x_2 -> (\x -> \r_3 -> foldir (\x_4 i_5 r_6 -> if case [trueXT | x_7 <- text (foldr (\a_8 s_9 -> child_step "author" a_8 ++ s_9) [] (x :: XSeq)),- y_10 <- text [XText "David Maier"],- compareXTrees x_7 y_10 == EQ] of- [XInt k_11] -> k_11 == i_5- b_12 -> conditionTest b_12- then x_4 : r_6- else r_6) [] [XElem "paper" [] 0 ((text (foldr (\a_13 s_14 -> child_step "booktitle" a_13 ++ s_14) [] (x :: XSeq)) ++ [XText ": "]) ++ text (foldr (\a_15 s_16 -> child_step "title" a_15 ++ s_16) [] (x :: XSeq)))] 1 ++ r_3) [x_2]) [] (foldr (\a_17 s_18 -> descendant_step "inproceedings" a_17 ++ s_18) [] [_doc0]))) (materialize (parseDocument doc_1))- putXSeq res