symantic-grammar (empty) → 0.0.0.20170623
raw patch · 12 files changed
+1840/−0 lines, 12 filesdep +basedep +megaparsecdep +symantic-grammar
Dependencies added: base, megaparsec, symantic-grammar, tasty, tasty-hunit, text, transformers
Files
- COPYING +674/−0
- Language/Symantic/Grammar.hs +19/−0
- Language/Symantic/Grammar/BinTree.hs +44/−0
- Language/Symantic/Grammar/ContextFree.hs +147/−0
- Language/Symantic/Grammar/EBNF.hs +148/−0
- Language/Symantic/Grammar/Fixity.hs +98/−0
- Language/Symantic/Grammar/Meta.hs +107/−0
- Language/Symantic/Grammar/Operators.hs +191/−0
- Language/Symantic/Grammar/Regular.hs +103/−0
- Language/Symantic/Grammar/Terminal.hs +111/−0
- Language/Symantic/Grammar/Test.hs +113/−0
- symantic-grammar.cabal +85/−0
+ COPYING 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>.
+ Language/Symantic/Grammar.hs view
@@ -0,0 +1,19 @@+module Language.Symantic.Grammar+ ( module Language.Symantic.Grammar.Fixity+ , module Language.Symantic.Grammar.EBNF+ , module Language.Symantic.Grammar.Terminal+ , module Language.Symantic.Grammar.Regular+ , module Language.Symantic.Grammar.ContextFree+ , module Language.Symantic.Grammar.Operators+ , module Language.Symantic.Grammar.Meta+ , module Language.Symantic.Grammar.BinTree+ ) where++import Language.Symantic.Grammar.Fixity+import Language.Symantic.Grammar.EBNF+import Language.Symantic.Grammar.Terminal+import Language.Symantic.Grammar.Regular+import Language.Symantic.Grammar.ContextFree+import Language.Symantic.Grammar.Operators+import Language.Symantic.Grammar.Meta+import Language.Symantic.Grammar.BinTree
+ Language/Symantic/Grammar/BinTree.hs view
@@ -0,0 +1,44 @@+-- | Binary tree, useful to build /Abstract Syntax Tree/ (AST)+-- made of applications of tokens.+module Language.Symantic.Grammar.BinTree where++import Data.Semigroup (Semigroup(..))++-- * Type 'BinTree'+-- | /Binary Tree/.+data BinTree a+ = BinTree0 a+ | BinTree2 (BinTree a) (BinTree a)+ deriving (Eq, Show)++instance Semigroup (BinTree a) where+ (<>) = BinTree2+instance Functor BinTree where+ fmap f (BinTree0 a) = BinTree0 (f a)+ fmap f (BinTree2 x y) = BinTree2 (fmap f x) (fmap f y)+instance Applicative BinTree where+ pure = BinTree0+ BinTree0 f <*> BinTree0 a = BinTree0 (f a)+ BinTree0 f <*> BinTree2 x y = BinTree2 (f <$> x) (f <$> y)+ BinTree2 fx fy <*> a = BinTree2 (fx <*> a) (fy <*> a)+instance Monad BinTree where+ return = BinTree0+ BinTree0 a >>= f = f a+ BinTree2 x y >>= f = BinTree2 (x >>= f) (y >>= f)+instance Foldable BinTree where+ foldMap f (BinTree0 a) = f a+ foldMap f (BinTree2 x y) = foldMap f x `mappend` foldMap f y+ foldr f acc (BinTree0 a) = f a acc+ foldr f acc (BinTree2 x y) = foldr f (foldr f acc y) x+ foldl f acc (BinTree0 a) = f acc a+ foldl f acc (BinTree2 x y) = foldl f (foldl f acc x) y+instance Traversable BinTree where+ traverse f (BinTree0 a) = BinTree0 <$> f a+ traverse f (BinTree2 x y) = BinTree2 <$> traverse f x <*> traverse f y++-- | Collapse depth-first given 'BinTree' with given function.+--+-- Useful to apply all arguments.+collapseBT :: (a -> a -> a) -> BinTree a -> a+collapseBT _f (BinTree0 x) = x+collapseBT f (BinTree2 x y) = collapseBT f x `f` collapseBT f y
+ Language/Symantic/Grammar/ContextFree.hs view
@@ -0,0 +1,147 @@+-- | Symantics for context-free grammars.+module Language.Symantic.Grammar.ContextFree where++import Control.Applicative (Applicative(..))+import Control.Monad+import Data.Semigroup (Semigroup(..))+import Data.String (IsString(..))+import Prelude hiding (any)++import Language.Symantic.Grammar.Meta+import Language.Symantic.Grammar.Fixity+import Language.Symantic.Grammar.EBNF+import Language.Symantic.Grammar.Terminal+import Language.Symantic.Grammar.Regular++-- * Type 'CF'+-- | Context-free grammar.+newtype CF g a = CF { unCF :: g a }+ deriving (IsString, Functor, Gram_Terminal, Applicative, Gram_App)+deriving instance Gram_Error err g => Gram_Error err (CF g)+deriving instance Gram_Reader st g => Gram_Reader st (CF g)+deriving instance Gram_State st g => Gram_State st (CF g)+deriving instance Gram_Alt g => Gram_Alt (CF g)+deriving instance Gram_Try g => Gram_Try (CF g)+deriving instance Gram_AltApp g => Gram_AltApp (CF g)+deriving instance Gram_Rule g => Gram_Rule (CF g)+deriving instance Gram_RegL g => Gram_RegL (CF g)+deriving instance Gram_RegR g => Gram_RegR (CF g)+deriving instance Gram_CF g => Gram_CF (CF g)+deriving instance Gram_CF RuleEBNF+deriving instance Gram_RuleEBNF g => Gram_RuleEBNF (CF g)+instance Gram_CF EBNF where+ CF (EBNF f) <& Reg (EBNF g) =+ CF $ EBNF $ \bo po -> parenInfix po op $+ f bo (op, SideL) <> " & " <> g bo (op, SideR)+ where op = infixB SideL 4+ Reg (EBNF f) &> CF (EBNF g) =+ CF $ EBNF $ \bo po -> parenInfix po op $+ f bo (op, SideL) <> " & " <> g bo (op, SideR)+ where op = infixB SideL 4+ CF (EBNF f) `minus` Reg (EBNF g) =+ CF $ EBNF $ \bo po -> parenInfix po op $+ f bo (op, SideL) <> " - " <> g bo (op, SideR)+ where op = infixL 6++cf_of_Terminal :: Terminal g a -> CF g a+cf_of_Terminal (Terminal g) = CF g++cf_of_Reg :: Reg lr g a -> CF g a+cf_of_Reg (Reg g) = CF g++-- ** Class 'Gram_CF'+-- | Symantics for context-free grammars.+class Gram_CF g where+ -- | NOTE: CFL ∩ RL is a CFL.+ -- See ISBN 81-7808-347-7, Theorem 7.27, p.286+ (<&) :: CF g (a -> b) -> Reg lr g a -> CF g b+ infixl 4 <&+ (&>) :: Reg lr g (a -> b) -> CF g a -> CF g b+ infixl 4 &>+ -- | NOTE: CFL - RL is a CFL.+ -- See ISBN 81-7808-347-7, Theorem 7.29, p.289+ minus :: CF g a -> Reg lr g b -> CF g a++-- ** Class 'Gram_App'+class Applicative g => Gram_App g where+ between :: g open -> g close -> g a -> g a+ between open close g = open *> g <* close+deriving instance Gram_App RuleEBNF+instance Gram_App EBNF++-- ** Class 'Gram_AltApp'+-- | Symantics when 'Gram_Alt' and 'Gram_App' are allowed by the grammar.+class (Gram_Alt g, Gram_App g) => Gram_AltApp g where+ option :: a -> g a -> g a+ option x g = g <+> pure x+ optional :: g a -> g (Maybe a)+ optional v = Just <$> v <+> pure Nothing+ many :: g a -> g [a]+ many a = some a <+> pure []+ some :: g a -> g [a]+ some a = (:) <$> a <*> many a+ skipMany :: g a -> g ()+ skipMany = void . many+ --manyTill :: g a -> g end -> g [a]+ --manyTill g end = go where go = ([] <$ end) <|> ((:) <$> g <*> go)+ inside+ :: (in_ -> next)+ -> CF g begin+ -> CF g in_+ -> CF g end+ -> CF g next+ -> CF g next+ inside f begin in_ end next =+ (f <$ begin <*> in_ <* end) <+> next+deriving instance Gram_AltApp RuleEBNF+instance Gram_AltApp EBNF where+ many (EBNF g) = EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}" where op = infixN0+ some (EBNF g) = EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}-" where op = infixN0+ option _x (EBNF g) = EBNF $ \rm _po ->+ "[" <> g rm (op, SideL) <> "]" where op = infixN0++-- * Class 'Gram_Comment'+-- | Symantics for handling comments after each 'lexeme'.+class+ ( Gram_Terminal g+ , Gram_Rule g+ , Gram_Alt g+ , Gram_App g+ , Gram_AltApp g+ , Gram_CF g+ ) => Gram_Comment g where+ commentable :: g () -> g () -> g () -> g ()+ commentable = rule3 "commentable" $ \space line block ->+ skipMany $ choice [space, line, block]+ comment_line :: CF g String -> CF g String+ comment_line prefix = rule "comment_line" $+ prefix *> many (any `minus` (void (char '\n') <+> eoi))+ comment_block :: CF g String -> Reg lr g String -> CF g String+ comment_block begin end = rule "comment_block" $+ begin *> many (any `minus` end) <* cf_of_Reg end+ lexeme :: CF g a -> CF g a+ lexeme = rule1 "lexeme" $ \g ->+ g <* commentable+ (void $ string " " <+> string "\n ")+ (void $ comment_line (string "--"))+ (void $ comment_block (string "{-") (string "-}"))+ parens :: CF g a -> CF g a+ parens = rule1 "parens" $+ between+ (lexeme $ char '(')+ (lexeme $ char ')')+ symbol :: String -> CF g String+ symbol = lexeme . string+deriving instance Gram_Comment g => Gram_Comment (CF g)+instance Gram_Comment RuleEBNF+instance Gram_Comment EBNF++gram_comment :: forall g. (Gram_Comment g, Gram_RuleEBNF g) => [CF g ()]+gram_comment =+ [ void $ commentable (void $ argEBNF "space") (void $ argEBNF "line") (void $ argEBNF "block")+ , void $ comment_line (argEBNF "prefix")+ , void $ comment_block (argEBNF "begin") (argEBNF "end" :: RegL g String)+ , void $ lexeme (argEBNF "g")+ , void $ parens (argEBNF "g")+ , void $ inside id (argEBNF "begin") (argEBNF "in") (argEBNF "end") (argEBNF "next")+ ]
+ Language/Symantic/Grammar/EBNF.hs view
@@ -0,0 +1,148 @@+module Language.Symantic.Grammar.EBNF where++import Control.Applicative (Applicative(..))+import Control.Monad+import Data.Semigroup hiding (option)+import Data.Text (Text)+import Prelude hiding (any)+import qualified Data.Text as Text++import Language.Symantic.Grammar.Meta+import Language.Symantic.Grammar.Fixity++-- * Type 'EBNF'+-- | Extended Backus-Naur-Form, following the+-- <http://standards.iso.org/ittf/PubliclyAvailableStandards/s026153_ISO_IEC_14977_1996(E).zip ISO-IEC-14977>+-- notations, augmented with the following notations:+--+-- * @("U+", code_point)@: for <http://unicode.org/versions/Unicode8.0.0/ ISO-IEC-10646> (aka. Unicode).+-- * @(char, "…", char)@: for character range.+-- * @(rule, "&", rule)@: for the intersection.+-- * @(rule, "-", rule)@: for the difference.+-- * @(rule, " ", rule)@: for rule application.+--+-- Inherited attributes are:+--+-- * 'RuleMode' is the requested rendering mode of a 'Rule' (body or reference).+-- * 'Infix' and 'Side' are the properties of the parent operator,+-- used to enclose the operand in parenthesis only when needed.+--+-- Synthetized attributes are:+--+-- * 'Text' of the 'EBNF' rendition.+newtype EBNF a = EBNF { unEBNF :: RuleMode -> (Infix, Side) -> Text }+instance Gram_Reader st EBNF where+ g_ask_before (EBNF e) = EBNF e+ g_ask_after (EBNF e) = EBNF e+instance Gram_State st EBNF where+ g_state_before (EBNF e) = EBNF e+ g_state_after (EBNF e) = EBNF e+instance Gram_Error err EBNF where+ g_catch (EBNF e) = EBNF e++-- | Get textual rendition of given 'EBNF'.+runEBNF :: EBNF a -> Text+runEBNF (EBNF g) = g RuleMode_Body (infixN0, SideL)++-- | Get textual rendition of given 'RuleEBNF'.+renderEBNF :: RuleEBNF a -> Text+renderEBNF = runEBNF . unRuleEBNF++-- | 'EBNF' returns a constant rendition.+ebnf_const :: Text -> EBNF a+ebnf_const t = EBNF $ \_rm _op -> t++-- | 'EBNF' which adds an argument to be applied.+ebnf_arg :: EBNF a -> EBNF b -> EBNF ()+ebnf_arg (EBNF a) (EBNF b) = EBNF $ \bo po -> parenInfix po op $+ a bo (op, SideL) <> " " <> b bo (op, SideR)+ where op = infixL 11+infixl 5 `ebnf_arg`++-- ** Type 'RuleMode'+data RuleMode+ = RuleMode_Body -- ^ Request to generate the body of the rule.+ | RuleMode_Ref -- ^ Request to generate a reference to the rule.+ deriving (Eq, Show)++-- * Type 'Rule'+type Rule a = a -> a++-- ** Class 'Gram_Rule'+class Gram_Rule g where+ rule :: Text -> Rule (g a)+ rule _n = id+ rule1 :: Text -> Rule (g a -> g b)+ rule1 _n g = g+ rule2 :: Text -> Rule (g a -> g b -> g c)+ rule2 _n g = g+ rule3 :: Text -> Rule (g a -> g b -> g c -> g d)+ rule3 _n g = g+ rule4 :: Text -> Rule (g a -> g b -> g c -> g d -> g e)+ rule4 _n g = g++-- * Type 'RuleEBNF'+newtype RuleEBNF a = RuleEBNF { unRuleEBNF :: EBNF a }+ deriving (Functor, Applicative)+deriving instance Gram_RuleEBNF RuleEBNF+deriving instance Gram_Error err RuleEBNF+deriving instance Gram_Reader st RuleEBNF+deriving instance Gram_State st RuleEBNF+instance Gram_Rule RuleEBNF where+ rule n = ruleEBNF (ebnf_const n)+ rule1 n g a = ruleEBNF (ebnf_const n `ebnf_arg` unRuleEBNF a) (g a)+ rule2 n g a b = ruleEBNF (ebnf_const n `ebnf_arg` unRuleEBNF a `ebnf_arg` unRuleEBNF b) (g a b)+ rule3 n g a b c = ruleEBNF (ebnf_const n `ebnf_arg` unRuleEBNF a `ebnf_arg` unRuleEBNF b `ebnf_arg` unRuleEBNF c) (g a b c)+ rule4 n g a b c d = ruleEBNF (ebnf_const n `ebnf_arg` unRuleEBNF a `ebnf_arg` unRuleEBNF b `ebnf_arg` unRuleEBNF c `ebnf_arg` unRuleEBNF d) (g a b c d)++-- ** Class 'Gram_RuleEBNF'+-- | Symantics for rendering 'EBNF' rules.+-- +-- * 'ruleEBNF' renders a rule, either its body or a reference to it, according to 'RuleMode'.+-- * 'argEBNF' renders an argument.+class Gram_RuleEBNF g where+ ruleEBNF :: EBNF () -> g a -> RuleEBNF a+ argEBNF :: Text -> g a+instance Show (EBNF a) where+ show = Text.unpack . runEBNF+instance Functor EBNF where+ fmap _f (EBNF x) = EBNF x+instance Applicative EBNF where+ pure _ = ebnf_const $ "\"\""+ EBNF f <*> EBNF x = EBNF $ \bo po -> parenInfix po op $+ f bo (op, SideL) <> ", " <> x bo (op, SideR)+ where op = infixB SideL 10+instance Gram_Rule EBNF where+ rule n g = EBNF $ \rm po ->+ case rm of+ RuleMode_Body -> unEBNF g RuleMode_Ref po+ RuleMode_Ref -> n+ rule1 n g a = EBNF $ \rm po ->+ case rm of+ RuleMode_Body -> unEBNF (g a) RuleMode_Ref po+ RuleMode_Ref -> unEBNF (ebnf_const n `ebnf_arg` a) RuleMode_Ref po+ rule2 n g a b = EBNF $ \rm po ->+ case rm of+ RuleMode_Body -> unEBNF (g a b) RuleMode_Ref po+ RuleMode_Ref -> unEBNF (ebnf_const n `ebnf_arg` a `ebnf_arg` b) RuleMode_Ref po+ rule3 n g a b c = EBNF $ \rm po ->+ case rm of+ RuleMode_Body -> unEBNF (g a b c) RuleMode_Ref po+ RuleMode_Ref -> unEBNF (ebnf_const n `ebnf_arg` a `ebnf_arg` b `ebnf_arg` c) RuleMode_Ref po+ rule4 n g a b c d = EBNF $ \rm po ->+ case rm of+ RuleMode_Body -> unEBNF (g a b c d) RuleMode_Ref po+ RuleMode_Ref -> unEBNF (ebnf_const n `ebnf_arg` a `ebnf_arg` b `ebnf_arg` c `ebnf_arg` d) RuleMode_Ref po+instance Gram_RuleEBNF EBNF where+ argEBNF = ebnf_const+ ruleEBNF call body =+ RuleEBNF $ EBNF $ \mo po ->+ case mo of+ RuleMode_Ref -> unEBNF call mo po+ RuleMode_Body ->+ Text.intercalate " "+ [ unEBNF call RuleMode_Ref (infixN0, SideL)+ , "="+ , unEBNF body RuleMode_Ref (infixN0, SideR)+ , ";"+ ]
+ Language/Symantic/Grammar/Fixity.hs view
@@ -0,0 +1,98 @@+module Language.Symantic.Grammar.Fixity where++import Data.Bool as Bool+import Data.Semigroup hiding (option)+import Data.String (IsString(..))+import Prelude hiding (any)++-- * Type 'Fixity'+data Fixity+ = Fixity1 Unifix+ | Fixity2 Infix+ deriving (Eq, Show)++-- ** Type 'Unifix'+data Unifix+ = Prefix { unifix_prece :: Precedence }+ | Postfix { unifix_prece :: Precedence }+ deriving (Eq, Show)++-- ** Type 'Infix'+data Infix+ = Infix+ { infix_assoc :: Maybe Associativity+ , infix_prece :: Precedence+ } deriving (Eq, Show)++infixL :: Precedence -> Infix+infixL = Infix (Just AssocL)++infixR :: Precedence -> Infix+infixR = Infix (Just AssocR)++infixB :: Side -> Precedence -> Infix+infixB = Infix . Just . AssocB++infixN :: Precedence -> Infix+infixN = Infix Nothing++infixN0 :: Infix+infixN0 = infixN 0++infixN5 :: Infix+infixN5 = infixN 5++-- | Given 'Precedence' and 'Associativity' of its parent operator,+-- and the operand 'Side' it is in,+-- return whether an 'Infix' operator+-- needs to be enclosed by parenthesis.+needsParenInfix :: (Infix, Side) -> Infix -> Bool+needsParenInfix (po, lr) op =+ infix_prece op < infix_prece po+ || infix_prece op == infix_prece po+ && Bool.not associate+ where+ associate =+ case (lr, infix_assoc po) of+ (_, Just AssocB{}) -> True+ (SideL, Just AssocL) -> True+ (SideR, Just AssocR) -> True+ _ -> False++-- | If 'needsParenInfix' is 'True',+-- enclose the given 'IsString' by parenthesis,+-- otherwise returns the same 'IsString'.+parenInfix+ :: (Semigroup s, IsString s)+ => (Infix, Side) -> Infix -> s -> s+parenInfix po op s =+ if needsParenInfix po op+ then fromString "(" <> s <> fromString ")"+ else s++-- * Type 'Precedence'+type Precedence = Int++-- ** Class 'PrecedenceOf'+class PrecedenceOf a where+ precedence :: a -> Precedence+instance PrecedenceOf Fixity where+ precedence (Fixity1 uni) = precedence uni+ precedence (Fixity2 inf) = precedence inf+instance PrecedenceOf Unifix where+ precedence = unifix_prece+instance PrecedenceOf Infix where+ precedence = infix_prece++-- * Type 'Associativity'+data Associativity+ = AssocL -- ^ Associate to the left: @a ¹ b ² c == (a ¹ b) ² c@+ | AssocR -- ^ Associate to the right: @a ¹ b ² c == a ¹ (b ² c)@+ | AssocB Side -- ^ Associate to both sides, but to 'Side' when reading.+ deriving (Eq, Show)++-- ** Type 'Side'+data Side+ = SideL -- ^ Left+ | SideR -- ^ Right+ deriving (Eq, Show)
+ Language/Symantic/Grammar/Meta.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+module Language.Symantic.Grammar.Meta where++import Data.Function (const)+import Data.Proxy (Proxy(..))+import Data.Typeable (Typeable)++-- * Type 'Gram_Reader'+class Gram_Reader st g where+ g_ask_before :: g (st -> a) -> g a+ g_ask_after :: g (st -> a) -> g a++-- * Type 'Gram_State'+class Gram_State st g where+ g_state_before :: g (st -> (st, a)) -> g a+ g_state_after :: g (st -> (st, a)) -> g a+ g_get_before :: g (st -> a) -> g a+ g_get_after :: g (st -> a) -> g a+ g_put :: g (st, a) -> g a+ default g_get_before :: Functor g => g (st -> a) -> g a+ default g_get_after :: Functor g => g (st -> a) -> g a+ default g_put :: Functor g => g (st, a) -> g a+ g_get_before g = g_state_before ((\f st -> (st, f st)) <$> g)+ g_get_after g = g_state_after ((\f st -> (st, f st)) <$> g)+ g_put g = g_state_after ((\(st, a) -> const (st, a)) <$> g)++-- * Class 'Gram_Error'+-- | Symantics for handling errors at the semantic level (not the syntaxic one).+class Gram_Error err g where+ g_catch :: g (Either err a) -> g a++-- * Class 'Inj_Error'+class Inj_Error a b where+ inj_Error :: a -> b+instance Inj_Error err e => Inj_Error err (Either e a) where+ inj_Error = Left . inj_Error++lift_Error ::+ forall e0 err e1 a.+ Inj_Error e0 e1 =>+ Inj_Error e1 err =>+ Proxy e1 -> Either e0 a -> Either err a+lift_Error _e1 (Right a) = Right a+lift_Error _e1 (Left e) = Left $ inj_Error @e1 @err $ inj_Error @e0 @e1 e++-- * Class 'Source'+class Source src where+ noSource :: src+instance Source () where+ noSource = ()++-- ** Class 'Inj_Source'+class Source src => Inj_Source a src where+ inj_Source :: a -> src+instance Inj_Source a () where+ inj_Source _ = ()++-- ** Type family 'SourceOf'+type family SourceOf a++-- ** Type 'Sourced'+class Source (SourceOf a) => Sourced a where+ sourceOf :: a -> SourceOf a+ setSource :: a -> SourceOf a -> a+infixl 5 `setSource`++source :: Inj_Source src (SourceOf a) => Sourced a => a -> src -> a+source a src = a `setSource` inj_Source src++-- ** Type 'Source_Input'+type family Source_Input (src :: *) :: *+type instance Source_Input () = ()++-- ** Type 'Span'+data Span src+ = Span+ { spanBegin :: !src+ , spanEnd :: !src+ } deriving (Eq, Ord, Show, Typeable)++-- ** Class 'Gram_Source'+class+ ( Gram_Reader (Source_Input src) g+ , Inj_Source (Span (Source_Input src)) src+ ) => Gram_Source src g where+ g_source :: Functor g => g (src -> a) -> g a+ g_source g =+ g_ask_after $ g_ask_before $+ (\f (beg::Source_Input src) (end::Source_Input src) ->+ f (inj_Source $ Span beg end::src))+ <$> g+instance+ ( Gram_Reader (Source_Input src) g+ , Inj_Source (Span (Source_Input src)) src+ ) => Gram_Source src g++-- ** Type 'At'+-- | Attach a 'Source' to something.+data At src a+ = At+ { at :: !src+ , unAt :: !a+ } deriving (Eq, Functor, Ord, Show, Typeable)
+ Language/Symantic/Grammar/Operators.hs view
@@ -0,0 +1,191 @@+-- | Symantics to handle 'Prefix', 'Postfix' or 'Infix' operators,+-- of different 'Precedence's and possibly with left and/or right 'Associativity'.+module Language.Symantic.Grammar.Operators where++import Control.Applicative (Applicative(..))+import Control.Monad (void)+import Data.Foldable hiding (any)+import Prelude hiding (any)++import Language.Symantic.Grammar.Fixity+import Language.Symantic.Grammar.EBNF+import Language.Symantic.Grammar.Terminal+import Language.Symantic.Grammar.Regular+import Language.Symantic.Grammar.ContextFree++-- * Class 'Gram_Op'+-- | Symantics for operators.+class+ ( Gram_Terminal g+ , Gram_Rule g+ , Gram_Alt g+ , Gram_Try g+ , Gram_App g+ , Gram_AltApp g+ , Gram_CF g+ ) => Gram_Op g where+ operators+ :: CF g a -- ^ expression+ -> CF g (Unifix, a -> a) -- ^ prefix operator+ -> CF g (Infix , a -> a -> a) -- ^ infix operator+ -> CF g (Unifix, a -> a) -- ^ postfix operator+ -> CF g (Either Error_Fixity a)+ operators g prefixG infixG postfixG =+ (evalOpTree <$>) <$> go g prefixG infixG postfixG+ where+ go+ :: CF g a+ -> CF g (Unifix, a -> a)+ -> CF g (Infix , a -> a -> a)+ -> CF g (Unifix, a -> a)+ -> CF g (Either Error_Fixity (OpTree a))+ go = rule4 "operators" $ \aG preG inG postG ->+ (\pres a posts ->+ let nod_a =+ foldr insertUnifix+ (foldl' (flip insertUnifix) (OpTree0 a) posts)+ pres+ in \case+ Just (in_, b) -> insertInfix nod_a in_ b+ Nothing -> Right nod_a)+ <$> many (try preG)+ <*> aG+ <*> many (try postG)+ <*> option Nothing (curry Just <$> try inG <*> go aG preG inG postG)+ infixrG :: CF g a -> CF g (a -> a -> a) -> CF g a+ infixrG = rule2 "infixr" $ \g opG ->+ (\a -> \case+ Just (op, b) -> a `op` b+ Nothing -> a)+ <$> g+ <*> option Nothing (try $ curry Just <$> opG <*> infixrG g opG)+ infixlG :: CF g a -> CF g (a -> a -> a) -> CF g a+ infixlG = rule2 "infixl" $ \g opG ->+ -- NOTE: infixl uses the same grammar than infixr,+ -- but build the parsed value by applying+ -- the operator in the opposite way.+ ($ id) <$> go g opG+ where+ go :: CF g a -> CF g (a -> a -> a) -> CF g ((a -> a) -> a)+ go g opG =+ (\a -> \case+ Just (op, kb) -> \k -> kb (k a `op`)+ Nothing -> ($ a))+ <$> g+ <*> option Nothing (try $ curry Just <$> opG <*> go g opG)+deriving instance Gram_Op g => Gram_Op (CF g)+instance Gram_Op RuleEBNF+instance Gram_Op EBNF++-- ** Type 'Error_Fixity'+data Error_Fixity+ = Error_Fixity_Infix_not_combinable Infix Infix+ {-+ Error_Fixity_NeedPostfixOrInfix+ Error_Fixity_NeedPrefix+ Error_Fixity_NeedPostfix+ Error_Fixity_NeedInfix+ -}+ deriving (Eq, Show)++-- ** Type 'OpTree'+-- | Tree of operators.+--+-- Useful to recombine operators according to their 'Precedence'.+data OpTree a+ = OpTree0 a+ | OpTree1 Unifix (a -> a) (OpTree a)+ | OpTree2 Infix (a -> a -> a) (OpTree a) (OpTree a)+instance Show a => Show (OpTree a) where+ showsPrec n (OpTree0 a) =+ showParen (n > 10) $ showString "OpTree0 "+ . showsPrec 11 a+ showsPrec n (OpTree1 f _ a) =+ showParen (n > 10) $ showString "OpTree1 "+ . showsPrec 11 f+ . showChar ' ' . showsPrec 11 a+ showsPrec n (OpTree2 f _ a b) =+ showParen (n > 10) $ showString "OpTree2 "+ . showsPrec 11 f+ . showChar ' ' . showsPrec 11 a+ . showChar ' ' . showsPrec 11 b++-- | Insert an 'Unifix' operator into an 'OpTree'.+insertUnifix :: (Unifix, a -> a) -> OpTree a -> OpTree a+insertUnifix a@(uni_a@(Prefix prece_a), op_a) nod_b =+ case nod_b of+ OpTree0{} -> OpTree1 uni_a op_a nod_b+ OpTree1 Prefix{} _op_b _nod -> OpTree1 uni_a op_a nod_b+ OpTree1 uni_b@(Postfix prece_b) op_b nod ->+ case prece_b `compare` prece_a of+ GT -> OpTree1 uni_a op_a nod_b+ EQ -> OpTree1 uni_a op_a nod_b+ LT -> OpTree1 uni_b op_b $ insertUnifix a nod+ OpTree2 inf_b op_b l r ->+ case infix_prece inf_b `compare` prece_a of+ GT -> OpTree1 uni_a op_a nod_b+ EQ -> OpTree1 uni_a op_a nod_b+ LT -> OpTree2 inf_b op_b (insertUnifix a l) r+insertUnifix a@(uni_a@(Postfix prece_a), op_a) nod_b =+ case nod_b of+ OpTree0{} -> OpTree1 uni_a op_a nod_b+ OpTree1 uni_b@(Prefix prece_b) op_b nod ->+ case prece_b `compare` prece_a of+ GT -> OpTree1 uni_a op_a nod_b+ EQ -> OpTree1 uni_a op_a nod_b+ LT -> OpTree1 uni_b op_b $ insertUnifix a nod+ OpTree1 Postfix{} _op_b _nod -> OpTree1 uni_a op_a nod_b+ OpTree2 inf_b op_b l r ->+ case infix_prece inf_b `compare` prece_a of+ GT -> OpTree1 uni_a op_a nod_b+ EQ -> OpTree1 uni_a op_a nod_b+ LT -> OpTree2 inf_b op_b l (insertUnifix a r)++-- | Insert an 'Infix' operator into an 'OpTree'.+insertInfix+ :: OpTree a+ -> (Infix, a -> a -> a)+ -> Either Error_Fixity (OpTree a)+ -> Either Error_Fixity (OpTree a)+insertInfix nod_a in_@(inf_a, op_a) e_nod_b = do+ nod_b <- e_nod_b+ case nod_b of+ OpTree0{} -> Right $ OpTree2 inf_a op_a nod_a nod_b+ OpTree1 uni_b op_b nod ->+ case unifix_prece uni_b `compare` infix_prece inf_a of+ EQ -> Right $ OpTree2 inf_a op_a nod_a nod_b+ GT -> Right $ OpTree2 inf_a op_a nod_a nod_b+ LT -> do+ n <- insertInfix nod_a in_ (Right nod)+ Right $ OpTree1 uni_b op_b n+ OpTree2 inf_b op_b l r ->+ case infix_prece inf_b `compare` infix_prece inf_a of+ GT -> Right $ OpTree2 inf_a op_a nod_a nod_b+ LT -> do+ n <- insertInfix nod_a in_ (Right l)+ Right $ OpTree2 inf_b op_b n r+ EQ ->+ let ass = \case+ AssocL -> SideL+ AssocR -> SideR+ AssocB lr -> lr in+ case (ass <$> infix_assoc inf_b, ass <$> infix_assoc inf_a) of+ (Just SideL, Just SideL) -> do+ n <- insertInfix nod_a in_ (Right l)+ Right $ OpTree2 inf_b op_b n r+ (Just SideR, Just SideR) ->+ Right $ OpTree2 inf_a op_a nod_a nod_b+ _ -> Left $ Error_Fixity_Infix_not_combinable inf_a inf_b+ -- NOTE: non-associating infix ops+ -- of the same precedence cannot be mixed.++-- | Collapse an 'OpTree'.+evalOpTree :: OpTree a -> a+evalOpTree (OpTree0 a) = a+evalOpTree (OpTree1 _uni op n) = op $ evalOpTree n+evalOpTree (OpTree2 _inf op l r) = evalOpTree l `op` evalOpTree r++gram_operators :: (Gram_Op g, Gram_RuleEBNF g) => [CF g ()]+gram_operators =+ [ void $ operators (argEBNF "expr") (argEBNF "prefix") (argEBNF "infix") (argEBNF "postfix")+ ]
+ Language/Symantic/Grammar/Regular.hs view
@@ -0,0 +1,103 @@+-- | Symantics for regular grammars.+module Language.Symantic.Grammar.Regular where++import Data.Semigroup (Semigroup(..))+import Data.String (IsString(..))+import qualified Data.Text as Text++import Language.Symantic.Grammar.Meta+import Language.Symantic.Grammar.Fixity+import Language.Symantic.Grammar.EBNF+import Language.Symantic.Grammar.Terminal++-- * Type 'Reg'+-- | Left or right regular grammar.+newtype Reg (lr::Side) g a = Reg { unReg :: g a }+ deriving (IsString, Functor, Gram_Terminal)+deriving instance Gram_Alt g => Gram_Alt (Reg lr g)+deriving instance Gram_Try g => Gram_Try (Reg lr g)+deriving instance Gram_Rule g => Gram_Rule (Reg lr g)+deriving instance Gram_Reader st g => Gram_Reader st (Reg lr g)+deriving instance Gram_State st g => Gram_State st (Reg lr g)+deriving instance Gram_Error err g => Gram_Error err (Reg lr g)+deriving instance (Functor g, Gram_Alt g, Gram_RegL g) => Gram_RegL (RegL g)+deriving instance (Functor g, Gram_Alt g, Gram_RegR g) => Gram_RegR (RegR g)+deriving instance Gram_RegL RuleEBNF+deriving instance Gram_RegR RuleEBNF+deriving instance Gram_RuleEBNF g => Gram_RuleEBNF (RegR g)+deriving instance Gram_RuleEBNF g => Gram_RuleEBNF (RegL g)++reg_of_Terminal :: Terminal g a -> Reg lr g a+reg_of_Terminal (Terminal g) = Reg g++type RegL = Reg 'SideL+type RegR = Reg 'SideR++-- ** Class 'Gram_Alt'+-- | Like 'Alternative' but without the 'Applicative' super-class,+-- because a regular grammar is not closed under 'Applicative'.+class Gram_Alt g where+ empty :: g a+ (<+>) :: g a -> g a -> g a+ infixl 3 <+>+ choice :: [g a] -> g a+ choice = foldr (<+>) empty+deriving instance Gram_Alt p => Gram_Alt (Terminal p)+deriving instance Gram_Alt RuleEBNF+instance Gram_Alt EBNF where+ empty = ebnf_const $ "empty"+ EBNF g <+> EBNF q =+ EBNF $ \bo po -> parenInfix po op $+ g bo (op, SideL) <> " | " <> q bo (op, SideR)+ where op = infixB SideL 2+ choice [] = empty+ choice [g] = g+ choice l@(_:_) =+ EBNF $ \bo po -> parenInfix po op $+ Text.intercalate " | " $+ (unEBNF <$> l) <*> pure bo <*> pure (op, SideL)+ where op = infixB SideL 2++-- *** Type 'Gram_Try'+-- | Explicit backtracking.+--+-- To get more accurate error messages,+-- it is helpful to backtrack (put 'try' constructors)+-- only when the grammar actually has another alternative+-- that could match, instead of always backtracking+-- all previous alternatives, as in: 'try'@ a @'<+>'@ b@+class Gram_Try g where+ try :: g a -> g a+instance Gram_Try EBNF where+ try = id+deriving instance Gram_Try RuleEBNF++-- ** Class 'Gram_RegR'+-- | Symantics for right regular grammars.+class (Functor g, Gram_Alt g) => Gram_RegR g where+ (.*>) :: Terminal g (a -> b) -> RegR g a -> RegR g b+ infixl 4 .*>+ manyR :: Terminal g a -> RegR g [a]+ manyR g = (:) <$> g .*> manyR g <+> empty+ someR :: Terminal g a -> RegR g [a]+ someR g = (:) <$> g .*> manyR g+instance Gram_RegR EBNF where+ Terminal f .*> Reg x = Reg $ f <*> x+ manyR (Terminal (EBNF g)) = Reg $ EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}" where op = infixN0+ someR (Terminal (EBNF g)) = Reg $ EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}-" where op = infixN0+ -- NOTE: the suffix "-" symbolizes "minus the empty string".++-- ** Class 'Gram_RegL'+-- | Symantics for left regular grammars.+class (Functor g, Gram_Alt g) => Gram_RegL g where+ (<*.) :: RegL g (a -> b) -> Terminal g a -> RegL g b+ infixl 4 <*.+ manyL :: Terminal g a -> RegL g [a]+ manyL g' = reverse <$> go g'+ where go g = flip (:) <$> go g <*. g <+> empty+ someL :: Terminal g a -> RegL g [a]+ someL g = (\cs c -> cs ++ [c]) <$> manyL g <*. g+instance Gram_RegL EBNF where+ Reg f <*. Terminal x = Reg $ f <*> x+ manyL (Terminal (EBNF g)) = Reg $ EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}" where op = infixN0+ someL (Terminal (EBNF g)) = Reg $ EBNF $ \rm _po -> "{" <> g rm (op, SideL) <> "}-" where op = infixN0
+ Language/Symantic/Grammar/Terminal.hs view
@@ -0,0 +1,111 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- | Symantics for terminal grammars.+module Language.Symantic.Grammar.Terminal where++import Control.Monad+import Data.Semigroup (Semigroup(..))+import Data.String (IsString(..))+import Prelude hiding (any)+import qualified Data.Bool as Bool+import qualified Data.Char as Char+import qualified Data.List as List+import qualified Data.Text as Text++import Language.Symantic.Grammar.Fixity+import Language.Symantic.Grammar.EBNF++-- * Type 'Terminal'+-- | Terminal grammar.+newtype Terminal g a+ = Terminal { unTerminal :: g a }+ deriving (Functor, Gram_Terminal)+deriving instance Gram_Rule g => Gram_Rule (Terminal g)++-- ** Class 'Gram_Terminal'+-- | Symantics for terminal grammars.+class Gram_Terminal g where+ any :: g Char+ but :: Terminal g Char -> Terminal g Char -> Terminal g Char+ eoi :: g ()+ char :: Char -> g Char+ string :: String -> g String+ unicat :: Unicat -> g Char+ range :: (Char, Char) -> g Char+ -- string = foldr (\c -> (<*>) ((:) <$> char c)) (pure "")+ -- string [] = pure []+ -- string (c:cs) = (:) <$> char c <*> string cs+deriving instance Gram_Terminal RuleEBNF+instance Gram_Terminal EBNF where+ any = ebnf_const "_"+ Terminal (EBNF f) `but` Terminal (EBNF g) =+ Terminal $ EBNF $ \bo po -> parenInfix po op $+ f bo (op, SideL) <> " - " <> g bo (op, SideR)+ where op = infixL 6+ eoi = ebnf_const "eoi"+ char = ebnf_const . escape+ where+ escape c | Char.isPrint c && c /= '"' = Text.concat $ ["\"", Text.singleton c, "\""]+ escape c = Text.concat ["U+", Text.pack $ show $ Char.ord c]+ string s =+ case List.break (\c -> Bool.not (Char.isPrint c) || c == '"') s of+ (ps, "") -> raw ps+ ("", [c]) -> "" <$ char c+ (ps, [c]) -> "" <$ raw ps <* char c+ ("", c:rs) -> "" <$ char c <* string rs+ (ps, c:rs) -> "" <$ raw ps <* char c <* string rs+ where+ raw cs = ebnf_const $ Text.concat $ ["\"", Text.pack cs, "\""]+ unicat = ebnf_const . Text.pack . show+ range (l, h) = ebnf_const $ Text.concat+ [ runEBNF $ char l+ , "…"+ , runEBNF $ char h+ ]+instance IsString (EBNF String) where+ fromString = string++-- *** Type 'Unicat'+-- | Unicode category.+data Unicat+ = Unicat_Letter+ | Unicat_Mark+ | Unicat_Number+ | Unicat_Punctuation+ | Unicat_Symbol+ | Unicat Char.GeneralCategory+ deriving (Eq, Show)++unicode_categories :: Unicat -> [Char.GeneralCategory]+unicode_categories c =+ case c of+ Unicat_Letter ->+ [ Char.UppercaseLetter+ , Char.LowercaseLetter+ , Char.TitlecaseLetter+ , Char.ModifierLetter+ , Char.OtherLetter+ ]+ Unicat_Mark ->+ [ Char.NonSpacingMark+ , Char.SpacingCombiningMark+ , Char.EnclosingMark+ ]+ Unicat_Number ->+ [ Char.DecimalNumber+ , Char.LetterNumber+ , Char.OtherNumber+ ]+ Unicat_Punctuation ->+ [ Char.ConnectorPunctuation+ , Char.DashPunctuation+ , Char.OpenPunctuation+ , Char.ClosePunctuation+ , Char.OtherPunctuation+ ]+ Unicat_Symbol ->+ [ Char.MathSymbol+ , Char.CurrencySymbol+ , Char.ModifierSymbol+ , Char.OtherSymbol+ ]+ Unicat cat -> [cat]
+ Language/Symantic/Grammar/Test.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE ConstraintKinds #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Test where++import Test.Tasty+import Test.Tasty.HUnit++import Control.Applicative (Applicative(..))+import Control.Monad+import Data.Semigroup ((<>))+import Data.String (IsString(..))+import Prelude hiding (any, (^), exp)+import qualified Control.Applicative as Gram_AltApp+import qualified Data.Char as Char+import qualified Data.Text as Text+import qualified Text.Megaparsec as P++import Language.Symantic.Grammar++-- * Type 'ParsecT'+type ParsecC e s = (P.Token s ~ Char, P.Stream s, P.ErrorComponent e)+instance ParsecC e s => IsString (P.ParsecT e s m [Char]) where+ fromString = P.string+instance ParsecC e s => Gram_Rule (P.ParsecT e s m) where+ rule = P.label . Text.unpack+instance ParsecC e s => Gram_Terminal (P.ParsecT e s m) where+ any = P.anyChar+ eoi = P.eof+ char = P.char+ string = P.string+ unicat cat = P.satisfy $ (`elem` cats) . Char.generalCategory+ where cats = unicode_categories cat+ range (l, h) = P.satisfy $ \c -> l <= c && c <= h+ but (Terminal f) (Terminal p) = Terminal $ P.notFollowedBy (P.try p) *> f+instance ParsecC e s => Gram_Alt (P.ParsecT e s m) where+ empty = Gram_AltApp.empty+ (<+>) = (Gram_AltApp.<|>)+ choice = P.choice+instance ParsecC e s => Gram_Try (P.ParsecT e s m) where+ try = P.try+instance ParsecC e s => Gram_RegR (P.ParsecT e s m) where+ Terminal f .*> Reg x = Reg $ f <*> x+instance ParsecC e s => Gram_RegL (P.ParsecT e s m) where+ Reg f <*. Terminal x = Reg $ f <*> x+instance ParsecC e s => Gram_App (P.ParsecT e s m)+instance ParsecC e s => Gram_AltApp (P.ParsecT e s m)+instance ParsecC e s => Gram_CF (P.ParsecT e s m) where+ CF f <& Reg p = CF $ P.lookAhead f <*> p+ Reg f &> CF p = CF $ P.lookAhead f <*> p+ CF f `minus` Reg p = CF $ P.notFollowedBy (P.try p) *> f+instance ParsecC e s => Gram_Comment (P.ParsecT e s m)++elide :: Text.Text -> String+elide s | Text.length s > 42 = take 42 (Text.unpack s) <> ['…']+elide s = Text.unpack s++tests :: TestTree+tests = testGroup "Grammar"+ [ testGroup "Terminal" $+ let (==>) inp exp =+ testCase (elide exp) $+ runEBNF (unTerminal (void inp)) @?= exp+ ; infix 1 ==> in+ [ string "" ==> "\"\""+ , string "abé\"to" ==> "\"abé\", U+34, \"to\""+ , string "\"" ==> "U+34"+ , range ('a', 'z') ==> "\"a\"…\"z\""+ , unicat Unicat_Letter ==> "Unicat_Letter"+ , unicat (Unicat Char.LowercaseLetter) ==> "Unicat LowercaseLetter"+ ]+ , testGroup "Reg" $+ let (==>) inp exp =+ testCase (elide exp) $+ runEBNF (unReg (void inp)) @?= exp+ ; infix 1 ==> in+ [ (<>) <$> string "0" .*> someR (char '1') ==> "\"0\", {\"1\"}-"+ , (<>) <$> someL (char '1') <*. string "0" ==> "{\"1\"}-, \"0\""+ ]+ , testGroup "CF" $+ let (==>) inp exp =+ testCase (elide exp) $+ runEBNF (unCF (void inp)) @?= exp+ ; infix 1 ==> in+ [ (<>) <$> string "0" <*> string "1" ==> "\"0\", \"1\""+ , (<>) <$> string "0" <* string "X" <*> string "1" ==> "\"0\", \"X\", \"1\""+ , (<>) <$> (string "0" <+> string "1") <*> string "2" ==> "(\"0\" | \"1\"), \"2\""+ , (<>) <$> string "0" <*> (string "1" <+> string "2") ==> "\"0\", (\"1\" | \"2\")"+ , string "0" <+> string "1" <+> string "2" ==> "\"0\" | \"1\" | \"2\""+ , choice [string "0", string "1", string "2"] ==> "\"0\" | \"1\" | \"2\""+ , (<>) <$> choice+ [ (<>) <$> string "0" <*> string "1"+ , string "2" <+> string "3"+ , string "4"+ ] <*> string "5" ==> "(\"0\", \"1\" | \"2\" | \"3\" | \"4\"), \"5\""+ , concat <$> many (string "0") ==> "{\"0\"}"+ , () <$ char 'a' <* char 'b' <* char 'c' ==> "\"a\", \"b\", \"c\""+ ,let g0 = (<>) <$> string "0" .*> someR (char '1') in+ (<>) <$> string "0" <& g0 ==> "\"0\" & \"0\", {\"1\"}-"+ ,let g0 = (<>) <$> string "0" .*> someR (char '1') in+ let g1 = (<>) <$> someL (char '1') <*. string "0" in+ string "0" `minus` g0 `minus` g1 ==>+ "\"0\" - \"0\", {\"1\"}- - {\"1\"}-, \"0\""+ , (<>)+ <$> many (string "0" <+> string "1")+ <*> some (string "2") ==> "{\"0\" | \"1\"}, {\"2\"}-"+ ]+ ]++main :: IO ()+main =+ defaultMain $+ testGroup "Language.Symantic"+ [tests]
+ symantic-grammar.cabal view
@@ -0,0 +1,85 @@+author: Julien Moutinho <julm+symantic@autogeree.net>+bug-reports: Julien Moutinho <julm+symantic@autogeree.net>+build-type: Simple+cabal-version: >= 1.24+category: Language+description:+ This library defines an embedded DSL for regular or context-free grammars,+ in the <http://okmij.org/ftp/tagless-final/ Tagless-Final> way (aka. the /symantic/ way).+ .+ See @Test.hs@ or source code of <https://hackage.haskell.org/package/symantic symantic>+ and <https://hackage.haskell.org/package/symantic-lib symantic-lib> for examples of use.+extra-source-files:+extra-tmp-files:+-- homepage: +license: GPL-3+license-file: COPYING+maintainer: Julien Moutinho <julm+symantic@autogeree.net>+name: symantic-grammar+stability: experimental+synopsis: Library for symantic grammars.+tested-with: GHC==8.0.2+-- PVP: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 0.0.0.20170623++Source-Repository head+ location: git://git.autogeree.net/symantic+ type: git++Library+ default-extensions:+ DataKinds+ FlexibleContexts+ FlexibleInstances+ GeneralizedNewtypeDeriving+ KindSignatures+ LambdaCase+ MultiParamTypeClasses+ OverloadedStrings+ ScopedTypeVariables+ StandaloneDeriving+ ghc-options: -Wall+ -fwarn-incomplete-patterns+ -fno-warn-tabs+ -fprint-explicit-kinds+ default-language: Haskell2010+ exposed-modules:+ Language.Symantic.Grammar+ Language.Symantic.Grammar.BinTree+ Language.Symantic.Grammar.ContextFree+ Language.Symantic.Grammar.EBNF+ Language.Symantic.Grammar.Fixity+ Language.Symantic.Grammar.Meta+ Language.Symantic.Grammar.Operators+ Language.Symantic.Grammar.Regular+ Language.Symantic.Grammar.Terminal+ build-depends:+ base >= 4.6 && < 5+ , text++Test-Suite symantic-grammar-test+ type: exitcode-stdio-1.0+ default-extensions:+ FlexibleContexts+ FlexibleInstances+ MultiParamTypeClasses+ OverloadedStrings+ ScopedTypeVariables+ TypeFamilies+ default-language: Haskell2010+ ghc-options: -Wall+ -fno-warn-tabs+ -main-is Test+ hs-source-dirs: Language/Symantic+ main-is: Grammar/Test.hs+ other-modules:+ build-depends:+ base >= 4.6 && < 5+ , megaparsec+ , symantic-grammar+ , tasty >= 0.11+ , tasty-hunit+ , text+ , transformers