packages feed

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 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.