EditTimeReport (empty) → 1.0
raw patch · 13 files changed
+3362/−0 lines, 13 filesdep +arraydep +basedep +containerssetup-changed
Dependencies added: array, base, containers, csv, directory, editline, filepath, haskell98, html, pretty, xhtml
Files
- EditTimeReport.cabal +29/−0
- Edits.hs +125/−0
- LICENSE +674/−0
- Main.hs +93/−0
- Printers.hs +152/−0
- Query.hs +376/−0
- QueryAST.hs +33/−0
- QueryLexer.x +159/−0
- QueryParser.y +153/−0
- Setup.hs +2/−0
- Stats.hs +187/−0
- dist/build/report/report-tmp/QueryLexer.hs +482/−0
- dist/build/report/report-tmp/QueryParser.hs +897/−0
+ EditTimeReport.cabal view
@@ -0,0 +1,29 @@+Name: EditTimeReport+Version: 1.0+Cabal-Version: >= 1.2+License: GPL+License-file: LICENSE+Author: Bart Spaans+Maintainer: Bart Spaans <bart.spaans@gmail.com>+Synopsis: Query language and report generator for edit logs.+Description: This program can be used to see exactly how much time + you spent working on file X, project Y or language Z. + It can also be used to see for instance what your most + productive time of the year, month or week is. ++ In the long-run, this might help you make better time + estimates, while also providing you with an overview + of what you have worked on (which can also be nice for CV's).+ In short; this program allows you to query your logs+ and generate reports in plain text, html, xhtml and CSV.+ Support for more output formats is planned for the future.+ See the github page for more information.+Homepage: http://github.com/bspaans/EditTimeReport+Category: Utils+Bug-Reports: mailto:bart.spaans@gmail.com+Build-Type: Simple++Executable report+ Main-Is: Main.hs+ Build-Depends: base >= 3 && < 5, haskell98, xhtml, html, pretty, filepath, containers, array, editline, directory, csv+ Other-Modules: QueryLexer, QueryParser, Edits, Printers, Query, QueryAST, Stats
+ Edits.hs view
@@ -0,0 +1,125 @@+-- | Provides a low level view of the log file.++module Edits ( -- * AST+ Edits, Edit(..),+ -- ** Parsing+ editsFromFile, + -- * Grouping+ groupWith , fileGroup,+ -- ** Predicates+ Pred,+ -- * Calendars+ Calendar(..), flatten, + -- ** Calendar of Edits+ calendarE, CalendarE + ) where+++import Char+import Maybe (mapMaybe)+import Control.Applicative+import Data.List as L (groupBy)+import qualified Data.Map as D hiding (map, filter, mapMaybe)+import System.FilePath++++-- | Abstract syntax for an editor log entry.+--+data Edit = Edit { year :: Int+ , month :: Int+ , day :: Int+ , hour :: Int+ , minute :: Int+ , seconds :: Int+ , dow :: Int -- ^ Day of the week+ , doy :: Int -- ^ Day of the year+ , file :: FilePath } deriving (Show, Eq)+type Edits = [Edit]+++++-- | Parses log files generated by timechartd.py +-- daemon or editor.+--+editsFromFile :: FilePath -> IO Edits+editsFromFile f = parseEdits <$> readFile f+++parseEdits :: String -> Edits+parseEdit :: String -> Maybe Edit++parseEdits = mapMaybe parseEdit . lines+parseEdit s = if a then Just $ Edit y m d h mi se dw dy (unwords (drop 9 w))+ else Nothing+ where w = words s+ i = take 8 w+ a = length w >= 9 && all (all isDigit) i && w !! 8 == "EDIT"+ (y:m:d:h:mi:se:dw:dy:[]) = map read i+++-- | A simple abstraction for predicates +--+type Pred a = a -> Bool+++++-- | Use a function's result to group by.+--+groupWith :: Eq a => (b -> a) -> [b] -> [[b]]+groupWith y = groupBy (\f g -> y f == y g)++-- | Group Edits on year.+--+yearGroup :: Edits -> [Edits]+yearGroup = groupWith year++-- | Group Edits on month.+--+monthGroup :: Edits -> [Edits]+monthGroup = groupWith month++-- | Group Edits on day of the month.+--+dayGroup :: Edits -> [Edits]+dayGroup = groupWith day++-- | Group Edits on file name.+--+fileGroup :: Edits -> [Edits]+fileGroup = groupWith file+++-- | The Calendar type is an abstraction over lists of days in +-- lists of months in lists of years:+--+-- > [ [ [ a ] ] ]+-- > | | + years+-- > | + months+-- > + days +--+newtype Calendar a = Calendar [[[a]]] deriving (Eq, Show)++instance Functor Calendar where+ fmap f (Calendar as) = Calendar (map (map (map f)) as)+++-- Getting items out of the Calendar container+--+fromCalendar :: Calendar a -> [[[a]]]+flatten :: Calendar a -> [a]++fromCalendar (Calendar as) = as+flatten = concat . concat . fromCalendar+++-- Calendar of Edits+-- Using the grouping functions to build it.+-- Expects a chronological list of edits.+--+type CalendarE = Calendar Edits++calendarE :: Edits -> CalendarE+calendarE = Calendar . map (map dayGroup . monthGroup) . yearGroup
+ LICENSE view
@@ -0,0 +1,674 @@+ GNU GENERAL PUBLIC LICENSE+ Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The GNU General Public License is a free, copyleft license for+software and other kinds of works.++ The licenses for most software and other practical works are designed+to take away your freedom to share and change the works. By contrast,+the GNU General Public License is intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users. We, the Free Software Foundation, use the+GNU General Public License for most of our software; it applies also to+any other work released this way by its authors. You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++ To protect your rights, we need to prevent others from denying you+these rights or asking you to surrender the rights. Therefore, you have+certain responsibilities if you distribute copies of the software, or if+you modify it: responsibilities to respect the freedom of others.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must pass on to the recipients the same+freedoms that you received. You must make sure that they, too, receive+or can get the source code. And you must show them these terms so they+know their rights.++ Developers that use the GNU GPL protect your rights with two steps:+(1) assert copyright on the software, and (2) offer you this License+giving you legal permission to copy, distribute and/or modify it.++ For the developers' and authors' protection, the GPL clearly explains+that there is no warranty for this free software. For both users' and+authors' sake, the GPL requires that modified versions be marked as+changed, so that their problems will not be attributed erroneously to+authors of previous versions.++ Some devices are designed to deny users access to install or run+modified versions of the software inside them, although the manufacturer+can do so. This is fundamentally incompatible with the aim of+protecting users' freedom to change the software. The systematic+pattern of such abuse occurs in the area of products for individuals to+use, which is precisely where it is most unacceptable. Therefore, we+have designed this version of the GPL to prohibit the practice for those+products. If such problems arise substantially in other domains, we+stand ready to extend this provision to those domains in future versions+of the GPL, as needed to protect the freedom of users.++ Finally, every program is threatened constantly by software patents.+States should not allow patents to restrict development and use of+software on general-purpose computers, but in those that do, we wish to+avoid the special danger that patents applied to a free program could+make it effectively proprietary. To prevent this, the GPL assures that+patents cannot be used to render the program non-free.++ The precise terms and conditions for copying, distribution and+modification follow.++ TERMS AND CONDITIONS++ 0. Definitions.++ "This License" refers to version 3 of the GNU General Public License.++ "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++ "The Program" refers to any copyrightable work licensed under this+License. Each licensee is addressed as "you". "Licensees" and+"recipients" may be individuals or organizations.++ To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy. The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++ A "covered work" means either the unmodified Program or a work based+on the Program.++ To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy. Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++ To "convey" a work means any kind of propagation that enables other+parties to make or receive copies. Mere interaction with a user through+a computer network, with no transfer of a copy, is not conveying.++ An interactive user interface displays "Appropriate Legal Notices"+to the extent that it includes a convenient and prominently visible+feature that (1) displays an appropriate copyright notice, and (2)+tells the user that there is no warranty for the work (except to the+extent that warranties are provided), that licensees may convey the+work under this License, and how to view a copy of this License. If+the interface presents a list of user commands or options, such as a+menu, a prominent item in the list meets this criterion.++ 1. Source Code.++ The "source code" for a work means the preferred form of the work+for making modifications to it. "Object code" means any non-source+form of a work.++ A "Standard Interface" means an interface that either is an official+standard defined by a recognized standards body, or, in the case of+interfaces specified for a particular programming language, one that+is widely used among developers working in that language.++ The "System Libraries" of an executable work include anything, other+than the work as a whole, that (a) is included in the normal form of+packaging a Major Component, but which is not part of that Major+Component, and (b) serves only to enable use of the work with that+Major Component, or to implement a Standard Interface for which an+implementation is available to the public in source code form. A+"Major Component", in this context, means a major essential component+(kernel, window system, and so on) of the specific operating system+(if any) on which the executable work runs, or a compiler used to+produce the work, or an object code interpreter used to run it.++ The "Corresponding Source" for a work in object code form means all+the source code needed to generate, install, and (for an executable+work) run the object code and to modify the work, including scripts to+control those activities. However, it does not include the work's+System Libraries, or general-purpose tools or generally available free+programs which are used unmodified in performing those activities but+which are not part of the work. For example, Corresponding Source+includes interface definition files associated with source files for+the work, and the source code for shared libraries and dynamically+linked subprograms that the work is specifically designed to require,+such as by intimate data communication or control flow between those+subprograms and other parts of the work.++ The Corresponding Source need not include anything that users+can regenerate automatically from other parts of the Corresponding+Source.++ The Corresponding Source for a work in source code form is that+same work.++ 2. Basic Permissions.++ All rights granted under this License are granted for the term of+copyright on the Program, and are irrevocable provided the stated+conditions are met. This License explicitly affirms your unlimited+permission to run the unmodified Program. The output from running a+covered work is covered by this License only if the output, given its+content, constitutes a covered work. This License acknowledges your+rights of fair use or other equivalent, as provided by copyright law.++ You may make, run and propagate covered works that you do not+convey, without conditions so long as your license otherwise remains+in force. You may convey covered works to others for the sole purpose+of having them make modifications exclusively for you, or provide you+with facilities for running those works, provided that you comply with+the terms of this License in conveying all material for which you do+not control copyright. Those thus making or running the covered works+for you must do so exclusively on your behalf, under your direction+and control, on terms that prohibit them from making any copies of+your copyrighted material outside their relationship with you.++ Conveying under any other circumstances is permitted solely under+the conditions stated below. Sublicensing is not allowed; section 10+makes it unnecessary.++ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.++ No covered work shall be deemed part of an effective technological+measure under any applicable law fulfilling obligations under article+11 of the WIPO copyright treaty adopted on 20 December 1996, or+similar laws prohibiting or restricting circumvention of such+measures.++ When you convey a covered work, you waive any legal power to forbid+circumvention of technological measures to the extent such circumvention+is effected by exercising rights under this License with respect to+the covered work, and you disclaim any intention to limit operation or+modification of the work as a means of enforcing, against the work's+users, your or third parties' legal rights to forbid circumvention of+technological measures.++ 4. Conveying Verbatim Copies.++ You may convey verbatim copies of the Program's source code as you+receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice;+keep intact all notices stating that this License and any+non-permissive terms added in accord with section 7 apply to the code;+keep intact all notices of the absence of any warranty; and give all+recipients a copy of this License along with the Program.++ You may charge any price or no price for each copy that you convey,+and you may offer support or warranty protection for a fee.++ 5. Conveying Modified Source Versions.++ You may convey a work based on the Program, or the modifications to+produce it from the Program, in the form of source code under the+terms of section 4, provided that you also meet all of these conditions:++ a) The work must carry prominent notices stating that you modified+ it, and giving a relevant date.++ b) The work must carry prominent notices stating that it is+ released under this License and any conditions added under section+ 7. This requirement modifies the requirement in section 4 to+ "keep intact all notices".++ c) You must license the entire work, as a whole, under this+ License to anyone who comes into possession of a copy. This+ License will therefore apply, along with any applicable section 7+ additional terms, to the whole of the work, and all its parts,+ regardless of how they are packaged. This License gives no+ permission to license the work in any other way, but it does not+ invalidate such permission if you have separately received it.++ d) If the work has interactive user interfaces, each must display+ Appropriate Legal Notices; however, if the Program has interactive+ interfaces that do not display Appropriate Legal Notices, your+ work need not make them do so.++ A compilation of a covered work with other separate and independent+works, which are not by their nature extensions of the covered work,+and which are not combined with it such as to form a larger program,+in or on a volume of a storage or distribution medium, is called an+"aggregate" if the compilation and its resulting copyright are not+used to limit the access or legal rights of the compilation's users+beyond what the individual works permit. Inclusion of a covered work+in an aggregate does not cause this License to apply to the other+parts of the aggregate.++ 6. Conveying Non-Source Forms.++ You may convey a covered work in object code form under the terms+of sections 4 and 5, provided that you also convey the+machine-readable Corresponding Source under the terms of this License,+in one of these ways:++ a) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by the+ Corresponding Source fixed on a durable physical medium+ customarily used for software interchange.++ b) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by a+ written offer, valid for at least three years and valid for as+ long as you offer spare parts or customer support for that product+ model, to give anyone who possesses the object code either (1) a+ copy of the Corresponding Source for all the software in the+ product that is covered by this License, on a durable physical+ medium customarily used for software interchange, for a price no+ more than your reasonable cost of physically performing this+ conveying of source, or (2) access to copy the+ Corresponding Source from a network server at no charge.++ c) Convey individual copies of the object code with a copy of the+ written offer to provide the Corresponding Source. This+ alternative is allowed only occasionally and noncommercially, and+ only if you received the object code with such an offer, in accord+ with subsection 6b.++ d) Convey the object code by offering access from a designated+ place (gratis or for a charge), and offer equivalent access to the+ Corresponding Source in the same way through the same place at no+ further charge. You need not require recipients to copy the+ Corresponding Source along with the object code. If the place to+ copy the object code is a network server, the Corresponding Source+ may be on a different server (operated by you or a third party)+ that supports equivalent copying facilities, provided you maintain+ clear directions next to the object code saying where to find the+ Corresponding Source. Regardless of what server hosts the+ Corresponding Source, you remain obligated to ensure that it is+ available for as long as needed to satisfy these requirements.++ e) Convey the object code using peer-to-peer transmission, provided+ you inform other peers where the object code and Corresponding+ Source of the work are being offered to the general public at no+ charge under subsection 6d.++ A separable portion of the object code, whose source code is excluded+from the Corresponding Source as a System Library, need not be+included in conveying the object code work.++ A "User Product" is either (1) a "consumer product", which means any+tangible personal property which is normally used for personal, family,+or household purposes, or (2) anything designed or sold for incorporation+into a dwelling. In determining whether a product is a consumer product,+doubtful cases shall be resolved in favor of coverage. For a particular+product received by a particular user, "normally used" refers to a+typical or common use of that class of product, regardless of the status+of the particular user or of the way in which the particular user+actually uses, or expects or is expected to use, the product. A product+is a consumer product regardless of whether the product has substantial+commercial, industrial or non-consumer uses, unless such uses represent+the only significant mode of use of the product.++ "Installation Information" for a User Product means any methods,+procedures, authorization keys, or other information required to install+and execute modified versions of a covered work in that User Product from+a modified version of its Corresponding Source. The information must+suffice to ensure that the continued functioning of the modified object+code is in no case prevented or interfered with solely because+modification has been made.++ If you convey an object code work under this section in, or with, or+specifically for use in, a User Product, and the conveying occurs as+part of a transaction in which the right of possession and use of the+User Product is transferred to the recipient in perpetuity or for a+fixed term (regardless of how the transaction is characterized), the+Corresponding Source conveyed under this section must be accompanied+by the Installation Information. But this requirement does not apply+if neither you nor any third party retains the ability to install+modified object code on the User Product (for example, the work has+been installed in ROM).++ The requirement to provide Installation Information does not include a+requirement to continue to provide support service, warranty, or updates+for a work that has been modified or installed by the recipient, or for+the User Product in which it has been modified or installed. Access to a+network may be denied when the modification itself materially and+adversely affects the operation of the network or violates the rules and+protocols for communication across the network.++ Corresponding Source conveyed, and Installation Information provided,+in accord with this section must be in a format that is publicly+documented (and with an implementation available to the public in+source code form), and must require no special password or key for+unpacking, reading or copying.++ 7. Additional Terms.++ "Additional permissions" are terms that supplement the terms of this+License by making exceptions from one or more of its conditions.+Additional permissions that are applicable to the entire Program shall+be treated as though they were included in this License, to the extent+that they are valid under applicable law. If additional permissions+apply only to part of the Program, that part may be used separately+under those permissions, but the entire Program remains governed by+this License without regard to the additional permissions.++ When you convey a copy of a covered work, you may at your option+remove any additional permissions from that copy, or from any part of+it. (Additional permissions may be written to require their own+removal in certain cases when you modify the work.) You may place+additional permissions on material, added by you to a covered work,+for which you have or can give appropriate copyright permission.++ Notwithstanding any other provision of this License, for material you+add to a covered work, you may (if authorized by the copyright holders of+that material) supplement the terms of this License with terms:++ a) Disclaiming warranty or limiting liability differently from the+ terms of sections 15 and 16 of this License; or++ b) Requiring preservation of specified reasonable legal notices or+ author attributions in that material or in the Appropriate Legal+ Notices displayed by works containing it; or++ c) Prohibiting misrepresentation of the origin of that material, or+ requiring that modified versions of such material be marked in+ reasonable ways as different from the original version; or++ d) Limiting the use for publicity purposes of names of licensors or+ authors of the material; or++ e) Declining to grant rights under trademark law for use of some+ trade names, trademarks, or service marks; or++ f) Requiring indemnification of licensors and authors of that+ material by anyone who conveys the material (or modified versions of+ it) with contractual assumptions of liability to the recipient, for+ any liability that these contractual assumptions directly impose on+ those licensors and authors.++ All other non-permissive additional terms are considered "further+restrictions" within the meaning of section 10. If the Program as you+received it, or any part of it, contains a notice stating that it is+governed by this License along with a term that is a further+restriction, you may remove that term. If a license document contains+a further restriction but permits relicensing or conveying under this+License, you may add to a covered work material governed by the terms+of that license document, provided that the further restriction does+not survive such relicensing or conveying.++ If you add terms to a covered work in accord with this section, you+must place, in the relevant source files, a statement of the+additional terms that apply to those files, or a notice indicating+where to find the applicable terms.++ Additional terms, permissive or non-permissive, may be stated in the+form of a separately written license, or stated as exceptions;+the above requirements apply either way.++ 8. Termination.++ You may not propagate or modify a covered work except as expressly+provided under this License. Any attempt otherwise to propagate or+modify it is void, and will automatically terminate your rights under+this License (including any patent licenses granted under the third+paragraph of section 11).++ However, if you cease all violation of this License, then your+license from a particular copyright holder is reinstated (a)+provisionally, unless and until the copyright holder explicitly and+finally terminates your license, and (b) permanently, if the copyright+holder fails to notify you of the violation by some reasonable means+prior to 60 days after the cessation.++ Moreover, your license from a particular copyright holder is+reinstated permanently if the copyright holder notifies you of the+violation by some reasonable means, this is the first time you have+received notice of violation of this License (for any work) from that+copyright holder, and you cure the violation prior to 30 days after+your receipt of the notice.++ Termination of your rights under this section does not terminate the+licenses of parties who have received copies or rights from you under+this License. If your rights have been terminated and not permanently+reinstated, you do not qualify to receive new licenses for the same+material under section 10.++ 9. Acceptance Not Required for Having Copies.++ You are not required to accept this License in order to receive or+run a copy of the Program. Ancillary propagation of a covered work+occurring solely as a consequence of using peer-to-peer transmission+to receive a copy likewise does not require acceptance. However,+nothing other than this License grants you permission to propagate or+modify any covered work. These actions infringe copyright if you do+not accept this License. Therefore, by modifying or propagating a+covered work, you indicate your acceptance of this License to do so.++ 10. Automatic Licensing of Downstream Recipients.++ Each time you convey a covered work, the recipient automatically+receives a license from the original licensors, to run, modify and+propagate that work, subject to this License. You are not responsible+for enforcing compliance by third parties with this License.++ An "entity transaction" is a transaction transferring control of an+organization, or substantially all assets of one, or subdividing an+organization, or merging organizations. If propagation of a covered+work results from an entity transaction, each party to that+transaction who receives a copy of the work also receives whatever+licenses to the work the party's predecessor in interest had or could+give under the previous paragraph, plus a right to possession of the+Corresponding Source of the work from the predecessor in interest, if+the predecessor has it or can get it with reasonable efforts.++ You may not impose any further restrictions on the exercise of the+rights granted or affirmed under this License. For example, you may+not impose a license fee, royalty, or other charge for exercise of+rights granted under this License, and you may not initiate litigation+(including a cross-claim or counterclaim in a lawsuit) alleging that+any patent claim is infringed by making, using, selling, offering for+sale, or importing the Program or any portion of it.++ 11. Patents.++ A "contributor" is a copyright holder who authorizes use under this+License of the Program or a work on which the Program is based. The+work thus licensed is called the contributor's "contributor version".++ A contributor's "essential patent claims" are all patent claims+owned or controlled by the contributor, whether already acquired or+hereafter acquired, that would be infringed by some manner, permitted+by this License, of making, using, or selling its contributor version,+but do not include claims that would be infringed only as a+consequence of further modification of the contributor version. For+purposes of this definition, "control" includes the right to grant+patent sublicenses in a manner consistent with the requirements of+this License.++ Each contributor grants you a non-exclusive, worldwide, royalty-free+patent license under the contributor's essential patent claims, to+make, use, sell, offer for sale, import and otherwise run, modify and+propagate the contents of its contributor version.++ In the following three paragraphs, a "patent license" is any express+agreement or commitment, however denominated, not to enforce a patent+(such as an express permission to practice a patent or covenant not to+sue for patent infringement). To "grant" such a patent license to a+party means to make such an agreement or commitment not to enforce a+patent against the party.++ If you convey a covered work, knowingly relying on a patent license,+and the Corresponding Source of the work is not available for anyone+to copy, free of charge and under the terms of this License, through a+publicly available network server or other readily accessible means,+then you must either (1) cause the Corresponding Source to be so+available, or (2) arrange to deprive yourself of the benefit of the+patent license for this particular work, or (3) arrange, in a manner+consistent with the requirements of this License, to extend the patent+license to downstream recipients. "Knowingly relying" means you have+actual knowledge that, but for the patent license, your conveying the+covered work in a country, or your recipient's use of the covered work+in a country, would infringe one or more identifiable patents in that+country that you have reason to believe are valid.++ If, pursuant to or in connection with a single transaction or+arrangement, you convey, or propagate by procuring conveyance of, a+covered work, and grant a patent license to some of the parties+receiving the covered work authorizing them to use, propagate, modify+or convey a specific copy of the covered work, then the patent license+you grant is automatically extended to all recipients of the covered+work and works based on it.++ A patent license is "discriminatory" if it does not include within+the scope of its coverage, prohibits the exercise of, or is+conditioned on the non-exercise of one or more of the rights that are+specifically granted under this License. You may not convey a covered+work if you are a party to an arrangement with a third party that is+in the business of distributing software, under which you make payment+to the third party based on the extent of your activity of conveying+the work, and under which the third party grants, to any of the+parties who would receive the covered work from you, a discriminatory+patent license (a) in connection with copies of the covered work+conveyed by you (or copies made from those copies), or (b) primarily+for and in connection with specific products or compilations that+contain the covered work, unless you entered into that arrangement,+or that patent license was granted, prior to 28 March 2007.++ Nothing in this License shall be construed as excluding or limiting+any implied license or other defenses to infringement that may+otherwise be available to you under applicable patent law.++ 12. No Surrender of Others' Freedom.++ If conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot convey a+covered work so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you may+not convey it at all. For example, if you agree to terms that obligate you+to collect a royalty for further conveying from those to whom you convey+the Program, the only way you could satisfy both those terms and this+License would be to refrain entirely from conveying the Program.++ 13. Use with the GNU Affero General Public License.++ Notwithstanding any other provision of this License, you have+permission to link or combine any covered work with a work licensed+under version 3 of the GNU Affero General Public License into a single+combined work, and to convey the resulting work. The terms of this+License will continue to apply to the part which is the covered work,+but the special requirements of the GNU Affero General Public License,+section 13, concerning interaction through a network will apply to the+combination as such.++ 14. Revised Versions of this License.++ The Free Software Foundation may publish revised and/or new versions of+the GNU General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++ Each version is given a distinguishing version number. If the+Program specifies that a certain numbered version of the GNU General+Public License "or any later version" applies to it, you have the+option of following the terms and conditions either of that numbered+version or of any later version published by the Free Software+Foundation. If the Program does not specify a version number of the+GNU General Public License, you may choose any version ever published+by the Free Software Foundation.++ If the Program specifies that a proxy can decide which future+versions of the GNU General Public License can be used, that proxy's+public statement of acceptance of a version permanently authorizes you+to choose that version for the Program.++ Later license versions may give you additional or different+permissions. However, no additional obligations are imposed on any+author or copyright holder as a result of your choosing to follow a+later version.++ 15. Disclaimer of Warranty.++ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++ 16. Limitation of Liability.++ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF+SUCH DAMAGES.++ 17. Interpretation of Sections 15 and 16.++ If the disclaimer of warranty and limitation of liability provided+above cannot be given local legal effect according to their terms,+reviewing courts shall apply local law that most closely approximates+an absolute waiver of all civil liability in connection with the+Program, unless a warranty or assumption of liability accompanies a+copy of the Program in return for a fee.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+state the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.++Also add information on how to contact you by electronic and paper mail.++ If the program does terminal interaction, make it output a short+notice like this when it starts in an interactive mode:++ <program> Copyright (C) <year> <name of author>+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, your program's commands+might be different; for a GUI interface, you would use an "about box".++ You should also get your employer (if you work as a programmer) or school,+if any, to sign a "copyright disclaimer" for the program, if necessary.+For more information on this, and how to apply and follow the GNU GPL, see+<http://www.gnu.org/licenses/>.++ The GNU General Public License does not permit incorporating your program+into proprietary programs. If your program is a subroutine library, you+may consider it more useful to permit linking proprietary applications with+the library. If this is what you want to do, use the GNU Lesser General+Public License instead of this License. But first, please read+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+ Main.hs view
@@ -0,0 +1,93 @@+module Main where+++import Query+import Stats++import Control.Applicative+import Control.Monad+import Control.Arrow+import Data.Maybe+import System +import System.Console.GetOpt+import System.FilePath+import System.Directory+++usage = unlines ["Report generator\nCopyright 2009-2010, Bart Spaans\n",+ "Usage: report [OPTIONS] LOGFILE [QUERYFILE..]]\n"]++data Options = Options {+ interactive :: Bool+ , askOptions :: Bool+ , lang :: [(String, String)]+ , proj :: [(String, String)]+ , home :: Maybe (IO String) + , format :: [String]+ , commands :: [String]+ } ++defaultOptions :: Options+defaultOptions = Options { interactive = False+ , lang = []+ , proj = []+ , home = Just (getHomeDirectory)+ , askOptions = False+ , format = []+ , commands = []+ }++options :: [ OptDescr (Options -> IO Options) ]+options = [Option "h" ["help"] (NoArg outputHelp) "Output command info"+ , Option "f" ["format"] (ReqArg setFormat "FORMAT") "Set default format (csv, html, text, xhtml)"+ , Option "H" ["home"] (ReqArg setHome "HOME") "Set HOME directory"+ , Option "i" ["interactive"] (NoArg setInteractive) "Start interactive query session"+ , Option "l" ["language"] (ReqArg setLanguage "PATH") "Set languages directory"+ , Option "q" ["query"] (ReqArg addCommand "QUERY") "Evaluate query."+ , Option "p" ["project"] (ReqArg setProject "PATH") "Set projects directory"+ ]+++addCommand c opt = return opt { commands = c : commands opt }+outputHelp _ = putStrLn (usageInfo usage options) >> exitWith ExitSuccess+setFormat f opt = return opt { format = f : format opt } +setHome h opt = return opt { home = Just (return h) }+setInteractive opt = return opt { interactive = True }+setLanguage path opt = return opt { lang = parseDescription path : (lang opt) } +setProject path opt = return opt { proj = parseDescription path : (proj opt) } +++makeStatOptions :: Options -> IO StatOptions+makeStatOptions opts = do h <- fromMaybe (return "none") $ home opts+ return SO { languages = toMatches $ lang opts+ , projects = toMatches $ proj opts+ , homePath = h }++makePO :: Options -> E PrintOptions+makePO = setPrinters . format +++main = do + args <- getArgs+ let (actions, nonOpts, msgs) = getOpt RequireOrder options args + when (msgs /= []) (error $ concat msgs)+ opts <- foldl (>>=) (return defaultOptions) actions+ so <- makeStatOptions opts+ po <- case makePO opts of { Failed s -> error s ; Ok a -> return a }+ if null nonOpts then putStrLn usage else exec' so po opts nonOpts+++exec' so po opts nonOpts= + do stats <- statsFromFile (head nonOpts) so+ let i = interactiveQueries po stats+ if not . null $ commands opts+ then putStr $ execute' emptyEnv po (commands opts) stats + else when (length nonOpts <= 1) (i emptyEnv)+ if length nonOpts > 1 + then do co <- commandsFromFiles emptyEnv (tail nonOpts)+ case co of + Failed s -> error s+ Ok (st, e) -> do putStr $ execute emptyEnv po co stats + when (interactive opts) (i e)+ else when (interactive opts) (i emptyEnv)+
+ Printers.hs view
@@ -0,0 +1,152 @@+module Printers (+ -- * Printers+ printTree, printCSV, printHtml,+ printPlainText, printXHtml, ++ -- * Options+ PrintOptions, POption(..),+ PrinterF(..), emptyPO,+ isSet, set, unSet, setPrinters,++ -- * Time strings+ showTime, ++ -- * String converters+ getMonth, getDow,+ ) where++import QueryAST +import Stats++import Control.Applicative+import Data.Char+import qualified Data.Set as S+import qualified Text.CSV as C+import qualified Text.Html as H+import qualified Text.XHtml as X+import Text.Printf+++type PrintOptions = S.Set POption+data POption = PrinterF !PrinterF+ | Ident !Int+ deriving (Eq, Ord, Show)+data PrinterF = Csv + | Html + | Text + | XHtml + deriving (Eq, Ord, Show)++emptyPO :: PrintOptions+emptyPO = S.fromList []+++-- Handling PrintOptions+--+isSet :: POption -> PrintOptions -> Bool+set :: POption -> PrintOptions -> PrintOptions+unSet :: POption -> PrintOptions -> PrintOptions+getPrinters :: PrintOptions -> [StatsTree -> String]+setPrinters :: [String] -> E PrintOptions++isSet = S.member +set = S.insert+unSet = S.delete++getPrinters = map (printer . fromPrinters) . filter isPrinter . S.elems+ where printer Csv = printCSV + printer Html = printHtml + printer Text = printPlainText + printer XHtml = printXHtml + fromPrinters (PrinterF p) = p+ isPrinter (PrinterF _) = True+ isPrinter _ = False++parsePrinter "CSV" = Ok Csv+parsePrinter "HTML" = Ok Html+parsePrinter "TEXT" = Ok Text+parsePrinter "XHTML" = Ok XHtml+parsePrinter s = Failed $ "No such format `" ++ s ++ "'"++setPrinters [] = Ok (S.fromList [PrinterF Text])+setPrinters p = S.fromList <$> f p+ where f = mapM (fmap PrinterF . parsePrinter . map toUpper) ++++-- | Selects the printers described in the PrintOptions.+--+printTree :: PrintOptions -> [StatsTree] -> String+printTree po st = if null p then "No printers selected." + else p >>= (\p' -> concatMap (p'$) (reverse st))+ where p = getPrinters po++++-- String Conversions+--+getMonth :: Int -> String+getDow :: Int -> String+showTime :: Time -> String+months :: [String]+days :: [String]++getMonth n = months !! (min 12 (max 1 n) - 1)+months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]++getDow n = days !! min 6 (max 0 n)+days = ["Sunday" , "Monday", "Tuesday" , "Wednesday",+ "Thursday", "Friday", "Saturday"]++showTime (h, m, s) = concat [f h, ":", f m, ":", f s]+ where f = printf "%02d"++++-- | StatsTree to Plain Text+--+printPlainText :: StatsTree -> String+printPlainText (Root [] _ _ _) = "No matches"+printPlainText (Root ns _ t ti) = concatMap (tts' 1) ns ++ "\n\n Total time: " + ++ showTime ti ++ "\n" + where tts' lvl (Leaf time) = printf "%10s" (showTime time)+ tts' lvl (Node _ _ s tr) = '\n' : replicate (lvl * 4) ' ' + ++ printf "%-70s" s + ++ concatMap (tts' (lvl + 1)) tr+++-- | StatsTree to Html table (no HTML header)+--+printHtml :: StatsTree -> String+printHtml = H.prettyHtml . foldTree (root, node, leaf)+ where root ns h t ti = H.h2 (H.toHtml t) H.+++ H.table (headers h + H.+++ makeTable ns H.+++ total) H.+++ H.hr+ where total = H.tr(H.td (H.toHtml "TOTAL") H.! [H.colspan (length h - 1)] + H.+++ H.td (H.toHtml . showTime $ ti))+ headers = H.tr . H.concatHtml . map (H.th . H.toHtml) + makeTable = H.concatHtml . concatMap (map H.tr) + node cspan t = concatMap . map . (H.+++) . H.td . H.toHtml+ leaf = pure . H.td . H.toHtml . showTime++-- | StatsTree to XHtml table (includes HTML header)+--+printXHtml :: StatsTree -> String+printXHtml = X.prettyHtml . foldTree (root, node, leaf)+ where root ns h t ti = X.h2 (X.toHtml t) X.+++ X.table (headers h + X.+++ makeTable ns X.+++ total) X.+++ X.hr+ where total = X.tr(X.td (X.toHtml "TOTAL") X.! [X.colspan (length h - 1)] + X.+++ X.td (X.toHtml . showTime $ ti))+ headers = X.tr . X.concatHtml . map (X.th . X.toHtml) + makeTable = X.concatHtml . concatMap (map X.tr) + node cspan t = concatMap . map . (X.+++) . X.td . X.toHtml+ leaf = pure . X.td . X.toHtml . showTime+++-- | StatsTree to CSV String.+--+printCSV :: StatsTree -> String+printCSV = C.printCSV . foldTree (root, node, leaf)+ where root ns h _ _ = h : concat ns+ node _ _ = concatMap . map . (:)+ leaf = pure . pure . showTime
+ Query.hs view
@@ -0,0 +1,376 @@+-- | This module can take a parsed query, +-- convert it into something it can use and +-- execute it; resulting in a StatsTree, which +-- can be printed by one of the Printers.+--+module Query ( + -- * Commands+ Commands, Queries, Query, SubQuery, + View, Constraint, Group, Env,+ -- * Execute Queries + interactiveQueries, + commandsFromFile, commandsFromFiles,+ makeTree, QueryAST.E(..),+ emptyEnv, execute, execute' + , module Printers + ) where+++import Stats+import Printers+import QueryParser+import QueryAST+import Char+import Data.List+import Data.Function+import qualified Data.Map as D+import Maybe+import Control.Applicative+import System.Console.Editline.Readline+import System.IO+import System.Directory+import System.FilePath+import Text.Printf+import Control.Monad+++type Commands = (Queries, Env)+type ExecResult = ([StatsTree], Env)+type Queries = [Query]+type Env = D.Map String Query++-- | Each query is represented by sub queries, +-- each of which adds a new level to the tree.+--+type Query = [SubQuery]+type SubQuery = (Header, View, Constraint, Group)+type Constraint = Stats -> (Stats, Stats)+type View = EditStats -> String+type Group = Stats -> [Stats]+++-- | Read commands from files in a given environment.+--+commandsFromFiles :: Env -> [FilePath] -> IO (E Commands)+commandsFromFiles env [] = return $ Ok ([], env)+commandsFromFiles env (f:fp) = do o <- commandsFromFile env f+ case o of + Ok (q,e) -> do o2 <- commandsFromFiles e fp + case o2 of + Ok (q2,e) -> return (Ok (q ++ q2, e))+ Failed s -> return (Failed s)+ Failed s -> return (Failed s)++-- | Read commands from a file in a given environment.+--+commandsFromFile :: Env -> FilePath -> IO (E Commands)+commandsFromFile env = fmap (>>= fromQCommands env) . parseFile+++-- | This function executes Commands in a given environment+-- and then uses the Printers defined in the PrintOptions +-- to return a String representation of the StatsTree.+--+execute :: Env -> PrintOptions -> E Commands -> Stats -> String+execute env po q st = case tr of + Ok c -> printTree po c+ Failed f -> error f + where tr = fst . executeCommands st <$> q+ +execute' env po q st = execute env po (mapM parseCommands q >>= fromQCommands env . concat) st++emptyEnv :: Env+emptyEnv = D.fromList []+++-- A Constraint separates Stats matching +-- a predicate from the ones that don't+-- (P(s), ¬P(s))+--+makeConstraint :: Pred EditStats -> Constraint+makeConstraint p = con ([], [])+ where con (yes, no) [] = (yes, no)+ con (yes, no) (s:st) = con n st+ where n = if p s then (s : yes, no) else (yes, s:no)++++executeCommands :: Stats -> Commands -> ExecResult+makeTree' :: Stats -> Query -> Time -> [StatsTree]+makeNode :: String -> Stats -> Query -> StatsTree+treeFromQuery :: String -> Env -> Stats -> E ExecResult++executeCommands st (q, env) = (map (flip makeTree st) q, env)++-- | Executing a Query: +-- A Query works on Stats, which is a flat list of EditStats.+-- For our results to be meaningful we need to +-- create a StatsTree, where each level represents another+-- subquery. Executing a query can thus be seen +-- as building a tree from a list. +--+makeTree :: Query -> Stats -> StatsTree+makeTree [] s = Root [] [] "" (0,0,0)+makeTree q s = Root nodes headers title time+ where nodes = makeTree' s q (0,0,0)+ headers = map (\(h,_,_,_) -> h) q ++ ["Edit Time"]+ title = concat . intersperse " / " $ reverse headers+ time = sumTime' (map f nodes)+ f (Node _ t _ _) = t+ f _ = (0,0,0)++makeTree' s [] t = [Leaf t]+makeTree' s ((_,v,c, g):cs) t = pruneNodeTrees nodes+ where (yes, no) = c s+ nodes = map (\gr -> makeNode (v . head $ gr) gr cs) (g yes)+++-- Pruning is pretty easy because we need to remove +-- the trees that don't have any leafs in them, +-- and we already keep that information in the Nodes.+--+pruneNodeTrees :: [StatsTree] -> [StatsTree]+pruneNodeTrees = filter ((/=0) . f) + where f (Node i _ _ _) = i+ f _ = 1++-- A Node is made of an Int describing the number of leafs,+-- a string that is used for printing, and of course its children.+--+makeNode s yes cs = Node (n tr) time s tr+ where tr = makeTree' yes cs time+ time = sumTime yes+ n [] = 0 -- Count children+ n ((Node i _ _ _):cs) = i + n cs+ n ((Leaf _):cs) = 1 + n cs+ ++-- A helper function that builds a StatsTree out +-- of a String in the Query language.+--+treeFromQuery s env st = executeCommands st <$> (parseCommands s >>= fromQCommands env)++++-- | Interactive Query prompt using editline+--+interactiveQueries :: PrintOptions -> Stats -> Env -> IO()+promptStart :: IO Bool++type Action = Stats -> Env -> PrintOptions -> IO()++printerDict = [("csv", Csv), ("html", Html), ("text", Text), ("xhtml", XHtml)]+++makePrintAction (s, pr) = [('-' : s, (m un , "Disable " ++ s ++ " printer"))+ , ('+' : s, (m se , "Enable " ++ s ++ " printer"))]+ where un = unSet (PrinterF pr)+ se = set (PrinterF pr)+ m f stats env = repl stats env . f++++replCommands = concatMap makePrintAction printerDict+ ++ [("exit", (\_ _ _ -> onExit, "Exit Program"))+ , ("help", (\s e p -> printHelp >> repl s e p, "Output help"))]+++printHelp = putStrLn $ '\n' : unlines (sort (map h replCommands))+ where h (c, (_, d)) = printf " %-8s %s" c d+++interactiveQueries po stats env = promptStart >> repl stats env po+repl stats env po = do+ setCompletionEntryFunction (Just $ qCompleter env)+ maybeLine <- readline "> " + case maybeLine of+ Nothing -> onExit+ Just "" -> repl stats env po+ Just s -> case lookup s replCommands of + Just (c, _) -> c stats env po+ Nothing -> eval stats env po s++eval stats env po s = do + addHistory s+ case treeFromQuery s env stats of+ Ok (st, e) -> (putStrLn $ printTree po st) >> repl stats e po+ Failed e -> putStrLn e >> repl stats env po+ ++++promptStart = do putStrLn (unlines ["Time Report 1.0a, interactive session"+ , "Copyright 2009-2010, Bart Spaans"+ , "Type \"help\" for more information"])+ hSetBuffering stdout NoBuffering -- remove LineBuffering from stdout+ historyLocation >>= readHistory++onExit = putStr "\n" >> historyLocation >>= writeHistory >> return ()++historyLocation :: IO FilePath+historyLocation = (</> ".report_history") <$> getUserDocumentsDirectory++qCompleter :: Env -> String -> IO [String]+qCompleter env s = return (filter (startsWith s) known)+ where known = ["extension", "language", "project", "filename"+ , "year", "month", "day", "dow", "doy", "limit"+ , "asc", "desc"] ++ D.keys env ++ map fst replCommands+++-- Convert AST to Query+-- We have to transform the parsing result (QCommands) into +-- SubQueries (ie. a view function, a constraint and a +-- group function) and an Environment.+--+fromQCommands :: Env -> QCommands -> E Commands+fromQCommand :: Env -> QCommand -> E (Either Query Env)+fromQQuery :: Env -> QQuery -> E Query+fromQSubQuery :: Env -> QSubQuery -> E Query+fromQIndex :: QIndex -> (EditStats -> String)+addGrouping :: Ord a => Bool -> (EditStats -> a) -> Group++fromQCommands env qs = fromQCommands' env [] qs+ where fromQCommands' env res [] = Ok (res, env)+ fromQCommands' env res (q:qs) = fromQCommand env q >>= f+ where f (Left qr) = fromQCommands' env (qr : res) qs + f (Right e) = fromQCommands' newEnv res qs+ where newEnv = D.union e env+ ++fromQCommand env (Left q) = Left <$> fromQQuery env q+fromQCommand env (Right a) = Right <$> i a+ where i (QAssign s q) = flip (D.insert s) env <$> fromQQuery env q+++-- First convert all the subqueries, then apply+-- ordering and limiting to the last grouping function+-- +fromQQuery env [] = Ok []+fromQQuery env (c:cs) = fromQSubQuery env c >>= (\a -> (a++) <$> fromQQuery env cs)+++++-- Sub queries+--+fromQSubQuery _ q@(QSubQuery _ Ext _ _ _ _) = makeQuery q (takeExtension . fileName)+fromQSubQuery _ q@(QSubQuery _ Lang _ _ _ _) = makeQuery q language+fromQSubQuery _ q@(QSubQuery _ Proj _ _ _ _) = makeQuery q project+fromQSubQuery _ q@(QSubQuery _ File _ _ _ _) = makeQuery q fileName+fromQSubQuery _ q@(QSubQuery _ Year _ _ _ _) = makeQuery q (year . edit)+fromQSubQuery _ q@(QSubQuery _ Month _ _ _ _) = makeQuery q (month . edit)+fromQSubQuery _ q@(QSubQuery _ Day _ _ _ _) = makeQuery q (day . edit)+fromQSubQuery _ q@(QSubQuery _ Dow _ _ _ _) = makeQuery q (dow . edit)+fromQSubQuery _ q@(QSubQuery _ Doy _ _ _ _) = makeQuery q (doy . edit)+fromQSubQuery env (QCall s) = case D.lookup s env of + Just q -> Ok q+ Nothing -> Failed $ "Unknown definition `" ++ s ++ "'"++makeQuery (QSubQuery gr t c h o l) f = Ok [(fromQAs h t, view, constraints, grouping)]+ where view = fromQIndex t+ constraints = fromQConstraints t c+ grouping = fromQLimit l . fromQOrder o . addGrouping gr f+++fromQAs (As s) _ = s+fromQAs _ Ext = "Extension"+fromQAs _ Lang = "Language"+fromQAs _ Proj = "Project"+fromQAs _ File = "File Name"+fromQAs _ Year = "Year"+fromQAs _ Month = "Month"+fromQAs _ Day = "Day"+fromQAs _ Dow = "Day of the Week"+fromQAs _ Doy = "Day of the Year"++-- Limiting and ordering is done before passing +-- the grouped Stats on to the constraint function+--+fromQOrder :: QOrder -> [Stats] -> [Stats]+fromQOrder NoOrder = id+fromQOrder Asc = sortBy (compare `on` sumTime)+fromQOrder Desc = sortBy (flip compare `on` sumTime)+++fromQLimit :: QLimit -> [Stats] -> [Stats]+fromQLimit NoLimit = id+fromQLimit (Limit i) = take i +++-- The view function+--+fromQIndex Ext = takeExtension . fileName+fromQIndex Lang = maybe "Unknown language" snd . language+fromQIndex Proj = maybe "Unknown project" snd . project+fromQIndex File = fileName+fromQIndex Year = show . year . edit+fromQIndex Month = getMonth . month . edit+fromQIndex Day = show . day . edit+fromQIndex Dow = getDow . dow . edit+fromQIndex Doy = show . doy . edit++++-- The grouping function+--+addGrouping False _ = map (:[]) -- dontGroup+addGrouping True f = groupWith f . sortBy (compare `on` f)+++addToGrouping [] _ = error "Empty query, can't add to grouping"+addToGrouping cs f = init cs ++ [add (last cs)]+ where add (v, cs, gr) = (v, cs, f . gr)++++-- QConstraints to Constraints+-- Individual QConstraints are first converted to predicates+-- and get turned into one Constraint using makeConstraint.+--+fromQConstraints :: QIndex -> [QConstraint] -> Constraint+makePred :: QIndex -> QConstraint -> Pred EditStats+++fromQConstraints i qc = makeConstraint $ foldr f (const True) preds+ where f a b p = a p && b p + preds = map (makePred i) qc++makePred i (QC File op e) = fromQOper op (fromQExpr e) . fileName+makePred i (QC Month op e) = numStringC op e month getMonth+makePred i (QC Dow op e) = numStringC op e dow getDow+makePred i (QC Year op e) = numericalC op year e+makePred i (QC Day op e) = numericalC op day e+makePred i (QC Doy op e) = numericalC op doy e+makePred i (QC ind op e) = fromQOper op (fromQExpr e) . fromQIndex ind+makePred i (QCOE op e) = makePred i (QC i op e)+makePred i (QCE e) = makePred i (QC i QE e)+++-- helper functions; to do the conversion+stringC op s f = fromQOper op (map toUpper s) . map toUpper . f . edit+numericalC op g e = fromQOper op (read (fromQExpr e)) . g . edit+maybeC op g h e = maybe False (fromQOper op (fromQExpr e) . h) . g++numStringC op (QInt i) num _ = fromQOper op i . num . edit+numStringC op (QString s) num str = stringC op s (str . num)+++-- Expressions +--+fromQExpr :: QExpr -> String+fromQExpr (QInt i) = show i+fromQExpr (QString s) = s+++-- Operators are written flipped around to make it easier +-- to write in a point-free style (see above)+--+fromQOper :: Ord a => QOper -> (a -> a -> Bool)+fromQOper QL = (>) +fromQOper QG = (<) +fromQOper QLE = (>=) +fromQOper QGE = (<=) +fromQOper QE = (==)+fromQOper QNE = (/=)++
+ QueryAST.hs view
@@ -0,0 +1,33 @@+module QueryAST where++import Control.Applicative++-- A straight forward AST for the Query DSL+--+type QCommands = [QCommand]+type QCommand = Either QQuery QAssign +type QQuery = [QSubQuery]+data QAssign = QAssign String QQuery+data QSubQuery = QSubQuery Bool QIndex [QConstraint] QAs QOrder QLimit | QCall String+data QIndex = Ext | Lang | Proj | File | Year+ | Month | Day | Dow | Doy deriving (Eq, Show)+data QConstraint = QC QIndex QOper QExpr | QCOE QOper QExpr | QCE QExpr+data QOper = QL | QLE | QG | QGE | QE | QNE+data QExpr = QInt Int | QString String+data QOrder = Asc | Desc | NoOrder+data QLimit = Limit Int | NoLimit+data QAs = As String | DefaultAs++-- A Succes/Failure data type used for parsing+--+data E a = Ok a | Failed String++instance Functor E where+ fmap f (Ok a) = Ok $ f a+ fmap f (Failed e) = Failed e++instance Monad E where+ return = Ok+ m >>= k = case m of { Ok a -> k a ; Failed e -> Failed e }+ fail = Failed+
+ QueryLexer.x view
@@ -0,0 +1,159 @@+{+module QueryLexer where++import Data.Either+}++%wrapper "posn"++$digit = 0-9+$alpha = [a-zA-Z]+$upper = A-Z+$ident = [a-zA-Z0-9]+$s = [^'"']++tokens :-++ $white+ ;+ "#".* ;+ ">" { \p s -> TL p }+ "<" { \p s -> TG p }+ "<=" { \p s -> TLE p }+ ">=" { \p s -> TGE p }+ "==" { \p s -> TEqual p }+ "=" { \p s -> TEqual p }+ "!=" { \p s -> TNEqual p }+ "/=" { \p s -> TNEqual p }+ "(" { \p s -> TParenOpen p }+ ")" { \p s -> TParenClose p }+ "," { \p s -> TComma p }+ "*" { \p s -> TProduct p }+ ":=" { \p s -> TAssign p }+ ";" { \p s -> TSemiColon p }+ extension { \p s -> TExtension p }+ extensions { \p s -> TExtension p }+ exts { \p s -> TExtension p }+ ext { \p s -> TExtension p }+ e { \p s -> TExtension p }+ languages { \p s -> TLanguage p }+ language { \p s -> TLanguage p }+ langs { \p s -> TLanguage p }+ lang { \p s -> TLanguage p }+ l { \p s -> TLanguage p }+ projects { \p s -> TProject p }+ project { \p s -> TProject p }+ proj { \p s -> TProject p }+ p { \p s -> TProject p }+ filenames { \p s -> TFilename p }+ filename { \p s -> TFilename p }+ files { \p s -> TFilename p }+ file { \p s -> TFilename p }+ f { \p s -> TFilename p }+ years { \p s -> TYear p }+ year { \p s -> TYear p }+ y { \p s -> TYear p }+ months { \p s -> TMonth p }+ month { \p s -> TMonth p }+ m { \p s -> TMonth p }+ days { \p s -> TDay p }+ day { \p s -> TDay p }+ da { \p s -> TDay p }+ dow { \p s -> TDow p }+ doy { \p s -> TDoy p }+ ascending { \p s -> TAscending p }+ descending { \p s -> TDescending p }+ asc { \p s -> TAscending p }+ as { \p s -> TAs p }+ desc { \p s -> TDescending p }+ limit { \p s -> TLimit p }+ group { \p s -> TGroup p }+ "&" { \p s -> TGroup p }+ nogrouping { \p s -> TDontGroup p }+ nogroup { \p s -> TDontGroup p }+ "!" { \p s -> TDontGroup p }+ $digit+ { \p s -> TInteger p (read s) }+ $upper$ident* { \p s -> TIdent p s }+ \"$s*\" { \p s -> TString p (init (tail s)) }+ +{+data ConstraintToken = TExtension AlexPosn+ | TLanguage AlexPosn+ | TProject AlexPosn+ | TFilename AlexPosn+ | TYear AlexPosn+ | TMonth AlexPosn+ | TDay AlexPosn+ | TDow AlexPosn+ | TDoy AlexPosn+ | TGroup AlexPosn+ | TDontGroup AlexPosn+ | TAscending AlexPosn+ | TDescending AlexPosn+ | TLimit AlexPosn+ | TParenOpen AlexPosn+ | TParenClose AlexPosn+ | TComma AlexPosn+ | TProduct AlexPosn+ | TEqual AlexPosn+ | TNEqual AlexPosn+ | TL AlexPosn+ | TG AlexPosn+ | TLE AlexPosn+ | TGE AlexPosn+ | TSemiColon AlexPosn+ | TAs AlexPosn+ | TInteger AlexPosn Int+ | TIdent AlexPosn String+ | TAssign AlexPosn+ | TString AlexPosn String+ deriving (Eq, Show)+++alexScanTokens' :: String -> Either String [ConstraintToken]+alexScanTokens' str = case go (alexStartPos, '\n', str) of+ [] -> Right []+ cs -> case last cs of + Left a -> Left a+ _ -> Right (rights cs)+ where go inp@(pos,_,str) =+ case alexScan inp 0 of+ AlexEOF -> []+ AlexError _ -> [Left $ "Lexical error on " ++ showPos pos+ ++ if null str then "."+ else ". Not a valid token: '" ++ (head . words $ str) ++ "'"]+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> Right (act pos (take len str)): go inp'++showPos (AlexPn _ li co) = unwords ["line", show li, ", column", show co]++showTokenPos (TExtension p) = showPos p+showTokenPos (TLanguage p) = showPos p+showTokenPos (TProject p) = showPos p+showTokenPos (TFilename p) = showPos p+showTokenPos (TYear p) = showPos p+showTokenPos (TMonth p) = showPos p+showTokenPos (TDay p) = showPos p+showTokenPos (TDow p) = showPos p+showTokenPos (TDoy p) = showPos p+showTokenPos (TGroup p) = showPos p+showTokenPos (TDontGroup p) = showPos p+showTokenPos (TAscending p) = showPos p+showTokenPos (TDescending p) = showPos p+showTokenPos (TLimit p) = showPos p+showTokenPos (TParenOpen p) = showPos p+showTokenPos (TParenClose p) = showPos p+showTokenPos (TComma p) = showPos p+showTokenPos (TProduct p) = showPos p+showTokenPos (TEqual p) = showPos p+showTokenPos (TNEqual p) = showPos p+showTokenPos (TL p) = showPos p+showTokenPos (TG p) = showPos p+showTokenPos (TLE p) = showPos p+showTokenPos (TGE p) = showPos p+showTokenPos (TInteger p _) = showPos p+showTokenPos (TString p _) = showPos p+showTokenPos (TAssign p) = showPos p+showTokenPos (TIdent p _) = showPos p+showTokenPos (TSemiColon p) = showPos p+showTokenPos (TAs p) = showPos p+}
+ QueryParser.y view
@@ -0,0 +1,153 @@+{+module QueryParser (ParseResult, parseCommands, parseFile) where++import Prelude hiding (catch)+import qualified Control.Exception as C++import QueryLexer+import QueryAST++}++%name queryParser++%tokentype { ConstraintToken }+%error { parseError }++%monad { E } ++%token + '>' { TL p } + '<' { TG p } + '<=' { TLE p } + '>=' { TGE p } + '!=' { TNEqual p } + '==' { TEqual p } + '(' { TParenOpen p } + ')' { TParenClose p } + ',' { TComma p } + '*' { TProduct p } + ':=' { TAssign p }+ ';' { TSemiColon p }+ as { TAs p }+ extension { TExtension p } + language { TLanguage p } + project { TProject p } + filename { TFilename p } + year { TYear p } + month { TMonth p } + day { TDay p } + dow { TDow p } + doy { TDoy p } + group { TGroup p } + nogroup { TDontGroup p }+ limit { TLimit p } + asc { TAscending p } + desc { TDescending p } + integer { TInteger p $$ } + string { TString p $$ }+ ident { TIdent p $$ }++%%+++COMMANDS : MULTICOMMAND { $1 }+ | MULTICOMMAND COMMAND { $1 ++ [$2] }+ | COMMAND { [$1] }++MULTICOMMAND: MULTICOMMAND SINGLECOMMAND { $1 ++ [$2] } + | SINGLECOMMAND { [$1] }++SINGLECOMMAND : COMMAND ';' { $1 }++++COMMAND : QUERY { Left $1 } + | ASSIGNMENT { Right $1 }+++ASSIGNMENT : ident ':=' QUERY { QAssign $1 $3 }++QUERY : SUBQUERY { [$1] }+ | QUERY '*' SUBQUERY { $1 ++ [$3] }++SUBQUERY : GROUP INDEX CONSTRAINTS AS ORDER LIMIT {% if typeCheckConstraints $2 $3 + then return $ QSubQuery $1 $2 $3 $4 $5 $6+ else fail "Parse error in constraints: expecting an integer"}+ | ident { QCall $1 }++GROUP : group { True }+ | nogroup { False }+ | { True }++INDEX : extension { Ext }+ | language { Lang } + | project { Proj } + | filename { File } + | year { Year } + | month { Month } + | day { Day } + | dow { Dow } + | doy { Doy } + +CONSTRAINTS : '(' CONS ')' { $2 } + | CONS { $1 }+ | { [] }++CONS : CONSTRAINT { [$1] }+ | CONS ',' CONSTRAINT { $1 ++ [$3] }++CONSTRAINT : INDEX OPERATOR EXPR {% typeCheckQC $1 $2 $3 }+ | OPERATOR EXPR { QCOE $1 $2 }+ | EXPR { QCE $1 } ++AS : as string { As $2 }+ | { DefaultAs }++OPERATOR : '<' { QL }+ | '>' { QG }+ | '<=' { QLE }+ | '>=' { QGE }+ | '==' { QE }+ | '!=' { QNE }++EXPR : integer { QInt $1 }+ | string { QString $1 }++ORDER : asc { Asc }+ | desc { Desc }+ | { NoOrder }++LIMIT: limit integer { Limit $2 }+ | { NoLimit }++{++typeCheckConstraints i cs = all typeCheck cs+ where typeCheck (QC _ _ _) = True+ typeCheck (QCOE _ e) = check e+ typeCheck (QCE e) = check e+ check e = if elem i [Year, Day, Doy] + then case e of { QInt _ -> True ; _ -> False }+ else True+ ++typeCheckQC a b c = if elem a [Year, Day, Doy] + then case c of + QInt _ -> return $ QC a b c+ QString s -> fail $ "Expecting an integer, but got string \"" ++ s ++ "\"" + else (return $ QC a b c)++type ParseResult = E QCommands++parseError :: [ConstraintToken] -> E a+parseCommands :: String -> ParseResult+parseFile :: FilePath -> IO ParseResult++parseError s = fail "Parse error."+parseCommands s = case alexScanTokens' s of + Left err -> fail err+ Right a -> queryParser a+parseFile f = readFile f >>= return . parseCommands++}
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Stats.hs view
@@ -0,0 +1,187 @@+module Stats ( -- * Statistics+ EditStats(..), Stats, + Description, Languages, Projects, Children, + Matches, Match, SplitPath,statsFromFile,+ -- ** Options+ StatOptions(..),+ -- ** Time+ Time, sumTime, sumTime',+ -- * Trees+ Header, Title,+ StatsTree(..),+ StatsTreeAlgebra, foldTree,+ -- * Misc.+ -- ** Match parser for Main+ parseDescription, toMatches,+ -- ** Handy functions+ both, startsWith,+ module Edits+ ) where ++import Edits+import Control.Applicative+import Control.Arrow+import Data.Char+import Data.List+import Data.Maybe +import qualified Data.Map as D hiding (map, filter, mapMaybe)+import System.FilePath++type Description = String+type SplitPath = [FilePath]+type Match = (SplitPath, Description)+type Matches = [Match]+type Languages = Matches+type Projects = Matches+++-- | Used to store the amount of time that was spent+-- on a certain file while also listing some other +-- classifications.+--+data EditStats = ES { language :: Maybe (Description, String)+ , project :: Maybe (Description, String)+ , fileName :: FilePath+ , editTime :: Time+ , edit :: Edit } deriving (Show, Eq)+type Stats = [EditStats]+++-- | Options to be used when creating new Stats.+--+data StatOptions = SO { languages :: Languages, -- ^ Languages src locations + projects :: Projects, -- ^ Projects src locations+ homePath :: String -- ^ HOME directory+ }+++-- Stats — Build EditStats+--+stats :: Edit -> Edit -> StatOptions -> EditStats+matchFile :: Edit -> Matches -> Maybe (Description, Match)+startsWith :: Eq a => [a] -> [a] -> Bool+both :: (a -> b) -> a -> a -> (b, b)+++-- Create EditStats (ie match languages, projects and +-- home directory, count edit time) from two Edits+--+stats e e2 (SO lang proj home) = ES l p n t e+ where (l, p) = both (fmap (second snd)) la pr+ (la, pr) = both (matchFile e) lang (maybe [] new la ++ proj)+ new (c, (fs, d)) = if d == slash then [] else [(fs ++ [d ++ slash] , d)]+ n = if startsWith home f then replaceHome else f+ (t, f) = (diffEdit e e2, file e)+ replaceHome = '~' : drop (length home) f+++-- Try to match a File with a Project or Language+--+matchFile edit matches' = snd <$> (listToMaybe . reverse . sort $ matches)+ where matches = mapMaybe (uncurry match) matches'+ match fs c = if check then j else Nothing+ where path = if [last p] == slash then init p else slash+ check = startsWith fs s && length s > length fs+ (s, p) = (splitPath (file edit), s !! length fs)+ j = Just (length fs, (c, (fs, path))) +++slash :: String+slash = [pathSeparator]+++-- Matches — Description Parsers+--+parseDescription :: String -> (String, String)+toMatches :: [(String, String)] -> Matches+++parseDescription [] = ("", "")+parseDescription s = maybe noDesc desc getDesc + where reversed = reverse s+ desc (x,y) = (reverse x, reverse y)+ noDesc = (s, dropTrailingPathSeparator . last . splitPath $ s)+ getDesc = do c <- elemIndex ')' reversed+ o <- elemIndex '(' reversed+ if all isSpace (take c reversed) + then return (drop (o + 1) reversed, + take (o + 1) (drop (c + 1) reversed))+ else Nothing++toMatches = map (first $ splitPath . addTrailingPathSeparator)+++-- Times+--+diffEdit :: Edit -> Edit -> Time+toSeconds :: Time -> Seconds+fromSeconds :: Seconds -> Time+sumTime :: Stats -> Time+sumTime' :: [Time] -> Time+++type Seconds = Int+type Time = (Int, Int, Int)+++diffEdit (Edit _ _ _ h m s _ _ _) (Edit _ _ _ h' m' s' _ _ _) = fromSeconds t+ where t = toSeconds (h', m', s') - toSeconds (h, m , s)+++toSeconds (h, m, s) = h * 3600 + m * 60 + s+fromSeconds t = (div t 3600, div (mod t 3600) 60, mod (mod t 3600) 60)+sumTime = fromSeconds . sum . map (toSeconds . editTime)+sumTime' = fromSeconds . sum . map toSeconds +++-- Helper functions+--+both f a b = (f a, f b)++startsWith [] _ = True+startsWith _ [] = False+startsWith (a:as) (b:bs) = a == b && startsWith as bs++++-- Calendar of Stats +--+type CalendarS = Calendar Stats++calendarEtoS :: StatOptions -> CalendarE -> CalendarS+calendarS :: StatOptions -> Edits -> CalendarS+statsFromFile :: FilePath -> StatOptions -> IO Stats++calendarEtoS so = fmap stat + where stat = map (\e -> stats (head e) (last e) so) . fileGroup ++calendarS so = calendarEtoS so . calendarE+statsFromFile f so = concat . flatten . calendarS so <$> editsFromFile f++++-- Stats — Trees+--+type Children = Int -- Total number of children in tree+type Header = String+type Title = String++-- | Trees are used to represent the result of a Query.+--+data StatsTree = Root [StatsTree] [Header] Title Time+ | Node Children Time String [StatsTree] + | Leaf Time+ deriving (Eq, Show)++type StatsTreeAlgebra r n = ([n] -> [Header] -> Title -> Time -> r + , Int -> Time -> String -> [n] -> n+ , Time -> n)++-- | A fold for StatsTrees. Most of the Printers are +-- written using this fold.+--+foldTree :: StatsTreeAlgebra r n -> StatsTree -> r+foldTree (root, node, leaf) (Root tr h s t) = root (map f tr) h s t+ where f (Node i t s tr) = node i t s (map f tr)+ f (Leaf e) = leaf e+
+ dist/build/report/report-tmp/QueryLexer.hs view
@@ -0,0 +1,482 @@+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LINE 1 "QueryLexer.x" #-}++module QueryLexer where++import Data.Either++#if __GLASGOW_HASKELL__ >= 603+#include "ghcconfig.h"+#elif defined(__GLASGOW_HASKELL__)+#include "config.h"+#endif+#if __GLASGOW_HASKELL__ >= 503+import Data.Array+import Data.Char (ord)+import Data.Array.Base (unsafeAt)+#else+import Array+import Char (ord)+#endif+#if __GLASGOW_HASKELL__ >= 503+import GHC.Exts+#else+import GlaExts+#endif+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/wrappers.hs" #-}+-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++{-# LINE 18 "templates/wrappers.hs" #-}++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,s) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (p,c,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))+++{-# LINE 51 "templates/wrappers.hs" #-}++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.+++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq,Show)++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad++{-# LINE 162 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Monad (with ByteString input)++{-# LINE 251 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper++{-# LINE 273 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Basic wrapper, ByteString version++{-# LINE 297 "templates/wrappers.hs" #-}++{-# LINE 322 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- Posn wrapper++-- Adds text positions to the basic model.+++--alexScanTokens :: String -> [token]+alexScanTokens str = go (alexStartPos,'\n',str)+ where go inp@(pos,_,str) =+ case alexScan inp 0 of+ AlexEOF -> []+ AlexError _ -> error "lexical error"+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> act pos (take len str) : go inp'++++-- -----------------------------------------------------------------------------+-- Posn wrapper, ByteString version++{-# LINE 354 "templates/wrappers.hs" #-}+++-- -----------------------------------------------------------------------------+-- GScan wrapper++-- For compatibility with previous versions of Alex, and because we can.++alex_base :: AlexAddr+alex_base = AlexA# "\xf8\xff\xff\xff\xfd\xff\xff\xff\x03\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\xd5\xff\xff\xff\xd6\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\xff\xff\xff\x00\x00\x00\x00\xd8\xff\xff\xff\x00\x00\x00\x00\xd9\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xff\xff\xff\x00\x00\x00\x00\xa9\xff\xff\xff\xb1\xff\xff\xff\xb6\xff\xff\xff\xbd\xff\xff\xff\xc4\xff\xff\xff\xca\xff\xff\xff\xee\xff\xff\xff\xe0\xff\xff\xff\xdd\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xff\xff\xff\xf2\xff\xff\xff\xf1\xff\xff\xff\xf9\xff\xff\xff\xed\xff\xff\xff\xf4\xff\xff\xff\xf5\xff\xff\xff\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xff\xff\xff\xf7\xff\xff\xff\x09\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\xfe\xff\xff\xff\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x0b\x00\x00\x00\x08\x00\x00\x00\x12\x00\x00\x00\x0a\x00\x00\x00\x11\x00\x00\x00\x0d\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x0f\x00\x00\x00\x19\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x14\x00\x00\x00\x13\x00\x00\x00\x17\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x1a\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x1c\x00\x00\x00\x20\x00\x00\x00\x24\x00\x00\x00\x21\x00\x00\x00\x28\x00\x00\x00\x2b\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x27\x00\x00\x00\x2d\x00\x00\x00\x33\x00\x00\x00\x2a\x00\x00\x00\x34\x00\x00\x00\x37\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x32\x00\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x31\x00\x00\x00\x35\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3a\x00\x00\x00\x39\x00\x00\x00\x3c\x00\x00\x00\x3b\x00\x00\x00\x38\x00\x00\x00\x3d\x00\x00\x00\x3e\x00\x00\x00\x42\x00\x00\x00\x3f\x00\x00\x00\x81\x00\x00\x00\x8b\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x00\x00\x47\x01\x00\x00\x48\x01\x00\x00"#++alex_table :: AlexAddr+alex_table = AlexA# "\x00\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\xff\xff\x02\x00\x02\x00\x02\x00\x02\x00\x02\x00\xff\xff\x08\x00\x07\x00\x09\x00\x0b\x00\x0d\x00\x13\x00\x02\x00\x0c\x00\x79\x00\x03\x00\x1f\x00\x02\x00\x6a\x00\x16\x00\x0f\x00\x10\x00\x12\x00\x02\x00\x11\x00\x17\x00\x18\x00\x0e\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x14\x00\x15\x00\x06\x00\x0a\x00\x05\x00\x19\x00\x1a\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x76\x00\x1b\x00\x1c\x00\x1d\x00\x21\x00\x22\x00\x23\x00\x57\x00\x24\x00\x26\x00\x4b\x00\x1e\x00\x3b\x00\x69\x00\x2a\x00\x20\x00\x25\x00\x27\x00\x29\x00\x47\x00\x74\x00\x28\x00\x32\x00\x2b\x00\x2e\x00\x2c\x00\x2d\x00\x30\x00\x2f\x00\x64\x00\x34\x00\x41\x00\x33\x00\x36\x00\x31\x00\x35\x00\x38\x00\x3a\x00\x37\x00\x39\x00\x3f\x00\x40\x00\x43\x00\x3c\x00\x4a\x00\x3d\x00\x00\x00\x3e\x00\x60\x00\x42\x00\x46\x00\x45\x00\x4f\x00\x44\x00\x52\x00\x51\x00\x50\x00\x48\x00\x4d\x00\x54\x00\x55\x00\x53\x00\x58\x00\x56\x00\x4c\x00\x49\x00\x4e\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x62\x00\x63\x00\x00\x00\x00\x00\x5f\x00\x65\x00\x6b\x00\x61\x00\x00\x00\x67\x00\x6d\x00\x66\x00\x6c\x00\x68\x00\x72\x00\x00\x00\x6e\x00\x70\x00\x6f\x00\x73\x00\x00\x00\x71\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x75\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\x77\x00\xff\xff\xff\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\x78\x00\x78\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++alex_check :: AlexAddr+alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x20\x00\x21\x00\x22\x00\x23\x00\x73\x00\x20\x00\x26\x00\x6e\x00\x28\x00\x29\x00\x2a\x00\x20\x00\x2c\x00\x6f\x00\x69\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x73\x00\x6e\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x65\x00\x74\x00\x78\x00\x73\x00\x65\x00\x67\x00\x61\x00\x61\x00\x67\x00\x64\x00\x65\x00\x66\x00\x67\x00\x73\x00\x73\x00\x75\x00\x6e\x00\x6c\x00\x6d\x00\x6e\x00\x61\x00\x70\x00\x73\x00\x65\x00\x74\x00\x63\x00\x6f\x00\x6a\x00\x69\x00\x65\x00\x79\x00\x73\x00\x61\x00\x72\x00\x6d\x00\x65\x00\x69\x00\x6e\x00\x6c\x00\x61\x00\x65\x00\x68\x00\x73\x00\x61\x00\x73\x00\xff\xff\x72\x00\x65\x00\x73\x00\x6f\x00\x6e\x00\x67\x00\x74\x00\x64\x00\x69\x00\x6e\x00\x73\x00\x6f\x00\x65\x00\x63\x00\x6e\x00\x67\x00\x73\x00\x77\x00\x79\x00\x79\x00\x6e\x00\x69\x00\x64\x00\x6e\x00\x65\x00\x63\x00\x69\x00\x6d\x00\xff\xff\xff\xff\x73\x00\x70\x00\x67\x00\x74\x00\xff\xff\x6f\x00\x69\x00\x75\x00\x6e\x00\x72\x00\x67\x00\xff\xff\x70\x00\x6f\x00\x75\x00\x6f\x00\xff\xff\x72\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x0a\x00\x0a\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\x22\x00\x22\x00\xff\xff\xff\xff\xff\xff\x27\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++alex_deflt :: AlexAddr+alex_deflt = AlexA# "\xff\xff\xff\xff\xff\xff\x04\x00\x04\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7a\x00\x7a\x00"#++alex_accept = listArray (0::Int,122) [[],[],[(AlexAccSkip)],[(AlexAccSkip)],[(AlexAccSkip)],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_7))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_56))],[(AlexAcc (alex_action_9))],[],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_13))],[(AlexAcc (alex_action_14))],[],[(AlexAcc (alex_action_15))],[(AlexAcc (alex_action_16))],[],[],[],[],[],[(AlexAcc (alex_action_19))],[],[(AlexAcc (alex_action_20))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_18))],[(AlexAcc (alex_action_21))],[(AlexAcc (alex_action_22))],[],[],[],[(AlexAcc (alex_action_24))],[],[],[(AlexAcc (alex_action_25))],[(AlexAcc (alex_action_23))],[(AlexAcc (alex_action_26))],[(AlexAcc (alex_action_27))],[],[],[(AlexAcc (alex_action_28))],[],[],[(AlexAcc (alex_action_29))],[(AlexAcc (alex_action_30))],[(AlexAcc (alex_action_31))],[],[],[],[(AlexAcc (alex_action_33))],[],[],[(AlexAcc (alex_action_34))],[(AlexAcc (alex_action_32))],[(AlexAcc (alex_action_35))],[(AlexAcc (alex_action_36))],[],[],[(AlexAcc (alex_action_37))],[(AlexAcc (alex_action_38))],[(AlexAcc (alex_action_39))],[],[],[],[(AlexAcc (alex_action_40))],[(AlexAcc (alex_action_41))],[(AlexAcc (alex_action_42))],[(AlexAcc (alex_action_43))],[],[(AlexAcc (alex_action_44))],[],[(AlexAcc (alex_action_45))],[(AlexAcc (alex_action_46))],[],[],[],[],[],[(AlexAcc (alex_action_48))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_47))],[],[],[],[],[],[(AlexAcc (alex_action_50))],[],[],[(AlexAcc (alex_action_51))],[],[],[],[(AlexAcc (alex_action_52))],[],[],[],[],[(AlexAcc (alex_action_53))],[(AlexAcc (alex_action_54))],[],[],[(AlexAcc (alex_action_55))],[],[],[],[],[],[],[(AlexAcc (alex_action_57))],[(AlexAcc (alex_action_58))],[(AlexAcc (alex_action_58))],[(AlexAcc (alex_action_59))],[],[]]+{-# LINE 78 "QueryLexer.x" #-}++data ConstraintToken = TExtension AlexPosn+ | TLanguage AlexPosn+ | TProject AlexPosn+ | TFilename AlexPosn+ | TYear AlexPosn+ | TMonth AlexPosn+ | TDay AlexPosn+ | TDow AlexPosn+ | TDoy AlexPosn+ | TGroup AlexPosn+ | TDontGroup AlexPosn+ | TAscending AlexPosn+ | TDescending AlexPosn+ | TLimit AlexPosn+ | TParenOpen AlexPosn+ | TParenClose AlexPosn+ | TComma AlexPosn+ | TProduct AlexPosn+ | TEqual AlexPosn+ | TNEqual AlexPosn+ | TL AlexPosn+ | TG AlexPosn+ | TLE AlexPosn+ | TGE AlexPosn+ | TSemiColon AlexPosn+ | TAs AlexPosn+ | TInteger AlexPosn Int+ | TIdent AlexPosn String+ | TAssign AlexPosn+ | TString AlexPosn String+ deriving (Eq, Show)+++alexScanTokens' :: String -> Either String [ConstraintToken]+alexScanTokens' str = case go (alexStartPos, '\n', str) of+ [] -> Right []+ cs -> case last cs of + Left a -> Left a+ _ -> Right (rights cs)+ where go inp@(pos,_,str) =+ case alexScan inp 0 of+ AlexEOF -> []+ AlexError _ -> [Left $ "Lexical error on " ++ showPos pos+ ++ if null str then "."+ else ". Not a valid token: '" ++ (head . words $ str) ++ "'"]+ AlexSkip inp' len -> go inp'+ AlexToken inp' len act -> Right (act pos (take len str)): go inp'++showPos (AlexPn _ li co) = unwords ["line", show li, ", column", show co]++showTokenPos (TExtension p) = showPos p+showTokenPos (TLanguage p) = showPos p+showTokenPos (TProject p) = showPos p+showTokenPos (TFilename p) = showPos p+showTokenPos (TYear p) = showPos p+showTokenPos (TMonth p) = showPos p+showTokenPos (TDay p) = showPos p+showTokenPos (TDow p) = showPos p+showTokenPos (TDoy p) = showPos p+showTokenPos (TGroup p) = showPos p+showTokenPos (TDontGroup p) = showPos p+showTokenPos (TAscending p) = showPos p+showTokenPos (TDescending p) = showPos p+showTokenPos (TLimit p) = showPos p+showTokenPos (TParenOpen p) = showPos p+showTokenPos (TParenClose p) = showPos p+showTokenPos (TComma p) = showPos p+showTokenPos (TProduct p) = showPos p+showTokenPos (TEqual p) = showPos p+showTokenPos (TNEqual p) = showPos p+showTokenPos (TL p) = showPos p+showTokenPos (TG p) = showPos p+showTokenPos (TLE p) = showPos p+showTokenPos (TGE p) = showPos p+showTokenPos (TInteger p _) = showPos p+showTokenPos (TString p _) = showPos p+showTokenPos (TAssign p) = showPos p+showTokenPos (TIdent p _) = showPos p+showTokenPos (TSemiColon p) = showPos p+showTokenPos (TAs p) = showPos p++alex_action_2 = \p s -> TL p +alex_action_3 = \p s -> TG p +alex_action_4 = \p s -> TLE p +alex_action_5 = \p s -> TGE p +alex_action_6 = \p s -> TEqual p +alex_action_7 = \p s -> TEqual p +alex_action_8 = \p s -> TNEqual p +alex_action_9 = \p s -> TNEqual p +alex_action_10 = \p s -> TParenOpen p +alex_action_11 = \p s -> TParenClose p +alex_action_12 = \p s -> TComma p +alex_action_13 = \p s -> TProduct p +alex_action_14 = \p s -> TAssign p +alex_action_15 = \p s -> TSemiColon p +alex_action_16 = \p s -> TExtension p +alex_action_17 = \p s -> TExtension p +alex_action_18 = \p s -> TExtension p +alex_action_19 = \p s -> TExtension p +alex_action_20 = \p s -> TExtension p +alex_action_21 = \p s -> TLanguage p +alex_action_22 = \p s -> TLanguage p +alex_action_23 = \p s -> TLanguage p +alex_action_24 = \p s -> TLanguage p +alex_action_25 = \p s -> TLanguage p +alex_action_26 = \p s -> TProject p +alex_action_27 = \p s -> TProject p +alex_action_28 = \p s -> TProject p +alex_action_29 = \p s -> TProject p +alex_action_30 = \p s -> TFilename p +alex_action_31 = \p s -> TFilename p +alex_action_32 = \p s -> TFilename p +alex_action_33 = \p s -> TFilename p +alex_action_34 = \p s -> TFilename p +alex_action_35 = \p s -> TYear p +alex_action_36 = \p s -> TYear p +alex_action_37 = \p s -> TYear p +alex_action_38 = \p s -> TMonth p +alex_action_39 = \p s -> TMonth p +alex_action_40 = \p s -> TMonth p +alex_action_41 = \p s -> TDay p +alex_action_42 = \p s -> TDay p +alex_action_43 = \p s -> TDay p +alex_action_44 = \p s -> TDow p +alex_action_45 = \p s -> TDoy p +alex_action_46 = \p s -> TAscending p +alex_action_47 = \p s -> TDescending p +alex_action_48 = \p s -> TAscending p +alex_action_49 = \p s -> TAs p +alex_action_50 = \p s -> TDescending p +alex_action_51 = \p s -> TLimit p +alex_action_52 = \p s -> TGroup p +alex_action_53 = \p s -> TGroup p +alex_action_54 = \p s -> TDontGroup p +alex_action_55 = \p s -> TDontGroup p +alex_action_56 = \p s -> TDontGroup p +alex_action_57 = \p s -> TInteger p (read s) +alex_action_58 = \p s -> TIdent p s +alex_action_59 = \p s -> TString p (init (tail s)) +{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- -----------------------------------------------------------------------------+-- ALEX TEMPLATE+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- INTERNALS and main scanner engine++{-# LINE 35 "templates/GenericTemplate.hs" #-}++{-# LINE 45 "templates/GenericTemplate.hs" #-}+++data AlexAddr = AlexA# Addr#++#if __GLASGOW_HASKELL__ < 503+uncheckedShiftL# = shiftL#+#endif++{-# INLINE alexIndexInt16OffAddr #-}+alexIndexInt16OffAddr (AlexA# arr) off =+#ifdef WORDS_BIGENDIAN+ narrow16Int# i+ where+ i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)+ high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ low = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 2#+#else+ indexInt16OffAddr# arr off+#endif++++++{-# INLINE alexIndexInt32OffAddr #-}+alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN+ narrow32Int# i+ where+ i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`+ (b2 `uncheckedShiftL#` 16#) `or#`+ (b1 `uncheckedShiftL#` 8#) `or#` b0)+ b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))+ b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))+ b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ b0 = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 4#+#else+ indexInt32OffAddr# arr off+#endif++++++#if __GLASGOW_HASKELL__ < 503+quickIndex arr i = arr ! i+#else+-- GHC >= 503, unsafeAt is available from Data.Array.Base.+quickIndex = unsafeAt+#endif+++++-- -----------------------------------------------------------------------------+-- Main lexing routines++data AlexReturn a+ = AlexEOF+ | AlexError !AlexInput+ | AlexSkip !AlexInput !Int+ | AlexToken !AlexInput !Int a++-- alexScan :: AlexInput -> StartCode -> AlexReturn a+alexScan input (I# (sc))+ = alexScanUser undefined input (I# (sc))++alexScanUser user input (I# (sc))+ = case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, input') ->+ case alexGetChar input of+ Nothing -> ++++ AlexEOF+ Just _ ->++++ AlexError input'++ (AlexLastSkip input len, _) ->++++ AlexSkip input len++ (AlexLastAcc k input len, _) ->++++ AlexToken input len k+++-- Push the input through the DFA, remembering the most recent accepting+-- state it encountered.++alex_scan_tkn user orig_input len input s last_acc =+ input `seq` -- strict in the input+ let + new_acc = check_accs (alex_accept `quickIndex` (I# (s)))+ in+ new_acc `seq`+ case alexGetChar input of+ Nothing -> (new_acc, input)+ Just (c, new_input) -> ++++ let+ base = alexIndexInt32OffAddr alex_base s+ (I# (ord_c)) = ord c+ offset = (base +# ord_c)+ check = alexIndexInt16OffAddr alex_check offset+ + new_s = if (offset >=# 0#) && (check ==# ord_c)+ then alexIndexInt16OffAddr alex_table offset+ else alexIndexInt16OffAddr alex_deflt s+ in+ case new_s of + -1# -> (new_acc, input)+ -- on an error, we want to keep the input *before* the+ -- character that failed, not after.+ _ -> alex_scan_tkn user orig_input (len +# 1#) + new_input new_s new_acc++ where+ check_accs [] = last_acc+ check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))+ check_accs (AlexAccPred a pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkipPred pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastSkip input (I# (len))+ check_accs (_ : rest) = check_accs rest++data AlexLastAcc a+ = AlexNone+ | AlexLastAcc a !AlexInput !Int+ | AlexLastSkip !AlexInput !Int++data AlexAcc a user+ = AlexAcc a+ | AlexAccSkip+ | AlexAccPred a (AlexAccPred user)+ | AlexAccSkipPred (AlexAccPred user)++type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool++-- -----------------------------------------------------------------------------+-- Predicates on a rule++alexAndPred p1 p2 user in1 len in2+ = p1 user in1 len in2 && p2 user in1 len in2++--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input++--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input++--alexRightContext :: Int -> AlexAccPred _+alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, _) -> False+ _ -> True+ -- TODO: there's no need to find the longest+ -- match when checking the right context, just+ -- the first match will do.++-- used by wrappers+iUnbox (I# (i)) = i
+ dist/build/report/report-tmp/QueryParser.hs view
@@ -0,0 +1,897 @@+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}+{-# OPTIONS -fglasgow-exts -cpp #-}+module QueryParser (ParseResult, parseCommands, parseFile) where++import Prelude hiding (catch)+import qualified Control.Exception as C++import QueryLexer+import QueryAST+#if __GLASGOW_HASKELL__ >= 503+import qualified Data.Array as Happy_Data_Array+#else+import qualified Array as Happy_Data_Array+#endif+#if __GLASGOW_HASKELL__ >= 503+import qualified GHC.Exts as Happy_GHC_Exts+#else+import qualified GlaExts as Happy_GHC_Exts+#endif++-- parser produced by Happy Version 1.18.4++newtype HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20 = HappyAbsSyn HappyAny+#if __GLASGOW_HASKELL__ >= 607+type HappyAny = Happy_GHC_Exts.Any+#else+type HappyAny = forall a . a+#endif+happyIn4 :: t4 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn4 #-}+happyOut4 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t4+happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut4 #-}+happyIn5 :: t5 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn5 #-}+happyOut5 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t5+happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut5 #-}+happyIn6 :: t6 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn6 #-}+happyOut6 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t6+happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut6 #-}+happyIn7 :: t7 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn7 #-}+happyOut7 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t7+happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut7 #-}+happyIn8 :: t8 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn8 #-}+happyOut8 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t8+happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut8 #-}+happyIn9 :: t9 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn9 #-}+happyOut9 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t9+happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut9 #-}+happyIn10 :: t10 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn10 #-}+happyOut10 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t10+happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut10 #-}+happyIn11 :: t11 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn11 #-}+happyOut11 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t11+happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut11 #-}+happyIn12 :: t12 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn12 #-}+happyOut12 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t12+happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut12 #-}+happyIn13 :: t13 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn13 #-}+happyOut13 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t13+happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut13 #-}+happyIn14 :: t14 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn14 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn14 #-}+happyOut14 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t14+happyOut14 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut14 #-}+happyIn15 :: t15 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn15 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn15 #-}+happyOut15 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t15+happyOut15 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut15 #-}+happyIn16 :: t16 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn16 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn16 #-}+happyOut16 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t16+happyOut16 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut16 #-}+happyIn17 :: t17 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn17 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn17 #-}+happyOut17 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t17+happyOut17 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut17 #-}+happyIn18 :: t18 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn18 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn18 #-}+happyOut18 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t18+happyOut18 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut18 #-}+happyIn19 :: t19 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn19 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn19 #-}+happyOut19 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t19+happyOut19 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut19 #-}+happyIn20 :: t20 -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyIn20 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyIn20 #-}+happyOut20 :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> t20+happyOut20 x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOut20 #-}+happyInTok :: (ConstraintToken) -> (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20)+happyInTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyInTok #-}+happyOutTok :: (HappyAbsSyn t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20) -> (ConstraintToken)+happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x+{-# INLINE happyOutTok #-}+++happyActOffsets :: HappyAddr+happyActOffsets = HappyA# "\x42\x00\x42\x00\x42\x00\x00\x00\x79\x00\x00\x00\x7a\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x78\x00\x63\x00\x2f\x00\x75\x00\x00\x00\x00\x00\x75\x00\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x74\x00\x73\x00\x76\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x62\x00\x53\x00\x00\x00\x1e\x00\x1d\x00\x61\x00\x19\x00\x00\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x00\x00\x00\x00\x00"#++happyGotoOffsets :: HappyAddr+happyGotoOffsets = HappyA# "\x4f\x00\x24\x00\x6d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x59\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x52\x00\x51\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x00\x3a\x00\x00\x00\x2b\x00\x00\x00\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyDefActions :: HappyAddr+happyDefActions = HappyA# "\xef\xff\x00\x00\xef\xff\xfa\xff\x00\x00\xf7\xff\xf8\xff\xf5\xff\x00\x00\xf1\xff\xf0\xff\xf2\xff\x00\x00\xef\xff\xfc\xff\xf9\xff\xfb\xff\xfd\xff\xef\xff\xe3\xff\xee\xff\xed\xff\xec\xff\xeb\xff\xea\xff\xe9\xff\xe8\xff\xe7\xff\xe6\xff\xef\xff\xf4\xff\xf2\xff\x00\x00\xdc\xff\xe4\xff\xe2\xff\x00\x00\xde\xff\xda\xff\xdb\xff\xd9\xff\xd8\xff\xd6\xff\xd7\xff\x00\x00\xd5\xff\xd4\xff\xf6\xff\x00\x00\xdf\xff\x00\x00\xd1\xff\x00\x00\x00\x00\xe0\xff\xdd\xff\xcf\xff\xd3\xff\xd2\xff\xe1\xff\xe5\xff\xf3\xff\x00\x00\xd0\xff"#++happyCheck :: HappyAddr+happyCheck = HappyA# "\xff\xff\x10\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x05\x00\x06\x00\x07\x00\x06\x00\x07\x00\x1c\x00\x1d\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x1c\x00\x1d\x00\x1a\x00\x1b\x00\x0e\x00\x1c\x00\x1d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x08\x00\x17\x00\x18\x00\x0b\x00\x0f\x00\x0d\x00\x0e\x00\x0e\x00\x1e\x00\x1f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x17\x00\x18\x00\x17\x00\x18\x00\x08\x00\x09\x00\x0c\x00\x1e\x00\x0d\x00\x1e\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x08\x00\x0d\x00\x0e\x00\x08\x00\x1c\x00\x0a\x00\x0b\x00\x0a\x00\x0d\x00\x0e\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x1c\x00\x1d\x00\x19\x00\x1d\x00\x09\x00\x0d\x00\x0c\x00\x1f\x00\x0b\x00\x0a\x00\x0c\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"#++happyTable :: HappyAddr+happyTable = HappyA# "\x00\x00\x3d\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x10\x00\x11\x00\x05\x00\x06\x00\x07\x00\x08\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x2f\x00\x07\x00\x08\x00\x1e\x00\x08\x00\x2e\x00\x2f\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x2e\x00\x2f\x00\x3a\x00\x3b\x00\x36\x00\x2e\x00\x2f\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x20\x00\x0a\x00\x0b\x00\x3b\x00\x38\x00\x24\x00\x25\x00\x31\x00\x0c\x00\xfe\xff\x0c\x00\x0d\x00\x03\x00\x0e\x00\x05\x00\x06\x00\x07\x00\x08\x00\x0a\x00\x0b\x00\x0a\x00\x0b\x00\x3d\x00\x33\x00\x33\x00\x20\x00\x35\x00\x0c\x00\x20\x00\x21\x00\x22\x00\x23\x00\x13\x00\x24\x00\x25\x00\x20\x00\x40\x00\x30\x00\x23\x00\x1e\x00\x24\x00\x25\x00\x10\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2e\x00\x2f\x00\x3f\x00\x38\x00\x33\x00\x35\x00\x10\x00\xff\xff\x13\x00\x1e\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#++happyReduceArr = Happy_Data_Array.array (1, 48) [+ (1 , happyReduce_1),+ (2 , happyReduce_2),+ (3 , happyReduce_3),+ (4 , happyReduce_4),+ (5 , happyReduce_5),+ (6 , happyReduce_6),+ (7 , happyReduce_7),+ (8 , happyReduce_8),+ (9 , happyReduce_9),+ (10 , happyReduce_10),+ (11 , happyReduce_11),+ (12 , happyReduce_12),+ (13 , happyReduce_13),+ (14 , happyReduce_14),+ (15 , happyReduce_15),+ (16 , happyReduce_16),+ (17 , happyReduce_17),+ (18 , happyReduce_18),+ (19 , happyReduce_19),+ (20 , happyReduce_20),+ (21 , happyReduce_21),+ (22 , happyReduce_22),+ (23 , happyReduce_23),+ (24 , happyReduce_24),+ (25 , happyReduce_25),+ (26 , happyReduce_26),+ (27 , happyReduce_27),+ (28 , happyReduce_28),+ (29 , happyReduce_29),+ (30 , happyReduce_30),+ (31 , happyReduce_31),+ (32 , happyReduce_32),+ (33 , happyReduce_33),+ (34 , happyReduce_34),+ (35 , happyReduce_35),+ (36 , happyReduce_36),+ (37 , happyReduce_37),+ (38 , happyReduce_38),+ (39 , happyReduce_39),+ (40 , happyReduce_40),+ (41 , happyReduce_41),+ (42 , happyReduce_42),+ (43 , happyReduce_43),+ (44 , happyReduce_44),+ (45 , happyReduce_45),+ (46 , happyReduce_46),+ (47 , happyReduce_47),+ (48 , happyReduce_48)+ ]++happy_n_terms = 32 :: Int+happy_n_nonterms = 17 :: Int++happyReduce_1 = happySpecReduce_1 0# happyReduction_1+happyReduction_1 happy_x_1+ = case happyOut5 happy_x_1 of { happy_var_1 -> + happyIn4+ (happy_var_1+ )}++happyReduce_2 = happySpecReduce_2 0# happyReduction_2+happyReduction_2 happy_x_2+ happy_x_1+ = case happyOut5 happy_x_1 of { happy_var_1 -> + case happyOut7 happy_x_2 of { happy_var_2 -> + happyIn4+ (happy_var_1 ++ [happy_var_2]+ )}}++happyReduce_3 = happySpecReduce_1 0# happyReduction_3+happyReduction_3 happy_x_1+ = case happyOut7 happy_x_1 of { happy_var_1 -> + happyIn4+ ([happy_var_1]+ )}++happyReduce_4 = happySpecReduce_2 1# happyReduction_4+happyReduction_4 happy_x_2+ happy_x_1+ = case happyOut5 happy_x_1 of { happy_var_1 -> + case happyOut6 happy_x_2 of { happy_var_2 -> + happyIn5+ (happy_var_1 ++ [happy_var_2]+ )}}++happyReduce_5 = happySpecReduce_1 1# happyReduction_5+happyReduction_5 happy_x_1+ = case happyOut6 happy_x_1 of { happy_var_1 -> + happyIn5+ ([happy_var_1]+ )}++happyReduce_6 = happySpecReduce_2 2# happyReduction_6+happyReduction_6 happy_x_2+ happy_x_1+ = case happyOut7 happy_x_1 of { happy_var_1 -> + happyIn6+ (happy_var_1+ )}++happyReduce_7 = happySpecReduce_1 3# happyReduction_7+happyReduction_7 happy_x_1+ = case happyOut9 happy_x_1 of { happy_var_1 -> + happyIn7+ (Left happy_var_1+ )}++happyReduce_8 = happySpecReduce_1 3# happyReduction_8+happyReduction_8 happy_x_1+ = case happyOut8 happy_x_1 of { happy_var_1 -> + happyIn7+ (Right happy_var_1+ )}++happyReduce_9 = happySpecReduce_3 4# happyReduction_9+happyReduction_9 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOutTok happy_x_1 of { (TIdent p happy_var_1) -> + case happyOut9 happy_x_3 of { happy_var_3 -> + happyIn8+ (QAssign happy_var_1 happy_var_3+ )}}++happyReduce_10 = happySpecReduce_1 5# happyReduction_10+happyReduction_10 happy_x_1+ = case happyOut10 happy_x_1 of { happy_var_1 -> + happyIn9+ ([happy_var_1]+ )}++happyReduce_11 = happySpecReduce_3 5# happyReduction_11+happyReduction_11 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut9 happy_x_1 of { happy_var_1 -> + case happyOut10 happy_x_3 of { happy_var_3 -> + happyIn9+ (happy_var_1 ++ [happy_var_3]+ )}}++happyReduce_12 = happyMonadReduce 6# 6# happyReduction_12+happyReduction_12 (happy_x_6 `HappyStk`+ happy_x_5 `HappyStk`+ happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest) tk+ = happyThen (case happyOut11 happy_x_1 of { happy_var_1 -> + case happyOut12 happy_x_2 of { happy_var_2 -> + case happyOut13 happy_x_3 of { happy_var_3 -> + case happyOut16 happy_x_4 of { happy_var_4 -> + case happyOut19 happy_x_5 of { happy_var_5 -> + case happyOut20 happy_x_6 of { happy_var_6 -> + ( if typeCheckConstraints happy_var_2 happy_var_3 + then return $ QSubQuery happy_var_1 happy_var_2 happy_var_3 happy_var_4 happy_var_5 happy_var_6+ else fail "Parse error in constraints: expecting an integer")}}}}}}+ ) (\r -> happyReturn (happyIn10 r))++happyReduce_13 = happySpecReduce_1 6# happyReduction_13+happyReduction_13 happy_x_1+ = case happyOutTok happy_x_1 of { (TIdent p happy_var_1) -> + happyIn10+ (QCall happy_var_1+ )}++happyReduce_14 = happySpecReduce_1 7# happyReduction_14+happyReduction_14 happy_x_1+ = happyIn11+ (True+ )++happyReduce_15 = happySpecReduce_1 7# happyReduction_15+happyReduction_15 happy_x_1+ = happyIn11+ (False+ )++happyReduce_16 = happySpecReduce_0 7# happyReduction_16+happyReduction_16 = happyIn11+ (True+ )++happyReduce_17 = happySpecReduce_1 8# happyReduction_17+happyReduction_17 happy_x_1+ = happyIn12+ (Ext+ )++happyReduce_18 = happySpecReduce_1 8# happyReduction_18+happyReduction_18 happy_x_1+ = happyIn12+ (Lang+ )++happyReduce_19 = happySpecReduce_1 8# happyReduction_19+happyReduction_19 happy_x_1+ = happyIn12+ (Proj+ )++happyReduce_20 = happySpecReduce_1 8# happyReduction_20+happyReduction_20 happy_x_1+ = happyIn12+ (File+ )++happyReduce_21 = happySpecReduce_1 8# happyReduction_21+happyReduction_21 happy_x_1+ = happyIn12+ (Year+ )++happyReduce_22 = happySpecReduce_1 8# happyReduction_22+happyReduction_22 happy_x_1+ = happyIn12+ (Month+ )++happyReduce_23 = happySpecReduce_1 8# happyReduction_23+happyReduction_23 happy_x_1+ = happyIn12+ (Day+ )++happyReduce_24 = happySpecReduce_1 8# happyReduction_24+happyReduction_24 happy_x_1+ = happyIn12+ (Dow+ )++happyReduce_25 = happySpecReduce_1 8# happyReduction_25+happyReduction_25 happy_x_1+ = happyIn12+ (Doy+ )++happyReduce_26 = happySpecReduce_3 9# happyReduction_26+happyReduction_26 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut14 happy_x_2 of { happy_var_2 -> + happyIn13+ (happy_var_2+ )}++happyReduce_27 = happySpecReduce_1 9# happyReduction_27+happyReduction_27 happy_x_1+ = case happyOut14 happy_x_1 of { happy_var_1 -> + happyIn13+ (happy_var_1+ )}++happyReduce_28 = happySpecReduce_0 9# happyReduction_28+happyReduction_28 = happyIn13+ ([]+ )++happyReduce_29 = happySpecReduce_1 10# happyReduction_29+happyReduction_29 happy_x_1+ = case happyOut15 happy_x_1 of { happy_var_1 -> + happyIn14+ ([happy_var_1]+ )}++happyReduce_30 = happySpecReduce_3 10# happyReduction_30+happyReduction_30 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut14 happy_x_1 of { happy_var_1 -> + case happyOut15 happy_x_3 of { happy_var_3 -> + happyIn14+ (happy_var_1 ++ [happy_var_3]+ )}}++happyReduce_31 = happyMonadReduce 3# 11# happyReduction_31+happyReduction_31 (happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest) tk+ = happyThen (case happyOut12 happy_x_1 of { happy_var_1 -> + case happyOut17 happy_x_2 of { happy_var_2 -> + case happyOut18 happy_x_3 of { happy_var_3 -> + ( typeCheckQC happy_var_1 happy_var_2 happy_var_3)}}}+ ) (\r -> happyReturn (happyIn15 r))++happyReduce_32 = happySpecReduce_2 11# happyReduction_32+happyReduction_32 happy_x_2+ happy_x_1+ = case happyOut17 happy_x_1 of { happy_var_1 -> + case happyOut18 happy_x_2 of { happy_var_2 -> + happyIn15+ (QCOE happy_var_1 happy_var_2+ )}}++happyReduce_33 = happySpecReduce_1 11# happyReduction_33+happyReduction_33 happy_x_1+ = case happyOut18 happy_x_1 of { happy_var_1 -> + happyIn15+ (QCE happy_var_1+ )}++happyReduce_34 = happySpecReduce_2 12# happyReduction_34+happyReduction_34 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_2 of { (TString p happy_var_2) -> + happyIn16+ (As happy_var_2+ )}++happyReduce_35 = happySpecReduce_0 12# happyReduction_35+happyReduction_35 = happyIn16+ (DefaultAs+ )++happyReduce_36 = happySpecReduce_1 13# happyReduction_36+happyReduction_36 happy_x_1+ = happyIn17+ (QL+ )++happyReduce_37 = happySpecReduce_1 13# happyReduction_37+happyReduction_37 happy_x_1+ = happyIn17+ (QG+ )++happyReduce_38 = happySpecReduce_1 13# happyReduction_38+happyReduction_38 happy_x_1+ = happyIn17+ (QLE+ )++happyReduce_39 = happySpecReduce_1 13# happyReduction_39+happyReduction_39 happy_x_1+ = happyIn17+ (QGE+ )++happyReduce_40 = happySpecReduce_1 13# happyReduction_40+happyReduction_40 happy_x_1+ = happyIn17+ (QE+ )++happyReduce_41 = happySpecReduce_1 13# happyReduction_41+happyReduction_41 happy_x_1+ = happyIn17+ (QNE+ )++happyReduce_42 = happySpecReduce_1 14# happyReduction_42+happyReduction_42 happy_x_1+ = case happyOutTok happy_x_1 of { (TInteger p happy_var_1) -> + happyIn18+ (QInt happy_var_1+ )}++happyReduce_43 = happySpecReduce_1 14# happyReduction_43+happyReduction_43 happy_x_1+ = case happyOutTok happy_x_1 of { (TString p happy_var_1) -> + happyIn18+ (QString happy_var_1+ )}++happyReduce_44 = happySpecReduce_1 15# happyReduction_44+happyReduction_44 happy_x_1+ = happyIn19+ (Asc+ )++happyReduce_45 = happySpecReduce_1 15# happyReduction_45+happyReduction_45 happy_x_1+ = happyIn19+ (Desc+ )++happyReduce_46 = happySpecReduce_0 15# happyReduction_46+happyReduction_46 = happyIn19+ (NoOrder+ )++happyReduce_47 = happySpecReduce_2 16# happyReduction_47+happyReduction_47 happy_x_2+ happy_x_1+ = case happyOutTok happy_x_2 of { (TInteger p happy_var_2) -> + happyIn20+ (Limit happy_var_2+ )}++happyReduce_48 = happySpecReduce_0 16# happyReduction_48+happyReduction_48 = happyIn20+ (NoLimit+ )++happyNewToken action sts stk [] =+ happyDoAction 31# notHappyAtAll action sts stk []++happyNewToken action sts stk (tk:tks) =+ let cont i = happyDoAction i tk action sts stk tks in+ case tk of {+ TL p -> cont 1#;+ TG p -> cont 2#;+ TLE p -> cont 3#;+ TGE p -> cont 4#;+ TNEqual p -> cont 5#;+ TEqual p -> cont 6#;+ TParenOpen p -> cont 7#;+ TParenClose p -> cont 8#;+ TComma p -> cont 9#;+ TProduct p -> cont 10#;+ TAssign p -> cont 11#;+ TSemiColon p -> cont 12#;+ TAs p -> cont 13#;+ TExtension p -> cont 14#;+ TLanguage p -> cont 15#;+ TProject p -> cont 16#;+ TFilename p -> cont 17#;+ TYear p -> cont 18#;+ TMonth p -> cont 19#;+ TDay p -> cont 20#;+ TDow p -> cont 21#;+ TDoy p -> cont 22#;+ TGroup p -> cont 23#;+ TDontGroup p -> cont 24#;+ TLimit p -> cont 25#;+ TAscending p -> cont 26#;+ TDescending p -> cont 27#;+ TInteger p happy_dollar_dollar -> cont 28#;+ TString p happy_dollar_dollar -> cont 29#;+ TIdent p happy_dollar_dollar -> cont 30#;+ _ -> happyError' (tk:tks)+ }++happyError_ tk tks = happyError' (tk:tks)++happyThen :: () => E a -> (a -> E b) -> E b+happyThen = (>>=)+happyReturn :: () => a -> E a+happyReturn = (return)+happyThen1 m k tks = (>>=) m (\a -> k a tks)+happyReturn1 :: () => a -> b -> E a+happyReturn1 = \a tks -> (return) a+happyError' :: () => [(ConstraintToken)] -> E a+happyError' = parseError++queryParser tks = happySomeParser where+ happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))++happySeq = happyDontSeq+++typeCheckConstraints i cs = all typeCheck cs+ where typeCheck (QC _ _ _) = True+ typeCheck (QCOE _ e) = check e+ typeCheck (QCE e) = check e+ check e = if elem i [Year, Day, Doy] + then case e of { QInt _ -> True ; _ -> False }+ else True+ ++typeCheckQC a b c = if elem a [Year, Day, Doy] + then case c of + QInt _ -> return $ QC a b c+ QString s -> fail $ "Expecting an integer, but got string \"" ++ s ++ "\"" + else (return $ QC a b c)++type ParseResult = E QCommands++parseError :: [ConstraintToken] -> E a+parseCommands :: String -> ParseResult+parseFile :: FilePath -> IO ParseResult++parseError s = fail "Parse error."+parseCommands s = case alexScanTokens' s of + Left err -> fail err+ Right a -> queryParser a+parseFile f = readFile f >>= return . parseCommands+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<built-in>" #-}+{-# LINE 1 "<command-line>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp ++{-# LINE 28 "templates/GenericTemplate.hs" #-}+++data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList++++++{-# LINE 49 "templates/GenericTemplate.hs" #-}++{-# LINE 59 "templates/GenericTemplate.hs" #-}++{-# LINE 68 "templates/GenericTemplate.hs" #-}++infixr 9 `HappyStk`+data HappyStk a = HappyStk a (HappyStk a)++-----------------------------------------------------------------------------+-- starting the parse++happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll++-----------------------------------------------------------------------------+-- Accepting the parse++-- If the current token is 0#, it means we've just accepted a partial+-- parse (a %partial parser). We must ignore the saved token on the top of+-- the stack in this case.+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =+ happyReturn1 ans+happyAccept j tk st sts (HappyStk ans _) = + (happyTcHack j (happyTcHack st)) (happyReturn1 ans)++-----------------------------------------------------------------------------+-- Arrays only: do the next action++++happyDoAction i tk st+ = {- nothing -}+++ case action of+ 0# -> {- nothing -}+ happyFail i tk st+ -1# -> {- nothing -}+ happyAccept i tk st+ n | (n Happy_GHC_Exts.<# (0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}++ (happyReduceArr Happy_Data_Array.! rule) i tk st+ where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))+ n -> {- nothing -}+++ happyShift new_state i tk st+ where new_state = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))+ where off = indexShortOffAddr happyActOffsets st+ off_i = (off Happy_GHC_Exts.+# i)+ check = if (off_i Happy_GHC_Exts.>=# (0# :: Happy_GHC_Exts.Int#))+ then (indexShortOffAddr happyCheck off_i Happy_GHC_Exts.==# i)+ else False+ action | check = indexShortOffAddr happyTable off_i+ | otherwise = indexShortOffAddr happyDefActions st++{-# LINE 127 "templates/GenericTemplate.hs" #-}+++indexShortOffAddr (HappyA# arr) off =+#if __GLASGOW_HASKELL__ > 500+ Happy_GHC_Exts.narrow16Int# i+#elif __GLASGOW_HASKELL__ == 500+ Happy_GHC_Exts.intToInt16# i+#else+ Happy_GHC_Exts.iShiftRA# (Happy_GHC_Exts.iShiftL# i 16#) 16#+#endif+ where+#if __GLASGOW_HASKELL__ >= 503+ i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)+#else+ i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.shiftL# high 8#) low)+#endif+ high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))+ low = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))+ off' = off Happy_GHC_Exts.*# 2#++++++data HappyAddr = HappyA# Happy_GHC_Exts.Addr#+++++-----------------------------------------------------------------------------+-- HappyState data type (not arrays)++{-# LINE 170 "templates/GenericTemplate.hs" #-}++-----------------------------------------------------------------------------+-- Shifting a token++happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =+ let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in+-- trace "shifting the error token" $+ happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)++happyShift new_state i tk st sts stk =+ happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)++-- happyReduce is specialised for the common cases.++happySpecReduce_0 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_0 nt fn j tk st@((action)) sts stk+ = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)++happySpecReduce_1 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')+ = let r = fn v1 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_2 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')+ = let r = fn v1 v2 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happySpecReduce_3 i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')+ = let r = fn v1 v2 v3 in+ happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))++happyReduce k i fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyReduce k nt fn j tk st sts stk+ = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of+ sts1@((HappyCons (st1@(action)) (_))) ->+ let r = fn stk in -- it doesn't hurt to always seq here...+ happyDoSeq r (happyGoto nt j tk st1 sts1 r)++happyMonadReduce k nt fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyMonadReduce k nt fn j tk st sts stk =+ happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))+ where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))+ drop_stk = happyDropStk k stk++happyMonad2Reduce k nt fn 0# tk st sts stk+ = happyFail 0# tk st sts stk+happyMonad2Reduce k nt fn j tk st sts stk =+ happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))+ where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))+ drop_stk = happyDropStk k stk++ off = indexShortOffAddr happyGotoOffsets st1+ off_i = (off Happy_GHC_Exts.+# nt)+ new_state = indexShortOffAddr happyTable off_i+++++happyDrop 0# l = l+happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t++happyDropStk 0# l = l+happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs++-----------------------------------------------------------------------------+-- Moving to a new state after a reduction+++happyGoto nt j tk st = + {- nothing -}+ happyDoAction j tk new_state+ where off = indexShortOffAddr happyGotoOffsets st+ off_i = (off Happy_GHC_Exts.+# nt)+ new_state = indexShortOffAddr happyTable off_i+++++-----------------------------------------------------------------------------+-- Error recovery (0# is the error token)++-- parse error if we are in recovery and we fail again+happyFail 0# tk old_st _ stk =+-- trace "failing" $ + happyError_ tk++{- We don't need state discarding for our restricted implementation of+ "error". In fact, it can cause some bogus parses, so I've disabled it+ for now --SDM++-- discard a state+happyFail 0# tk old_st (HappyCons ((action)) (sts)) + (saved_tok `HappyStk` _ `HappyStk` stk) =+-- trace ("discarding state, depth " ++ show (length stk)) $+ happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))+-}++-- Enter error recovery: generate an error token,+-- save the old token and carry on.+happyFail i tk (action) sts stk =+-- trace "entering error recovery" $+ happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)++-- Internal happy errors:++notHappyAtAll = error "Internal Happy error\n"++-----------------------------------------------------------------------------+-- Hack to get the typechecker to accept our action functions+++happyTcHack :: Happy_GHC_Exts.Int# -> a -> a+happyTcHack x y = y+{-# INLINE happyTcHack #-}+++-----------------------------------------------------------------------------+-- Seq-ing. If the --strict flag is given, then Happy emits +-- happySeq = happyDoSeq+-- otherwise it emits+-- happySeq = happyDontSeq++happyDoSeq, happyDontSeq :: a -> b -> b+happyDoSeq a b = a `seq` b+happyDontSeq a b = b++-----------------------------------------------------------------------------+-- Don't inline any functions from the template. GHC has a nasty habit+-- of deciding to inline happyGoto everywhere, which increases the size of+-- the generated parser quite a bit.+++{-# NOINLINE happyDoAction #-}+{-# NOINLINE happyTable #-}+{-# NOINLINE happyCheck #-}+{-# NOINLINE happyActOffsets #-}+{-# NOINLINE happyGotoOffsets #-}+{-# NOINLINE happyDefActions #-}++{-# NOINLINE happyShift #-}+{-# NOINLINE happySpecReduce_0 #-}+{-# NOINLINE happySpecReduce_1 #-}+{-# NOINLINE happySpecReduce_2 #-}+{-# NOINLINE happySpecReduce_3 #-}+{-# NOINLINE happyReduce #-}+{-# NOINLINE happyMonadReduce #-}+{-# NOINLINE happyGoto #-}+{-# NOINLINE happyFail #-}++-- end of Happy Template.