Pegex-0.75000755001750001750 013621325365 11622 5ustar00ingyingy000000000000README100644001750001750 737113621325365 12573 0ustar00ingyingy000000000000Pegex-0.75NAME Pegex - Acmeist PEG Parser Framework VERSION This document describes Pegex version 0.75. SYNOPSIS use Pegex; my $result = pegex($grammar)->parse($input); or with options: use Pegex; use ReceiverClass; my $parser = pegex($grammar, 'ReceiverClass'); my $result = $parser->parse($input); or more explicitly: use Pegex::Parser; use Pegex::Grammar; my $pegex_grammar = Pegex::Grammar->new( text => $grammar, ); my $parser = Pegex::Parser->new( grammar => $pegex_grammar, ); my $result = $parser->parse($input); or customized explicitly: { package MyGrammar; use Pegex::Base; extends 'Pegex::Grammar'; has text => "your grammar definition text goes here"; has receiver => "MyReceiver"; } { package MyReceiver; use base 'Pegex::Receiver'; got_some_rule { ... } got_other_rule { ... } } use Pegex::Parser; my $parser = Pegex::Parser->new( grammar => MyGrammar->new, receiver => MyReceiver->new, ); $parser->parse($input); my $result = $parser->receiver->data; DESCRIPTION Pegex is an Acmeist parser framework. It allows you to easily create parsers that will work equivalently in lots of programming languages! The inspiration for Pegex comes from the parsing engine upon which the postmodern programming language Perl 6 is based on. Pegex brings this beauty to the other justmodern languages that have a normal regular expression engine available. Pegex gets it name by combining Parsing Expression Grammars (PEG), with Regular Expressions (Regex). That's actually what Pegex does. PEG is the cool new way to elegantly specify recursive descent grammars. The Perl 6 language is defined in terms of a self modifying PEG language called Perl 6 Rules. Regexes are familiar to programmers of most modern programming languages. Pegex defines a simple PEG syntax, where all the terminals are regexes. This means that Pegex can be quite fast and powerful. Pegex attempts to be the simplest way to define new (or old) Domain Specific Languages (DSLs) that need to be used in several programming languages and environments. Things like JSON, YAML, Markdown etc. It also great for writing parsers/compilers that only need to work in one language. USAGE The Pegex.pm module itself (this module) is just a trivial way to use the Pegex framework. It is only intended for the simplest of uses. This module exports a single function, pegex, which takes a Pegex grammar string as input. You may also pass a receiver class name after the grammar. my $parser = pegex($grammar, 'MyReceiver'); The pegex function returns a Pegex::Parser object, on which you would typically call the parse() method, which (on success) will return a data structure of the parsed data. See Pegex::API for more details. PEGEX DEBUGGING Pegex (Pegex::Parser) has many easy to use methods of debugging. See the "Debugging" section of Pegex::Parser for details. SEE ALSO * Pegex::Overview * Pegex::API * Pegex::Syntax * Pegex::Tutorial * Pegex::Resources * Pegex::Parser * http://github.com/ingydotnet/pegex-pm * irc://freenode.net#pegex AUTHOR Ingy döt Net COPYRIGHT AND LICENSE Copyright 2010-2020. Ingy döt Net. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html Changes100644001750001750 1513213621325365 13220 0ustar00ingyingy000000000000Pegex-0.750.75 Thu Feb 13 11:59:58 PST 2020 - Use YAML::PP 0.19 and remove special cases that it fixed. tinita++ 0.74 Wed Jan 22 14:57:47 PST 2020 - Fix YAML::PP and float interaction for older perls 0.73 Wed Jan 22 12:03:38 PST 2020 - Make ./ rule / same as .(/ rule /) - Use YAML::PP and JSON::PP - No XS dependencies 0.72 Sun Jan 5 14:03:42 PST 2020 - Apply https://github.com/ingydotnet/pegex-pm/pull/75 (for real) Fix P::P::Grammar title - not "::Name" @mohawk2++ 0.71 Sun Jan 5 10:59:17 PST 2020 - Apply https://github.com/ingydotnet/pegex-pm/pull/75 Fix P::P::Grammar title - not "::Name" @mohawk2++ 0.70 Sun Nov 11 16:47:51 PST 2018 - Use new Dist-Zilla-Plugin-TestMLIncluder (spaces in windows paths) 0.69 Sun Nov 11 12:10:38 PST 2018 - https://github.com/ingydotnet/pegex-pm/pull/72 @mohawk2++ 0.68 Sun Nov 11 10:57:31 PST 2018 - https://github.com/ingydotnet/pegex-pm/pull/71 @mohawk2++ 0.67 Sun Sep 2 09:30:23 PDT 2018 - https://github.com/ingydotnet/pegex-pm/pull/70 @manwar++ - https://github.com/ingydotnet/pegex-pm/pull/67 @paultcochrane++ 0.66 Sat Sep 1 11:20:12 PDT 2018 - Support back to perl5.8.1 0.65 Wed Aug 29 09:53:13 PDT 2018 - Use new TestML for tests - Support back to perl5.8.3 0.64 Sun Sep 17 19:26:03 PDT 2017 - Applied 3 small PRs from @mohawk2++ (60,61,62) 0.63 Sat Jan 14 09:31:43 PST 2017 - Fixed colors on older perls. TINITA++ - Changed on/off to always/never. TINITA++ 0.62 Fri Jan 13 22:37:55 PST 2017 - Debug color and indent options added by TINITA++ - Recursion controls. Apply PR/46 by @pdl++ (refactored) - Support Perl regex look-behind assertions 0.61 Mon Jun 13 18:10:24 PDT 2016 - Performance improvements by @agentzh++ - See PR/52 0.60 Wed Jan 28 10:44:38 PST 2015 - Added EMPTY atom - Fix small bug in a helper function. Issue - Update docs and Meta for 2015 0.59 Sun Dec 28 14:25:13 PST 2014 - Release with new TestML-0.52 0.58 Fri Dec 12 11:10:16 PST 2014 - Fix test for windows (issue - Share Pegex grammar for Pegex 0.57 Mon Oct 6 14:30:28 CEST 2014 - Added 'rule' helper method to Pegex::Receiver - Refactored the calculator examples to be dry 0.56 Fri Oct 3 22:55:58 CEST 2014 - Upgrade Mo to 0.39 - Fix problems with % - Fix whitespace matching at start of regex 0.55 Sun Aug 24 10:03:26 PDT 2014 - Doc tweak 0.54 Sat Aug 16 14:14:34 PDT 2014 - Remove =travis section 0.53 Sat Aug 16 11:55:44 PDT 2014 - Meta 0.0.2 0.52 Sat Aug 16 02:33:53 PDT 2014 - Eliminate File::Basename from test/ 0.51 Fri Aug 15 20:26:26 PDT 2014 - Remove Pegex::Mo - Add t/000-compile-modules.t 0.50 Fri Aug 15 09:30:56 PDT 2014 - Fixed a Mo bug directly - Added regression test - Mo still needs fix - See https://github.com/ingydotnet/jsony-pm/issues/2 0.49 Tue Aug 12 11:01:28 PDT 2014 - Add `receiver` accessor back into parser - Other modules use it - Add test for it 0.48 Sun Aug 10 18:18:35 PDT 2014 - Refactor Pegex.pm to match CafeScript 0.47 Sat Aug 9 12:00:13 PDT 2014 - Refactor to match CafeScript - https://github.com/ingydotnet/pegex-cafe 0.46 Fri Aug 8 19:29:32 PDT 2014 - Fix swim errors 0.45 Mon Aug 4 00:17:27 PDT 2014 - Remove (c) from Copyright - Doc fixes 0.44 Tue Jul 29 16:35:34 PDT 2014 - Some Parser refactoring. - Add a new example parser called `self-parser.pl` - Get the devel tests working again 0.43 Wed Jul 23 14:21:29 PDT 2014 - Add inlining support for text to Pegex::Grammar - Add a line_column method to Pegex::Parser 0.42 Mon Jul 21 17:25:50 PDT 2014 - Fix copyright year stuff 0.41 Thu Jul 17 10:28:16 PDT 2014 - ZD put an incorrect dep on TestML. @rurban++ 0.40 Mon Jul 14 09:56:50 PDT 2014 - Fix Meta and add Contributing file 0.39 Tue Jul 1 10:05:51 PDT 2014 - Support a maxparse debugging option 0.38 Sun Jun 29 16:02:50 PDT 2014 - Fix issue#12. Make trace work on outermost rule. 0.37 Sat Jun 28 09:52:45 PDT 2014 - More doc change for Pegex::Module. ggl++ 0.36 Sat Jun 28 09:45:54 PDT 2014 - Doc change for Pegex::Module. ggl++ 0.35 Fri Jun 27 20:55:38 PDT 2014 - Kwim to Swim 0.34 Mon Jun 23 16:02:08 PDT 2014 - Fix for issue#13 0.33 Mon Jun 16 13:45:07 PDT 2014 - Change VERSION dist strategy. 0.32 Sat Jun 14 12:26:36 PDT 2014 - New badge syntax 0.31 Sat May 17 23:43:00 PDT 2014 - Add doc badges. - Switch to Zilla::Dist - Fix a bug in Pegex::Parser 0.30 Sat May 17 23:43:00 PDT 2014 - Major release. - New cleaner syntax. - Slight breakage of backwards compatability. - Grammar authors can get help on 0.25 Sat Feb 8 14:14:59 PST 2014 - Support 5.8.1+ 0.24 Thu Feb 6 22:56:23 PST 2014 - tweak some dzil settings 0.23 Thu Feb 6 17:16:39 PST 2014 - https://rt.cpan.org/Ticket/Display.html?id=82587 - Doc and example fixes - Add 2014 to all copyrights 0.22 Wed Feb 5 11:26:05 PST 2014 - Release under dzil (thanks frew++!!) - travis testing (frew++) 0.21 Thu Nov 8 10:47:42 PST 2012 - A massive refactoring release. - 8-10 times faster parsing speed! - Support a b | c precedence in Pegex grammars. - Complete documenatation. - Examples and Tutorials - New receivers, Pegex::Tree and Pegex::Tree::Wrap - API becomes more solidified. 0.20 Thu Aug 30 00:06:30 PDT 2012 - Refactored Pegex to make API less flexible but more sensible, explainable and maintainable. 0.19 Sat Nov 5 01:16:15 PDT 2011 - Fixed Test::Differences missing. 0.18 Fri Sep 30 00:44:35 CEST 2011 - Use Mo 0.25 - Support advanced quantifiers and %/%% - Rename classes - Make AST class use unwrap events and be much simpler. 0.17 Wed Sep 21 23:42:00 CEST 2011 - Complete refactoring of everything. - This hard fought gem was released from Liz++ and Wendy++'s TV room. 0.16 Fri Sep 9 14:51:38 CEST 2011 - Changed AST model to be faster and simpler. 0.15 Wed Sep 7 10:17:11 BST 2011 - With this release of Pegex, I do declare the true birthday of Acmeism. THis release was performed from the living room of Leon "Acme" Brocard. How fitting. His daughter Lara was present to witness her first ever CPAN release. 0.14 Sat Aug 20 18:19:20 CEST 2011 - Fix TestML dep with new version of Module::Package 0.13 Fri Aug 19 20:51:18 EEST 2011 - Use updated version of TestML with updated version of Pegex! - Switch Mouse back to Gloom 0.12 Sun Aug 14 17:27:13 EEST 2011 - Switch OO to Mouse 0.11 Fri Sep 10 10:41:30 PDT 2010 - Add manifest_skip and readme_from to Makefile.PL 0.10 Thu Sep 9 10:41:30 PDT 2010 - Changes supporting TestML 0.20 0.05 Sat Aug 14 17:11:17 PDT 2010 - Add REPOSITORY and COMMUNITY info to doc. 0.04 Sat Aug 14 17:11:17 PDT 2010 - Use new Gloom for base OO. 0.02 Tue Aug 10 01:15:58 PDT 2010 - Changed name from Parse::Pegex to Pegex. 0.01 Tue Aug 3 02:42:29 PDT 2010 - Initial version. t000755001750001750 013621325365 12006 5ustar00ingyingy000000000000Pegex-0.75api.t100644001750001750 103113621325365 13077 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; use Pegex::Parser; use Pegex::Grammar; use Pegex::Receiver; use Pegex::Input; my $p = Pegex::Parser->new( grammar => Pegex::Grammar->new, receiver => Pegex::Receiver->new, input => Pegex::Input->new, debug => 1, ); ok $p->grammar, 'grammar accessor works'; ok $p->receiver, 'receiver accessor works'; ok $p->input, 'input accessor works'; ok $p->debug, 'debug accessor works'; eval { Pegex::Parser->new }; ok $@ =~ /grammar required/, 'grammar is required'; done_testing; LICENSE100644001750001750 4366013621325365 12741 0ustar00ingyingy000000000000Pegex-0.75This software is copyright (c) 2020 by Ingy döt Net. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2020 by Ingy döt Net. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, 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 make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the 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 a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE 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. END OF TERMS AND CONDITIONS Appendix: 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 humanity, 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 convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 1, 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision 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, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2020 by Ingy döt Net. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End tree.t100644001750001750 1124313621325365 13313 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan parse-to-tree(*grammar, *input).yaml.clean == *tree :"+ - Pegex::Tree" parse-to-tree-wrap(*grammar, *input).yaml.clean == *wrap :"+ - Pegex::Tree::Wrap" parse-to-tree-test(*grammar, *input).yaml.clean == *ast :"+ - t::TestAST" === Single Regex - Single Capture --- grammar a: /x*(y*)z* EOL/ --- input xxxyyyyzzz --- tree yyyy --- wrap a: yyyy === Single Regex - Multi Capture --- grammar a: /(x*)(y*)(z*) EOL/ --- input xxxyyyyzzz --- tree - xxx - yyyy - zzz --- wrap a: - xxx - yyyy - zzz === Multi Group Regex --- grammar t: /.*(x).*(y).*(z).*/ --- input: aaaxbbbyccczddd --- tree - x - y - z --- wrap t: - x - y - z === Single Regex - No Capture --- grammar a: /x*y*z* EOL/ --- input xxxyyyyzzz --- tree [] --- wrap a: [] === Non capture Regex --- grammar a: b b* -c* .d* b: /b/ c: /c+/ d: /d/ --- input: bbccdd --- tree - [] --- wrap a: - [] === A subrule --- grammar a: b /(y+)/ EOL b: /(x+)/ --- input xxxyyyy --- tree - xxx - yyyy --- wrap a: - b: xxx - yyyy === Multi match regex in subrule --- grammar a: b b: /(x*)y*(z*) EOL/ --- input xxxyyyyzzz --- tree - xxx - zzz --- wrap a: b: - xxx - zzz === Any rule group --- grammar a: (b | c) b: /(bleh)/ c: /(x*)y*(z*) EOL?/ --- input xxxyyyyzzz --- tree - xxx - zzz --- wrap a: c: - xxx - zzz === + Modifier --- grammar a: ( b c )+ EOL b: /(x*)/ c: /(y+)/ --- input xxyyxy --- tree - - - xx - yy - - x - y --- wrap a: - - - b: xx - c: yy - - b: x - c: y === Wrap Pass and Skip --- grammar a: +b -c .d b: /(b+)/ c: /(c+)/ d: /(d+)/ --- input: bbccdd --- tree - b: bb - cc --- wrap a: - b: bb - c: cc === Flat and Skip Multi --- grammar a: b* -c* .d* b: /(b)/ c: /(c)/ d: /(d)/ --- input: bccdd --- tree - - b - c - c --- wrap a: - - b: b - c: c - c: c === Skip Bracketed --- grammar a: b .(c d) b: /(b)/ c: /(c+)/ d: /(d+)/ --- input: bcccd --- tree b --- wrap a: b: b === Assertions --- grammar a: !b =c c b: /b/ c: /(c+)/ --- input: ccc --- tree ccc --- wrap a: c: ccc === Assertion not captured --- grammar a: =x x y EOL x: /(x+)/ y: /(y+)/ --- input xxxyyyy --- tree - xxx - yyyy --- wrap a: - x: xxx - y: yyyy === Empty regex group plus rule --- grammar a: b* c EOL b: /xxx/ c: /(yyy)/ --- input xxxyyy --- tree - [] - yyy --- wrap a: - [] - c: yyy === Rule to Rule to Rule --- grammar a: b b: c* c: d EOL d: /x(y)z/ --- input xyz xyz --- tree - - y - - y --- wrap a: b: - c: - d: y - c: - d: y === List and Separators --- grammar a: b c+ % d b: /(b)/ c: /(c+)/ d: /(d+)/ --- input: bcccdccddc --- tree - b - - ccc - d - cc - dd - c --- wrap a: - b: b - - c: ccc - d: d - c: cc - d: dd - c: c === Rule with Separator --- grammar a: c* % d c: /(c+)/ d: /d+/ --- input: cccdccddc --- tree - ccc - cc - c --- wrap a: - c: ccc - c: cc - c: c === List without Separators --- grammar a: b c* % d b b: /(b)/ c: /(c+)/ d: /d+/ --- input: bb --- tree - b - [] - b --- wrap a: - b: b - [] - b: b === Whitespace Matchers --- grammar TOP: / ws*( DOT ) - ( DOT* ) -/ --- input . .. --- tree - . - .. --- wrap TOP: - . - .. === Automatically Pass TOP --- grammar b: /(b)/ TOP: b c* c: /(c)/ --- input: bcc --- tree - b - - c - c --- wrap TOP: - b: b - - c: c - c: c === Empty Stars --- grammar a: ( b* c )+ b* b: /(b)/ c: /(c+)/ --- input: cc --- tree - - - [] - cc - [] --- wrap a: - - - [] - c: cc - [] === Exact Quantifier --- grammar a: 3 b: /(b)/ --- input: bbb --- tree - b - b - b --- wrap a: - b: b - b: b - b: b === Quantifier with Separator --- grammar a: 2-4 %% /,/ b: /(b)/ --- input: b,b,b, --- tree - b - b - b --- wrap a: - b: b - b: b - b: b === Quantifier with Separator, Trailing OK --- grammar a: 2-4 %% /,/ b: /(b)/ --- input: b,b,b, --- tree - b - b - b --- wrap a: - b: b - b: b - b: b === Quantifier on the Separator --- grammar a: 2-4 %% c* b: /(b)/ c: / COMMA / --- input: b,b,,,,bb, --- tree - b - [] - b - [] - b - [] - b --- wrap a: - b: b - [] - b: b - [] - b: b - [] - b: b === Tilde matching --- grammar a: - b + b+ b: /(b)/ c: / COMMA / --- input: b bb --- tree - b - - b - b --- wrap a: - b: b - - b: b - b: b === False Values --- grammar a: zero empty undef zero: /(b+)/ empty: /(c+)/ undef: /(d+)/ --- input: bbccdd --- ast - 0 - '' - null === Wrap --- grammar a: b c d b: /(b+)/ c: /(c+)/ d: /(d+)/ --- input: bbccdd --- wrap a: - b: bb - c: cc - d: dd === 2 + 1 --- SKIP --- grammar a: 2 b b: /(b)/ --- input: bbb --- ast - b - b - b === Separated Group --- grammar a: (b | c)+ % d b: /(b)/ c: /(c)/ d: /(d)/ --- input: bdcdb --- ast - b - d - c - d - b === Separator Group --- grammar a: b+ %% (c | d) b: /(b)/ c: /(c)/ d: /(d)/ --- input: bdbcbc --- ast - b - d - b - c - b - c safe.t100644001750001750 56313621325365 13235 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; # 2015-02-03 Safe.pm fails to load on Travis + 5.14 BEGIN { if ($ENV{TRAVIS} eq 'true' and $ENV{TRAVIS_PERL_VERSION} eq '5.14') { plan skip_all => 'Travis/Safe/5.14'; } } use Safe; BEGIN { Safe->new } use Pegex; pegex('a: /a/')->parse('a'); pass 'GitHub ingydotnet/jsony-pm issue #2 fixed'; done_testing; MANIFEST100644001750001750 467413621325365 13047 0ustar00ingyingy000000000000Pegex-0.75# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.012. CONTRIBUTING Changes LICENSE MANIFEST META.json META.yml Makefile.PL README example/calculator/calculator1.pl example/calculator/calculator2.pl example/calculator/lib/Precedence.pm example/calculator/lib/Runner.pm example/calculator/tests example/calculator/tokenizer.pl example/self-parser.pl inc/bin/testml-cpan inc/lib/TestML/Boolean.pm inc/lib/TestML/Bridge.pm inc/lib/TestML/Run.pm inc/lib/TestML/Run/TAP.pm inc/lib/TestML/StdLib.pm inc/t/compiler-checks.tml.lingy inc/t/compiler-equivalence.tml.lingy inc/t/compiler-perl.tml.lingy inc/t/compiler.tml.lingy inc/t/error.tml.lingy inc/t/optimize.tml.lingy inc/t/tree-pegex.tml.lingy inc/t/tree.tml.lingy lib/Pegex.pm lib/Pegex.pod lib/Pegex/API.pod lib/Pegex/Base.pm lib/Pegex/Bootstrap.pm lib/Pegex/Bootstrap.pod lib/Pegex/Compiler.pm lib/Pegex/Compiler.pod lib/Pegex/Grammar.pm lib/Pegex/Grammar.pod lib/Pegex/Grammar/Atoms.pm lib/Pegex/Grammar/Atoms.pod lib/Pegex/Input.pm lib/Pegex/Input.pod lib/Pegex/Miscellany.pod lib/Pegex/Module.pm lib/Pegex/Module.pod lib/Pegex/Optimizer.pm lib/Pegex/Overview.pod lib/Pegex/Parser.pm lib/Pegex/Parser.pod lib/Pegex/Parser/Indent.pm lib/Pegex/Pegex/AST.pm lib/Pegex/Pegex/Grammar.pm lib/Pegex/Pegex/Grammar.pod lib/Pegex/Receiver.pm lib/Pegex/Receiver.pod lib/Pegex/Regex.pm lib/Pegex/Regex.pod lib/Pegex/Resources.pod lib/Pegex/Syntax.pod lib/Pegex/Tree.pm lib/Pegex/Tree.pod lib/Pegex/Tree/Wrap.pm lib/Pegex/Tree/Wrap.pod lib/Pegex/Tutorial.pod lib/Pegex/Tutorial/Calculator.pod lib/Pegex/Tutorial/JSON.pod share/pegex.pgx t/000-compile-modules.t t/TestAST.pm t/TestMLBridge.pm t/api.t t/author-pod-syntax.t t/compiler-checks.t t/compiler-equivalence.t t/compiler-perl.t t/compiler.t t/error.t t/export-api.t t/flatten.t t/function-rule.t t/grammar-api.t t/look-behind.t t/mice.pgx t/optimize.t t/parse.t t/pegex-tml/compiler-checks.tml t/pegex-tml/compiler-equivalence.tml t/pegex-tml/compiler.tml t/pegex-tml/error.tml t/pegex-tml/optimize.tml t/pegex-tml/tree-pegex.tml t/pegex-tml/tree.tml t/repeat.t t/safe.t t/sample.t t/testml.yaml t/tree-pegex.t t/tree.t xt/TestDevelPegex.pm xt/compilers.t xt/grammars/Makefile xt/grammars/Pg.pgx xt/grammars/drinkup.pgx xt/grammars/eyapp2pegex.pgx xt/grammars/json.pgx xt/grammars/kwim.pgx xt/grammars/pegex.pgx xt/grammars/pg-lexer.pgx xt/grammars/swim.pgx xt/grammars/testml.pgx xt/grammars/vic.pgx xt/grammars/yaml.pgx xt/speed-ast.t xt/speed.t xt/test-pegex-repos.t META.yml100644001750001750 164413621325365 13161 0ustar00ingyingy000000000000Pegex-0.75--- abstract: 'Acmeist PEG Parser Framework' author: - 'Ingy döt Net ' build_requires: JSON::PP: '0' Test::Pod: '0' Tie::IxHash: '0' configure_requires: ExtUtils::MakeMaker: '0' File::ShareDir::Install: '0.06' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Pegex no_index: directory: - example - inc - t - xt requires: Carp: '0' File::ShareDir::Install: '0' JSON::PP: '0' Scalar::Util: '0' XXX: '0.35' YAML::PP: '0.019' perl: v5.8.1 resources: bugtracker: https://github.com/ingydotnet/pegex-pm/issues homepage: https://github.com/ingydotnet/pegex-pm repository: https://github.com/ingydotnet/pegex-pm.git version: '0.75' x_generated_by_perl: v5.28.0 x_serialization_backend: 'YAML::Tiny version 1.73' error.t100644001750001750 521113621325365 13463 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan parse-input(*grammar, *input).Catch.Msg ~~ *error :"Test error message: +" === Error fails at furthest match # XXX This one not testing much. --- grammar a: b+ c b: /b/ c: /c/ --- input bbbbddddd --- error: ddddd\n ### TODO ### # === Pegex: Illegal meta rule # --- grammar # %grammar Test # %foobar Quark # a: /a+/ # --- input # aaa # --- error: Illegal meta rule === Pegex: Rule header syntax error --- grammar a|: /a+/ --- input aaa --- error: Rule header syntax error === Pegex: Rule ending syntax error --- grammar a: /a+/ | --- input aaa --- error: Rule ending syntax error === Pegex: Illegal rule modifier --- grammar a: /a+/ b: ^1-2 --- input aaa --- error: Illegal rule modifier === Pegex: Missing > in rule reference --- grammar a: /a+/ b: ! in rule reference === Pegex: Missing < in rule reference --- grammar a: /a+/ b: !a>1-2 --- input aaa --- error: Rule ending syntax error # --- error: Missing < in rule reference === Pegex: Illegal character in rule quantifier --- grammar a: /a+/ b: !a^1-2 --- input aaa --- error: Rule ending syntax error # --- error: Illegal character in rule quantifier === Pegex: Unprotected rule name with numeric quantifier --- grammar a: /a+/ b: !a1-2 --- input aaa --- error: Parse document failed for some reason # --- error: Rule ending syntax error # --- error: Unprotected rule name with numeric quantifier === Pegex: Runaway regular expression --- grammar a: /a+ --- input aaa --- error: Runaway regular expression === Pegex: Illegal group rule modifier --- grammar a: /a+/ b: !(a =)1-2 --- input aaa --- error: Illegal group rule modifier === Pegex: Runaway rule group --- grammar a: /a+/ b: .(a =1-2 --- input aaa --- error: Runaway rule group === Pegex: Illegal character in group rule quantifier --- grammar a: /a+/ b: .(a =)^2 --- input aaa --- error: Rule ending syntax error # --- error: Illegal character in group rule quantifier === Pegex: Multi-line error messages not allowed --- grammar a: /a+/ b: `This is legal` c: `This is illegal` --- input aaa --- error: Multi-line error messages not allowed === Pegex: Runaway error message --- grammar a: /a+/ b: `This is legal` c: `This is illegal --- input aaa --- error: Runaway error message === Pegex: Leading separator form (BOK) no longer supported --- grammar a: /a+/ %%% ~ --- input aaa --- error: Rule ending syntax error # --- error: Leading separator form (BOK) no longer supported === Pegex: Illegal characters in separator indicator --- grammar a: /a+/ %%~%%^%% ~ --- input aaa --- error: Rule ending syntax error # --- error: Illegal characters in separator indicator parse.t100644001750001750 47513621325365 13433 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; # $Pegex::Parser::Debug = 1; my $t; use lib ($t = -e 't' ? 't' : 'test'); use Test::More tests => 1; use Pegex; use Pegex::Input; my $grammar_file = "$t/mice.pgx"; eval { pegex( Pegex::Input->new(file => $grammar_file) )->parse("3 blind mice\n") }; $@ ? fail $@ : pass "! works"; META.json100644001750001750 333013621325365 13323 0ustar00ingyingy000000000000Pegex-0.75{ "abstract" : "Acmeist PEG Parser Framework", "author" : [ "Ingy d\u00f6t Net " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Pegex", "no_index" : { "directory" : [ "example", "inc", "t", "xt" ] }, "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0", "File::ShareDir::Install" : "0.06" } }, "develop" : { "requires" : { "Test::Pod" : "1.41" } }, "runtime" : { "requires" : { "Carp" : "0", "File::ShareDir::Install" : "0", "JSON::PP" : "0", "Scalar::Util" : "0", "XXX" : "0.35", "YAML::PP" : "0.019", "perl" : "v5.8.1" } }, "test" : { "requires" : { "JSON::PP" : "0", "Test::Pod" : "0", "Tie::IxHash" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/ingydotnet/pegex-pm/issues" }, "homepage" : "https://github.com/ingydotnet/pegex-pm", "repository" : { "type" : "git", "url" : "https://github.com/ingydotnet/pegex-pm.git", "web" : "https://github.com/ingydotnet/pegex-pm" } }, "version" : "0.75", "x_generated_by_perl" : "v5.28.0", "x_serialization_backend" : "Cpanel::JSON::XS version 4.06" } xt000755001750001750 013621325365 12176 5ustar00ingyingy000000000000Pegex-0.75speed.t100644001750001750 71413621325365 13605 0ustar00ingyingy000000000000Pegex-0.75/xtuse strict; use warnings; use Test::More; use lib -e 'xt' ? 'xt' : 'test/devel'; use TestDevelPegex; for my $grammar (test_grammar_paths) { my $parser = pegex_parser; my $input = slurp($grammar); my $timer = [gettimeofday]; my $result = eval { $parser->parse($input) }; my $time = tv_interval($timer); if ($result) { pass "$grammar parses in $time seconds"; } else { fail "$grammar failed to parse $@"; } } repeat.t100644001750001750 37113621325365 13574 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; use Pegex; my $parser = pegex('a: /*?(x+)*/'); is $parser->parse('xxxx')->{a}, 'xxxx', 'First parse works'; is $parser->parse('xxxx')->{a}, 'xxxx', 'Second parse works'; done_testing; sample.t100644001750001750 241213621325365 13613 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; eval "use YAML::PP; 1" or plan skip_all => 'YAML::PP required'; plan tests => 1; my $grammar_text = <<'...'; contact: name_section phone_section address_section name_section: / 'Name' + / name EOL name: /(+)(+)/ phone_section: /Phone+/ phone_number: term address_section: /Address/ street_line city_line country_line? street_line: indent street EOL street: /*/ city_line: indent city EOL city: term country_line: indent country EOL country: term term: /( # NS is "non-space" * )/ indent: /{2}/ ... my $input = <<'...'; Name: Ingy Net Phone: 919-876-5432 Address: 1234 Main St Niceville OK ... my $want = <<'...'; ... use Pegex::Grammar; use Pegex::Receiver; use Pegex::Compiler; my $grammar = Pegex::Grammar->new( tree => Pegex::Compiler->new->compile($grammar_text)->tree, ); my $parser = Pegex::Parser->new( grammar => $grammar, receiver => Pegex::Receiver->new, debug => 1, ); my $ast1 = $parser->parse($input); pass 'parsed'; exit; my $got = YAML::PP ->new(schema => ['Perl']) ->dump_string($ast1); is $got, $want, 'It works'; mice.pgx100644001750001750 13413621325365 13561 0ustar00ingyingy000000000000Pegex-0.75/tphrase: !one number - things EOL one: /1/ number: DIGIT things: / 'blind' SPACE 'mice' / flatten.t100644001750001750 103313621325365 13765 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More tests => 1; use Pegex; my $grammar = <<'...'; a: (((b)))+ b: (c | d) c: /(x)/ d: /y/ ... { package R; use base 'Pegex::Receiver'; sub got_a { my ($self, $got) = @_; $self->flatten($got); $got; } sub got_b { my ($self, $got) = @_; [$got]; } sub got_c { my ($self, $got) = @_; [$got]; } } my $parser = pegex($grammar, 'R'); my $got = $parser->parse('xxx'); is join('', @$got), 'xxx', 'Array was flattened'; Makefile.PL100644001750001750 466113621325365 13664 0ustar00ingyingy000000000000Pegex-0.75# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.012. use strict; use warnings; use 5.008001; use ExtUtils::MakeMaker; use File::ShareDir::Install; $File::ShareDir::Install::INCLUDE_DOTFILES = 1; $File::ShareDir::Install::INCLUDE_DOTDIRS = 1; install_share dist => "share"; my %WriteMakefileArgs = ( "ABSTRACT" => "Acmeist PEG Parser Framework", "AUTHOR" => "Ingy d\x{f6}t Net ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0, "File::ShareDir::Install" => "0.06" }, "DISTNAME" => "Pegex", "LICENSE" => "perl", "MIN_PERL_VERSION" => "5.008001", "NAME" => "Pegex", "PREREQ_PM" => { "Carp" => 0, "File::ShareDir::Install" => 0, "JSON::PP" => 0, "Scalar::Util" => 0, "XXX" => "0.35", "YAML::PP" => "0.019" }, "TEST_REQUIRES" => { "JSON::PP" => 0, "Test::Pod" => 0, "Tie::IxHash" => 0 }, "VERSION" => "0.75", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Carp" => 0, "File::ShareDir::Install" => 0, "JSON::PP" => 0, "Scalar::Util" => 0, "Test::Pod" => 0, "Tie::IxHash" => 0, "XXX" => "0.35", "YAML::PP" => "0.019" ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); { package MY; use File::ShareDir::Install qw(postamble); } use Config; use File::Find; my $file = 'inc/bin/testml-cpan'; open IN, '<', $file or die "Can't open '$file' for input"; my @bin = ; close IN; shift @bin; unshift @bin, "#!$Config{perlpath}\n"; open OUT, '>', $file or die "Can't open '$file' for output"; print OUT @bin; close OUT; chmod 0755, 'inc/bin/testml-cpan'; if ($^O eq 'MSWin32') { my $file = 'inc/bin/testml-cpan.cmd'; open OUT, '>', $file or die "Can't open '$file' for output"; print OUT 'if exist "%~dpn0" perl %0 %*', "\r\n"; close OUT; find sub { return unless -f && /\.t$/; my $file = $_; open IN, '<', $file or die "Can't open '$file' for input"; return unless =~ /testml-cpan/; my $text = do {local $/; }; close IN; open OUT, '>', $file or die "Can't open '$file' for output"; print OUT '#!inc\\bin\\testml-cpan', "\r\n"; print OUT $text; close OUT; }, 't'; } CONTRIBUTING100644001750001750 234013621325365 13534 0ustar00ingyingy000000000000Pegex-0.75Contributing ============ The "Pegex" Project needs your help! Please consider being a contributor. This file contains instructions that will help you be an effective contributor to the Project. GitHub ------ The code for this Project is hosted at GitHub. The URL is: https://github.com/ingydotnet/pegex-pm You can get the code with this command: git clone https://github.com/ingydotnet/pegex-pm If you've found a bug or a missing feature that you would like the author to know about, report it here: https://github.com/ingydotnet/pegex-pm/issues or fix it and submit a pull request here: https://github.com/ingydotnet/pegex-pm/pulls See these links for help on interacting with GitHub: * https://help.github.com/ * https://help.github.com/articles/creating-a-pull-request Zilla::Dist ----------- This Project uses Zilla::Dist to prepare it for publishing to CPAN. Read: https://metacpan.org/pod/Zilla::Dist::Contributing for up-to-date instructions on what contributors like yourself need to know to use it. IRC --- Pegex has an IRC channel where you can find real people to help you: irc.freenode.net#pegex Join the channel. Join the team! Thanks in advance, # This file generated by Zilla-Dist-0.1.4 lib000755001750001750 013621325365 12311 5ustar00ingyingy000000000000Pegex-0.75Pegex.pm100644001750001750 135613621325365 14064 0ustar00ingyingy000000000000Pegex-0.75/libuse strict; use warnings; package Pegex; our $VERSION = '0.75'; use Pegex::Parser; use base 'Exporter'; our @EXPORT = 'pegex'; sub pegex { my ($grammar, $receiver) = @_; die "Argument 'grammar' required in function 'pegex'" unless $grammar; if (not ref $grammar or $grammar->isa('Pegex::Input')) { require Pegex::Grammar; $grammar = Pegex::Grammar->new(text => $grammar), } if (not defined $receiver) { require Pegex::Tree::Wrap; $receiver = Pegex::Tree::Wrap->new; } elsif (not ref $receiver) { eval "require $receiver; 1"; $receiver = $receiver->new; } return Pegex::Parser->new( grammar => $grammar, receiver => $receiver, ); } 1; TestAST.pm100644001750001750 22513621325365 13752 0ustar00ingyingy000000000000Pegex-0.75/tpackage TestAST; use Pegex::Base; extends 'Pegex::Tree'; sub got_zero { return 0 }; sub got_empty { return '' }; sub got_undef { return undef } 1; compiler.t100644001750001750 335113621325365 14147 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan *grammar.compile.yaml == *grammar.bootstrap-compile.yaml :"Compiler output matches bootstrap? - +" === Single Regex --- grammar a: /x/ === Single Reference --- grammar a: === Single Error --- grammar a: `b` === Simple All Group --- grammar a: /b/ === Simple Any Group --- grammar a: | === Bracketed All Group --- grammar a: ( /c/ ) === Bracketed Any Group --- grammar a: ( | /c/ | `d` ) === Bracketed Group in Unbracketed Group --- grammar a: ( | ) === And over Or Precedence --- SKIP --- grammar a: | | % === Multiple Rules --- grammar a: b: === Simple Grammar --- grammar a: ( * ) b: /x/ c: /y+/ === Semicolons OK --- grammar a: ; b: c: /d/; === Unbracketed --- grammar a: b: | === Not Rule --- grammar a: ! === Multiline --- grammar a: b: /c/ ; c: | ( /e/ ) | `g` === Various Groups --- grammar a: ( | ) b: ( | ) c: | ( ) | d: | ( ) | | ( `i` ) e: ( ) === Modifiers --- grammar a: ! = b: ( /c/ )+ c: ( /c/ )+ === Any Group Plus Rule --- grammar a: /w/ ( + | * ) ? === Equivalent --- grammar a: c: ! === Regex and Rule --- grammar a_b: /c/ === Quantified group --- grammar a: ( * | + )+ e: ( ! )? === Multiple Regex --- grammar b: ( /x/ )+ # XXX The \\# looks lie a testml bug. Should only need \#. === Comments --- grammar(#) # line comment a: b # end of line comment b: / foo # regex comment # regex line comment bar # regex line comment / === Comment between rules --- grammar(#) a: b # comment b: c optimize.t100644001750001750 36213621325365 14154 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan 1 == 1 :"[SKIP] Skipping this test for now. Might need a %Skip in TestML." # *grammar.compile.optimize.yaml.clean == *yaml === Question Mark Expansion --- SKIP --- grammar a: /(:foo)/ --- yaml a: .rgx: /(?:foo)/ Pegex.pod100644001750001750 734313621325365 14234 0ustar00ingyingy000000000000Pegex-0.75/lib=pod =for comment DO NOT EDIT. This Pod was generated by Swim v0.1.48. See http://github.com/ingydotnet/swim-pm#readme =encoding utf8 =head1 NAME Pegex - Acmeist PEG Parser Framework =head1 VERSION This document describes L version B<0.75>. =head1 SYNOPSIS use Pegex; my $result = pegex($grammar)->parse($input); or with options: use Pegex; use ReceiverClass; my $parser = pegex($grammar, 'ReceiverClass'); my $result = $parser->parse($input); or more explicitly: use Pegex::Parser; use Pegex::Grammar; my $pegex_grammar = Pegex::Grammar->new( text => $grammar, ); my $parser = Pegex::Parser->new( grammar => $pegex_grammar, ); my $result = $parser->parse($input); or customized explicitly: { package MyGrammar; use Pegex::Base; extends 'Pegex::Grammar'; has text => "your grammar definition text goes here"; has receiver => "MyReceiver"; } { package MyReceiver; use base 'Pegex::Receiver'; got_some_rule { ... } got_other_rule { ... } } use Pegex::Parser; my $parser = Pegex::Parser->new( grammar => MyGrammar->new, receiver => MyReceiver->new, ); $parser->parse($input); my $result = $parser->receiver->data; =head1 DESCRIPTION Pegex is an Acmeist parser framework. It allows you to easily create parsers that will work equivalently in lots of programming languages! The inspiration for Pegex comes from the parsing engine upon which the postmodern programming language B is based on. Pegex brings this beauty to the other Imodern languages that have a normal regular expression engine available. Pegex gets it name by combining Parsing Expression Grammars (PEG), with Regular Expressions (Regex). That's actually what Pegex does. PEG is the cool new way to elegantly specify recursive descent grammars. The Perl 6 language is defined in terms of a self modifying PEG language called B. Regexes are familiar to programmers of most modern programming languages. Pegex defines a simple PEG syntax, where all the terminals are regexes. This means that Pegex can be quite fast and powerful. Pegex attempts to be the simplest way to define new (or old) Domain Specific Languages (DSLs) that need to be used in several programming languages and environments. Things like JSON, YAML, Markdown etc. It also great for writing parsers/compilers that only need to work in one language. =head1 USAGE The C module itself (this module) is just a trivial way to use the Pegex framework. It is only intended for the simplest of uses. This module exports a single function, C, which takes a Pegex grammar string as input. You may also pass a receiver class name after the grammar. my $parser = pegex($grammar, 'MyReceiver'); The C function returns a L object, on which you would typically call the C method, which (on success) will return a data structure of the parsed data. See L for more details. =head1 PEGEX DEBUGGING Pegex (Pegex::Parser) has many easy to use methods of debugging. See the "Debugging" section of L for details. =head1 SEE ALSO =over =item * L =item * L =item * L =item * L =item * L =item * L =item * L =item * L =back =head1 AUTHOR Ingy döt Net =head1 COPYRIGHT AND LICENSE Copyright 2010-2020. Ingy döt Net. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut testml.yaml100644001750001750 67413621325365 14331 0ustar00ingyingy000000000000Pegex-0.75/tsource_testml_dir: ../ext/pegex-tml local_testml_dir: ./testml test_file_prefix: testml- test_file_template: | [% testml_setup_comment -%] use strict; use lib (-e 't' ? 't' : 'test'), 'inc'; use File::Spec; use TestML; use TestML::Compiler::Lite; use TestMLBridge; TestML->new( testml => File::Spec->catfile(qw{[% path.join(' ') %]}), bridge => 'TestMLBridge', compiler => 'TestML::Compiler::Lite', )->run; speed-ast.t100644001750001750 72013621325365 14367 0ustar00ingyingy000000000000Pegex-0.75/xtuse strict; use warnings; use Test::More; use lib -e 'xt' ? 'xt' : 'test/devel'; use TestDevelPegex; for my $grammar (test_grammar_paths) { my $parser = pegex_parser_ast; my $input = slurp($grammar); my $timer = [gettimeofday]; my $result = eval { $parser->parse($input) }; my $time = tv_interval($timer); if ($result) { pass "$grammar parses in $time seconds"; } else { fail "$grammar failed to parse $@"; } } compilers.t100644001750001750 124113621325365 14516 0ustar00ingyingy000000000000Pegex-0.75/xt# BEGIN { $TestML::Test::Differences = 1 } # BEGIN { $Pegex::Parser::Debug = 1 } # BEGIN { $Pegex::Bootstrap = 1 } use strict; use warnings; use Test::More; use lib -e 'xt' ? 'xt' : 'test/devel'; use TestDevelPegex; use Pegex::Bootstrap; use Pegex::Compiler; use YAML::PP; for my $grammar (test_grammar_paths) { my $expected = eval { Dump(Pegex::Bootstrap->new->parse(slurp($grammar))->tree); } or next; my $got = eval { Dump(Pegex::Bootstrap->new->parse(slurp($grammar))->tree); } or die "$grammar failed to compile: $@"; is $got, $expected, "Bootstrap compile matches normal compile for $grammar"; } pass "Pass one test"; tree-pegex.t100644001750001750 226713621325365 14407 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan parse-to-tree(*grammar, *input).yaml.clean == *tree :"+ - Pegex::Tree" parse-to-tree-wrap(*grammar, *input).yaml.clean == *wrap :"+ - Pegex::Tree::Wrap" parse-to-tree-test(*grammar, *input).yaml.clean == *ast :"+ - TestAST" === Part of Pegex Grammar --- grammar(#) # This is the Pegex grammar for Pegex grammars! grammar: ( * )+ * rule_definition: /*/ /*/ rule_name: /(*)/ comment: // line: /*/ rule_line: /()/ --- input(#) # This is the Pegex grammar for Pegex grammars! grammar: ( * )+ * rule_definition: /*/ /*/ --- tree - - - [] - - grammar - ( * )+ * - - [] - - rule_definition - /*/ /*/ - [] --- wrap grammar: - - - [] - rule_definition: - rule_name: grammar - rule_line: ( * )+ * - - [] - rule_definition: - rule_name: rule_definition - rule_line: /*/ /*/ - [] export-api.t100644001750001750 143413621325365 14425 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; # BEGIN { $Pegex::Parser::Debug = 1 } use Test::More tests => 8; use Pegex; ok defined(&pegex), 'pegex is exported'; my $parser1 = pegex("foo: \n"); is ref($parser1), 'Pegex::Parser', 'pegex returns a Pegex::Parser object'; is $parser1->grammar->tree->{'+toprule'}, 'foo', 'pegex() contains a grammar with a compiled tree'; my $parser2 = pegex(<<'...'); number: /+/ ... eval { $parser2->parse('123'); pass '$parser2->parse worked'; }; fail $@ if $@; is ref $parser2, 'Pegex::Parser', 'grammar property is Pegex::Parser object'; my $tree2 = $parser2->grammar->tree; ok $tree2, 'Grammar object has tree'; ok ref($tree2), 'Grammar object is compiled to a tree'; is $tree2->{'+toprule'}, 'number', '_FIRST_RULE is set correctly'; share000755001750001750 013621325365 12645 5ustar00ingyingy000000000000Pegex-0.75pegex.pgx100644001750001750 1245413621325365 14663 0ustar00ingyingy000000000000Pegex-0.75/share# This is the Pegex grammar for Pegex grammars! %grammar pegex %version 0.2.0 %include pegex-atoms grammar: meta-section rule-section ( doc-ending | ERROR-rule-definition ) meta-section: ( meta-definition | + | ERROR-meta-definition )* rule-section: ( rule-definition | + )* meta-definition: / '%' meta-name BLANK+ meta-value / rule-definition: rule-start rule-group ending rule-start: / ( rule-name ) BLANK* ':' -/ rule-group: any-group any-group: /- '|'? -/ all-group ( /- '|' -/ all-group )* all-group: rule-part (- rule-part)* rule-part: (rule-item)1-2 % /+ ( '%'{1,2} ) +/ rule-item: | bracketed-group | whitespace-token | rule-reference | quoted-regex | regular-expression | error-message rule-reference: / ( rule-modifier? ) # [=!.-+] (: # foo | ( rule-name ) | (: '<' ( rule-name ) '>' ) ) ( rule-quantifier? ) # [?*+] 2+ 2-3 (! BLANK* ':' ) # Avoid parsing 'foo:' / # as a rule reference. quoted-regex: / TICK ( [^ TICK ]* ) TICK / regular-expression: /( group-modifier? )/ '/' whitespace-start? ( | whitespace-must | whitespace-maybe | quoted-regex | regex-rule-reference | + | regex-raw )* '/' whitespace-start: / ([ PLUS DASH]) (! [ DASH TILDE ]) / whitespace-must: /+ (: PLUS | DASH DASH ) (= [ SPACE SLASH CR NL ]) / whitespace-maybe: /- DASH (= [ SPACE SLASH CR NL ]) / regex-rule-reference: / (: + ( rule-name ) | (: '<' ( rule-name ) '>' ) ) (! BLANK* ':' ) / regex-raw: / ( '(?'? '<' | (?:[^ WS SLASH TICK LANGLE ])+ ) / bracketed-group: / ( group-modifier? ) '(' -/ rule-group /- ')' ( rule-quantifier? ) / whitespace-token: / ( (: PLUS | DASH | DASH DASH | TILDE | TILDE TILDE ) ) (= + )/ error-message: / '`' ( [^ '`' DOS ]* ) '`' / rule-modifier: / [ BANG EQUAL PLUS DASH DOT ] / group-modifier: / [ DASH DOT ] / rule-quantifier: / (: [ STAR PLUS QMARK ] | DIGIT+ (: DASH DIGIT+ | PLUS)? ) / meta-name: / ( 'grammar' | 'extends' | 'include' | 'version' ) / meta-value: / BLANK* ( [^ SEMI BREAK ]*? ) BLANK* ending / rule_name: / (: ALPHA ALNUM* (:[ DASH UNDER ] ALNUM+)* | DASH+ | UNDER+ ) (= [^ WORD DASH ]) / ending: / - (: BREAK - SEMI? - | comment - SEMI? - | SEMI - | EOS ) / ws: / (: WS | comment ) / comment: / '#' ANY* (: BREAK | EOS ) / ### # Pegex common error recognition and reporting: ### doc-ending: /- EOS / illegal-non-modifier-char: / [^ WORD LPAREN RPAREN LANGLE SLASH TILDE PIPE GRAVE WS ] / illegal-non-quantifier-char: / [^ WORD LPAREN RPAREN LANGLE SLASH TILDE PIPE GRAVE WS STAR PLUS QMARK BANG EQUAL PLUS DASH DOT COLON SEMI ] / ERROR-meta-definition: /(= PERCENT WORD+ )/ `Illegal meta rule` # Much of this is essentially a duplicate of the above rules, except with added # error checking ERROR-rule-definition: ERROR-rule-start ERROR-rule-group ( ending | `Rule ending syntax error` ) ERROR-rule-group: ERROR-any-group | ERROR-all-group ERROR-all-group: ERROR-rule-part+ % - ERROR-any-group: (ERROR-all-group)2+ % /- PIPE -/ ERROR-rule-part: (ERROR-rule-item)1-2 % /+ ( PERCENT{1,2} ) +/ ERROR-rule-start: / ( rule-name ) BLANK* COLON -/ | `Rule header syntax error` ERROR-rule-item: rule-item | ERROR-rule-reference | ERROR-regular-expression | ERROR-bracketed-group | ERROR-error-message # Errors - rule-reference ERROR-rule-reference: /(= rule-modifier? LANGLE rule-name (! RANGLE ) )/ `Missing > in rule reference` | /(= rule-modifier? rule-name RANGLE )/ `Missing < in rule reference` | /(= rule-modifier? (: rule-name | LANGLE rule-name RANGLE ) illegal-non-quantifier-char )/ `Illegal character in rule quantifier` | /(= rule-modifier? rule-name DASH )/ `Unprotected rule name with numeric quantifier; please use #-# syntax!` | !rule-modifier /(= illegal-non-modifier-char (: rule-name | LANGLE rule-name RANGLE ) rule-quantifier? # [?*+] 2+ 2-3 (! BLANK* COLON ) # Avoid parsing 'foo:' )/ # as a rule reference. `Illegal rule modifier (must be [=!.-+]?)` # Errors - regular-expression ERROR-regular-expression: /(= SLASH ( [^ SLASH ]* ) doc-ending )/ `Runaway regular expression; no ending slash at EOF` # Errors - bracketed-group ERROR-bracketed-group: /(! group-modifier) (= illegal-non-modifier-char LPAREN )/ `Illegal group rule modifier (can only use .)` | / ( group-modifier? ) LPAREN -/ rule-group ( =doc-ending `Runaway rule group; no ending parens at EOF` | / (= - RPAREN illegal-non-quantifier-char ) / `Illegal character in group rule quantifier` ) # Errors - error-message ERROR-error-message: /(= GRAVE [^ GRAVE DOS ]* [ DOS ] [^ GRAVE ]* GRAVE )/ `Multi-line error messages not allowed!` | /(= GRAVE [^ GRAVE ]* doc-ending )/ `Runaway error message; no ending grave at EOF` # Errors - separation ERROR-separation: /(= - PERCENT{3} )/ `Leading separator form (BOK) no longer supported` | /(= - PERCENT{1,2} [^ WS ] )/ `Illegal characters in separator indicator` # vim: set lisp: grammar-api.t100644001750001750 54613621325365 14515 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More tests => 1; package MyGrammar1; use Pegex::Base; extends 'Pegex::Grammar'; has start_rules => []; use constant text => <<'...'; foo: /xyz/ bar: /abc/ | baz: /def/ ... package main; my $g1 = MyGrammar1->new; is $g1->tree->{'+toprule'}, 'foo', 'MyGrammar1 compiled a tree from its text'; look-behind.t100644001750001750 36413621325365 14511 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; use Pegex; my $grammar = <<'...'; top: foo bar foo: 'foo' bar: /(<=oo)(bar)/ ... my $result = pegex($grammar)->parse("foobar"); is $result->{top}[0]{bar}, 'bar', 'Lookbehind works'; done_testing 1; Pegex000755001750001750 013621325365 13361 5ustar00ingyingy000000000000Pegex-0.75/libTree.pm100644001750001750 46713621325365 14745 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegexpackage Pegex::Tree; use Pegex::Base; extends 'Pegex::Receiver'; sub gotrule { my $self = shift; @_ || return (); return {$self->{parser}{rule} => $_[0]} if $self->{parser}{parent}{-wrap}; return $_[0]; } sub final { my $self = shift; return(shift) if @_; return []; } 1; Base.pm100644001750001750 420213621325365 14727 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegexpackage Pegex::Base; # use Mo qw'build default builder xxx import nonlazy required'; # The following line of code was produced from the previous line by # Mo::Inline version 0.40 no warnings;my$M=__PACKAGE__.'::';*{$M.Object::new}=sub{my$c=shift;my$s=bless{@_},$c;my%n=%{$c.'::'.':E'};map{$s->{$_}=$n{$_}->()if!exists$s->{$_}}keys%n;$s};*{$M.import}=sub{import warnings;$^H|=1538;my($P,%e,%o)=caller.'::';shift;eval"no Mo::$_",&{$M.$_.::e}($P,\%e,\%o,\@_)for@_;return if$e{M};%e=(extends,sub{eval"no $_[0]()";@{$P.ISA}=$_[0]},has,sub{my$n=shift;my$m=sub{$#_?$_[0]{$n}=$_[1]:$_[0]{$n}};@_=(default,@_)if!($#_%2);$m=$o{$_}->($m,$n,@_)for sort keys%o;*{$P.$n}=$m},%e,);*{$P.$_}=$e{$_}for keys%e;@{$P.ISA}=$M.Object};*{$M.'build::e'}=sub{my($P,$e)=@_;$e->{new}=sub{$c=shift;my$s=&{$M.Object::new}($c,@_);my@B;do{@B=($c.::BUILD,@B)}while($c)=@{$c.::ISA};exists&$_&&&$_($s)for@B;$s}};*{$M.'default::e'}=sub{my($P,$e,$o)=@_;$o->{default}=sub{my($m,$n,%a)=@_;exists$a{default}or return$m;my($d,$r)=$a{default};my$g='HASH'eq($r=ref$d)?sub{+{%$d}}:'ARRAY'eq$r?sub{[@$d]}:'CODE'eq$r?$d:sub{$d};my$i=exists$a{lazy}?$a{lazy}:!${$P.':N'};$i or ${$P.':E'}{$n}=$g and return$m;sub{$#_?$m->(@_):!exists$_[0]{$n}?$_[0]{$n}=$g->(@_):$m->(@_)}}};*{$M.'builder::e'}=sub{my($P,$e,$o)=@_;$o->{builder}=sub{my($m,$n,%a)=@_;my$b=$a{builder}or return$m;my$i=exists$a{lazy}?$a{lazy}:!${$P.':N'};$i or ${$P.':E'}{$n}=\&{$P.$b}and return$m;sub{$#_?$m->(@_):!exists$_[0]{$n}?$_[0]{$n}=$_[0]->$b:$m->(@_)}}};use constant XXX_skip=>1;*{$M.'xxx::e'}=sub{my($P,$e)=@_;$e->{WWW}=sub{require XXX;XXX::WWW(@_)};$e->{XXX}=sub{require XXX;XXX::XXX(@_)};$e->{YYY}=sub{require XXX;XXX::YYY(@_)};$e->{ZZZ}=sub{require XXX;XXX::ZZZ(@_)}};my$i=\&import;*{$M.import}=sub{(@_==2 and not$_[1])?pop@_:@_==1?push@_,grep!/import/,@f:();goto&$i};*{$M.'nonlazy::e'}=sub{${shift().':N'}=1};*{$M.'required::e'}=sub{my($P,$e,$o)=@_;$o->{required}=sub{my($m,$n,%a)=@_;if($a{required}){my$C=*{$P."new"}{CODE}||*{$M.Object::new}{CODE};no warnings 'redefine';*{$P."new"}=sub{my$s=$C->(@_);my%a=@_[1..$#_];die$n." required"if!exists$a{$n};$s}}$m}};@f=qw[build default builder xxx import nonlazy required];use strict;use warnings; 1; API.pod100644001750001750 1644313621325365 14666 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegex=pod =for comment DO NOT EDIT. This Pod was generated by Swim v0.1.48. See http://github.com/ingydotnet/swim-pm#readme =encoding utf8 =head1 The Pegex API Pegex can be used in many ways: inside scripts, from the command line or as the foundation of a modular parsing framework. This document details the various ways to use Pegex. At the most abstract level, Pegex works like this: $result = $parser->new($grammar, $receiver)->parse($input); Which is to say, abstractly: a Pegex parser, under the direction of a Pegex grammar, parses an input stream, and reports matches to a Pegex receiver, which produces a result. The parser, grammar, receiver and even the input, are Pegex objects. These 4 objects are involved in every Pegex parse operation, so let's review them briefly: =over =item L The Pegex parsing engine. This engine applies the logic of the grammar to an input text. A B object contains a B object and a B object. Its primary method is called C. The default parser engine is non-backtracking, recursive descent. However there are parser subclasses for various alternative types of parsing. =item L A Pegex grammar starts as a text file/string composed in the B syntax. Before it can be used in by a Parser it must be compiled. After compilation, it is turned into a data tree consisting of rules and regexes. In modules that are based on a Pegex grammar, the grammar will be compiled into a class file. Pegex itself, uses a Pegex grammar class called L to parse various Pegex grammars. =item L A parser on it's own has no idea what to do with the text it matches. A Pegex B is a class that contains methods corresponding to the rules in a grammar. As a rule in the grammar matches, its corresponding receiver method (if one exists) is called with the data that has been matched. It is the receiver's job to take action on the data, often building it into some new structure. Pegex will use L as the default receiver; it produces a reasonably readable tree of the matched/captured data. =item L Pegex abstracts its input streams into an object interface as well. Any operation that can take an input string, can also take an input object. Pegex will turn regular strings into these objects. This is probably the API concept you will encounter the least, but it is covered here for completeness. =back All of these object classes can be subclassed to achieve various results. Normally, you will write your own Pegex grammar and a Pegex receiver to achieve a task. =head2 Starting Simple - The C Function The L module exports a function called C that you can use for smaller tasks. Here is an example: use Pegex; use YAML; $grammar = " expr: num PLUS num num: /( DIGIT+ )/ "; print Dump pegex($grammar)->parse('2+2'); This program would produce: expr: - num: 2 - num: 2 Let's review what's happening here. The L module is exporting a C function. This function takes a Pegex grammar string as input. Internally this function compiles the grammar string into a grammar object. Then it creates a parser object containing the grammar object and returns it. The parse method is called on the input string: C<'2+2'>. The string matches, and a nice data structure is returned. So how was the data structure created? By the receiver object, of course! But we didn't specify one, did we? Nope. It used the default receiver, L. We could have said: print Dump pegex($grammar, 'Pegex::Tree::Wrap')->parse('2+2'); This receiver basically generates a mapping, where rule names of matches are the keys, and the leaf values are the regex captures. The more basic receiver called L generates a tree of sequences that contain just the data (without the rule names). This code: print Dump pegex($grammar, 'Pegex::Tree')->parse('2+2'); would produce: - 2 - 2 If we wrote our own receiver class called C like this: package Calculator; use base 'Pegex::Tree'; sub got_expr { my ($receiver, $data) = @_; my ($a, $b) = @$data; return $a + $b; } Then, this: print pegex(grammar, 'Calculator')->parse('2+2'); would print: 4 =head2 More Explicit Usage Continuing with the example above, let's see how to do it a little more formally. use Pegex::Parser; use Pegex::Grammar; use Pegex::Tree; use Pegex::Input; use YAML; $grammar_text = " expr: num PLUS num num: /( DIGIT+ )/ "; $grammar = Pegex::Grammar->new(text => $grammar_text); $receiver = Pegex::Tree->new(); $parser = Pegex::Parser->new( grammar => $grammar, receiver => $receiver, ); $input = Pegex::Input->new(string => '2+2'); print Dump $parser->parse($input); This code does the same thing as the first example, but this time we've made all the objects ourselves. =head2 Precompiled Grammars If you ship a Pegex grammar as part of a CPAN distribution, you'll want it to be precompiled into a module. Pegex makes that easy. Say the grammar_text about is stored in a file called C. If you create a module called C with content like this: package MyThing::Grammar; use base 'Pegex::Grammar'; use constant file => './share/expr.pgx'; sub make_tree { } 1; Then run this command line: perl -Ilib -MMyThing::Grammar=compile It will rewrite your module to look something like this: package MyThing::Grammar; use base 'Pegex::Grammar'; use constant file => './share/expr.pgx'; sub make_tree { { '+toprule' => 'expr', 'PLUS' => { '.rgx' => qr/\G\+/ }, 'expr' => { '.all' => [ { '.ref' => 'num' }, { '.ref' => 'PLUS' }, { '.ref' => 'num' } ] }, 'num' => { '.rgx' => qr/\G([0-9]+)/ } } } 1; This command found the file where your grammar is, compiled it, and used L to output it back into your module's C method. This is what a compiled Pegex grammar looks like. As soon as this module is loaded, the grammar is ready to be used by Pegex. =head3 Automatically rebuilding during development with environment variable If you find yourself needing to compile your grammar module a lot during development, just set this environment variable like so: export PERL_PEGEX_AUTO_COMPILE=MyThing::Grammar Now, every time the grammar module is loaded it will check to see if it needs to be recompiled, and do it on the fly. If you have more than one grammar to recompile, just list all the names separated by commas. =head3 Automatically rebuilding during development using C Alternatively, if your module uses C, you can have C automatically rebuild your C class if your C<.pgx> file is updated. Simply add this at the bottom of your C: sub MY::postamble { < =item * L =item * L =item * L =item * L =item * L =back =cut function-rule.t100644001750001750 142113621325365 15123 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; use Test::More; use Pegex::Parser; { package G; use base 'Pegex::Grammar'; sub rule_a { my ($self, $parser, $input) = @_; return; } sub rule_b { my ($self, $parser, $buffer, $pos) = @_; return $parser->match_rule(3, ['aaa', $$buffer]); } use constant text => <<'...'; top: a | b ... } { package R; use base 'Pegex::Tree'; sub got_b { my ($self, $got) = @_; [reverse @$got]; } } my $parser = Pegex::Parser->new( grammar => G->new, receiver => R->new, # debug => 1, ); my $result = $parser->parse('xyz'); is scalar(@$result), 2, 'Got array of size 2'; is $result->[0], 'xyz', 'xyz is first'; is $result->[1], 'aaa', 'aaa is second'; done_testing; compiler-perl.t100644001750001750 142613621325365 15110 0ustar00ingyingy000000000000Pegex-0.75/t#!inc/bin/testml-cpan # XXX Bug in testml perl5 runtime for exec_func # % *pgx.compile.(compiled)=> # compiled.ok == True :"+: '{*pgx}' compiled" # compiled.perl !=~ *not :"+: No '{*not}'" *pgx.compile.ok == True :"+: '{*pgx}' compiled" *pgx.compile.perl !=~ *not :"+: No '{*not}'" %Bridge perl5 use lib 'lib'; # Avoid using testml/ext/perl5/Pegex* use Pegex::Compiler; use TestML::Boolean; sub compile { my ($self, $pgx) = @_; my $unit = Pegex::Compiler->new->compile($pgx); return $unit; } sub ok { my ($self, $compiled) = @_; return $compiled->tree ? true : false; } sub perl { my ($self, $compiled) = @_; return $compiled->to_perl; } === Test 1 --- pgx all: /\x{FEFF}/ --- not(/): /u$ === Test 2 --- pgx all: 'xxx' /\x{FEFF}/ 'yyy' --- ^not TestMLBridge.pm100644001750001750 376413621325365 15003 0ustar00ingyingy000000000000Pegex-0.75/tuse strict; use warnings; package TestMLBridge; use base 'TestML::Bridge'; use lib 'lib'; # Avoid using testml/ext/perl5/Pegex* use Pegex; use Pegex::Compiler; use Pegex::Bootstrap; use Pegex::Tree; use Pegex::Tree::Wrap; use TestAST; use YAML::PP; sub compile { my ($self, $grammar) = @_; my $tree = Pegex::Compiler->new->parse($grammar)->tree; delete $tree->{'+toprule'}; delete $tree->{'_'}; delete $tree->{'__'}; return $tree; } sub bootstrap_compile { my ($self, $grammar) = @_; my $tree = Pegex::Bootstrap->new->parse($grammar)->tree; delete $tree->{'+toprule'}; delete $tree->{'_'}; delete $tree->{'__'}; return $tree; } sub compress { my ($self, $grammar) = @_; $grammar = $grammar; $grammar =~ s/(?% % new(schema => ['Core', 'Perl']) ->dump_string($tree); } sub clean { my ($self, $yaml) = @_; $yaml = $yaml; $yaml =~ s/^---\s//; $yaml =~ s/'(\d+)'/$1/g; $yaml =~ s/^- ~$/- /gm; return $yaml; } sub parse_input { my ($self, $grammar, $input) = @_; my $parser = pegex($grammar); return $parser->parse($input); } sub parse_to_tree { my ($self, $grammar, $input) = @_; require Pegex::Tree; $::testing = 0; # XXX my $parser = pegex($grammar, 'Pegex::Tree'); $parser->grammar->tree; # use XXX; XXX $parser->grammar->tree; $::testing = 1; # XXX return $parser->parse($input); } sub parse_to_tree_wrap { my ($self, $grammar, $input) = @_; $::testing = 0; # XXX my $parser = pegex($grammar, 'Pegex::Tree::Wrap'); $parser->grammar->tree; $::testing = 1; # XXX return $parser->parse($input); } sub parse_to_tree_test { my ($self, $grammar, $input) = @_; my $parser = pegex($grammar, 'TestAST'); return $parser->parse($input); } 1; Regex.pm100644001750001750 301513621325365 15130 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegexpackage Pegex::Regex; use Pegex::Parser; use Pegex::Grammar; use Pegex::Receiver; my @parsers; my $PASS = ''; my $FAIL = '(*FAIL)'; sub generate_regex { push @parsers, Pegex::Parser->new( grammar => Pegex::Grammar->new( text => shift ), receiver => Pegex::Receiver->new, throw_on_error => 0, ); my $index = $#parsers; my $regex = "(??{Pegex::Regex::parse($index, \$_)})"; use re 'eval'; return qr{$regex}; } sub parse { my ($index, $input) = @_; undef %/; my $ast = $parsers[$index]->parse($input) or return $FAIL; %/ = %$ast if ref($ast) eq 'HASH'; return $PASS; }; # The following code was mutated from Damian Conway's Regexp::Grammars sub import { # Signal lexical scoping (active, unless something was exported)... $^H{'Pegex::Regex::active'} = 1; # Process any regexes in module's active lexical scope... use overload; overload::constant( qr => sub { my ($raw, $cooked, $type) = @_; # If active scope and really a regex... return generate_regex($raw) if _module_is_active() and $type =~ /qq?/; # Ignore everything else... return $cooked; } ); } # Deactivate module's regex effect when it is "anti-imported" with 'no'... sub unimport { # Signal lexical (non-)scoping... $^H{'Pegex::Regex::active'} = 0; } # Encapsulate the hoopy user-defined pragma interface... sub _module_is_active { return (caller 1)[10]->{'Pegex::Regex::active'}; } 1; Input.pm100644001750001750 305013621325365 15154 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegexpackage Pegex::Input; use Pegex::Base; has string => (); has stringref => (); has file => (); has handle => (); has _buffer => (); has _is_eof => 0; has _is_open => 0; has _is_close => 0; # NOTE: Current implementation reads entire input into _buffer on open(). sub read { my ($self) = @_; die "Attempted Pegex::Input::read before open" if not $self->{_is_open}; die "Attempted Pegex::Input::read after EOF" if $self->{_is_eof}; my $buffer = $self->{_buffer}; $self->{_buffer} = undef; $self->{_is_eof} = 1; return $buffer; } sub open { my ($self) = @_; die "Attempted to reopen Pegex::Input object" if $self->{_is_open} or $self->{_is_close}; if (my $ref = $self->{stringref}) { $self->{_buffer} = $ref; } elsif (my $handle = $self->{handle}) { $self->{_buffer} = \ do { local $/; <$handle> }; } elsif (my $path = $self->{file}) { open my $handle, "<", $path or die "Pegex::Input can't open $path for input:\n$!"; $self->{_buffer} = \ do { local $/; <$handle> }; } elsif (exists $self->{string}) { $self->{_buffer} = \$self->{string}; } else { die "Pegex::Input::open failed. No source to open"; } $self->{_is_open} = 1; return $self; } sub close { my ($self) = @_; die "Attempted to close an unopen Pegex::Input object" if $self->{_is_close}; close $self->{handle} if $self->{handle}; $self->{_is_open} = 0; $self->{_is_close} = 1; $self->{_buffer} = undef; return $self; } 1; Tree.pod100644001750001750 145213621325365 15126 0ustar00ingyingy000000000000Pegex-0.75/lib/Pegex=pod =for comment DO NOT EDIT. This Pod was generated by Swim v0.1.48. See http://github.com/ingydotnet/swim-pm#readme =encoding utf8 =head1 NAME Pegex::Tree - Pegex Parse Tree Receiver =head1 SYNOPSIS use Pegex; $tree = pegex($grammar, 'Pegex::Tree')->parse($input); =head1 DESCRIPTION L is receiver class that will shape the captured data from a Pegex parse operation into a tree made out of arrays. This module is a very (probably the most) common base class for writing your own receiver class. =head1 AUTHOR Ingy döt Net =head1 COPYRIGHT AND LICENSE Copyright 2010-2020. Ingy döt Net. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L =cut grammars000755001750001750 013621325365 14007 5ustar00ingyingy000000000000Pegex-0.75/xtPg.pgx100644001750001750 47765013621325365 15320 0ustar00ingyingy000000000000Pegex-0.75/xt/grammars%grammar SQL::Transform::Parser::Pg # The target production for the whole parse. stmtblock: stmtmulti # the thrashing around here is to discard "empty" statements... stmtmulti: stmt+ % / ~ ~ / stmt: ( AlterEventTrigStmt | AlterDatabaseStmt | AlterDatabaseSetStmt | AlterDefaultPrivilegesStmt | AlterDomainStmt | AlterEnumStmt | AlterExtensionStmt | AlterExtensionContentsStmt | AlterFdwStmt | AlterForeignServerStmt | AlterForeignTableStmt | AlterFunctionStmt | AlterGroupStmt | AlterObjectSchemaStmt | AlterOwnerStmt | AlterSeqStmt | AlterTableStmt | AlterCompositeTypeStmt | AlterRoleSetStmt | AlterRoleStmt | AlterTSConfigurationStmt | AlterTSDictionaryStmt | AlterUserMappingStmt | AlterUserSetStmt | AlterUserStmt | AnalyzeStmt | CheckPointStmt | ClosePortalStmt | ClusterStmt | CommentStmt | ConstraintsSetStmt | CopyStmt | CreateAsStmt | CreateAssertStmt | CreateCastStmt | CreateConversionStmt | CreateDomainStmt | CreateExtensionStmt | CreateFdwStmt | CreateForeignServerStmt | CreateForeignTableStmt | CreateFunctionStmt | CreateGroupStmt | CreateOpClassStmt | CreateOpFamilyStmt | AlterOpFamilyStmt | CreatePLangStmt | CreateSchemaStmt | CreateSeqStmt | CreateStmt | CreateTableSpaceStmt | CreateTrigStmt | CreateEventTrigStmt | CreateRoleStmt | CreateUserStmt | CreateUserMappingStmt | CreatedbStmt | DeallocateStmt | DeclareCursorStmt | DefineStmt | DeleteStmt | DiscardStmt | DoStmt | DropAssertStmt | DropCastStmt | DropFdwStmt | DropForeignServerStmt | DropGroupStmt | DropOpClassStmt | DropOpFamilyStmt | DropOwnedStmt | DropPLangStmt | DropRuleStmt | DropStmt | DropTableSpaceStmt | DropTrigStmt | DropRoleStmt | DropUserStmt | DropUserMappingStmt | DropdbStmt | ExecuteStmt | ExplainStmt | FetchStmt | GrantStmt | GrantRoleStmt | IndexStmt | InsertStmt | ListenStmt | LoadStmt | LockStmt | NotifyStmt | PrepareStmt | ReassignOwnedStmt | ReindexStmt | RemoveAggrStmt | RemoveFuncStmt | RemoveOperStmt | RenameStmt | RevokeStmt | RevokeRoleStmt | RuleStmt | SecLabelStmt | SelectStmt | TransactionStmt | TruncateStmt | UnlistenStmt | UpdateStmt | VacuumStmt | VariableResetStmt | VariableSetStmt | VariableShowStmt | ViewStmt )? ############################################################################# # # Create a new Postgres DBMS role # ############################################################################# CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList opt_with: WITH? # Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER # for backwards compatibility). Note: the only option required by SQL99 # is "WITH ADMIN name". OptRoleList: CreateOptRoleElem* % ~ AlterOptRoleList: AlterOptRoleElem* % ~ AlterOptRoleElem : AlterOptRoleElem_1 | AlterOptRoleElem_2 | AlterOptRoleElem_3 | AlterOptRoleElem_4 | AlterOptRoleElem_5 | AlterOptRoleElem_6 | AlterOptRoleElem_7 | AlterOptRoleElem_8 | AlterOptRoleElem_9 AlterOptRoleElem_1: PASSWORD Sconst AlterOptRoleElem_2: PASSWORD NULL AlterOptRoleElem_3: ENCRYPTED PASSWORD Sconst AlterOptRoleElem_4: UNENCRYPTED PASSWORD Sconst AlterOptRoleElem_5: INHERIT AlterOptRoleElem_6: CONNECTION LIMIT SignedIconst AlterOptRoleElem_7: VALID UNTIL Sconst AlterOptRoleElem_8: USER name_list AlterOptRoleElem_9: IDENT CreateOptRoleElem : CreateOptRoleElem_1 | CreateOptRoleElem_2 | CreateOptRoleElem_3 | CreateOptRoleElem_4 | CreateOptRoleElem_5 | CreateOptRoleElem_6 CreateOptRoleElem_1: AlterOptRoleElem CreateOptRoleElem_2: SYSID Iconst CreateOptRoleElem_3: ADMIN name_list CreateOptRoleElem_4: ROLE name_list CreateOptRoleElem_5: IN ROLE name_list CreateOptRoleElem_6: IN GROUP name_list ############################################################################# # # Create a new Postgres DBMS user (role with implied login ability) # ############################################################################# CreateUserStmt: CREATE USER RoleId opt_with OptRoleList ############################################################################# # # Alter a postgresql DBMS role # ############################################################################# AlterRoleStmt: ALTER ROLE RoleId opt_with AlterOptRoleList opt_in_database: ( IN DATABASE database_name )? AlterRoleSetStmt: ALTER ROLE RoleId opt_in_database SetResetClause ############################################################################# # # Alter a postgresql DBMS user # ############################################################################# AlterUserStmt: ALTER USER RoleId opt_with AlterOptRoleList AlterUserSetStmt: ALTER USER RoleId SetResetClause ############################################################################# # # Drop a postgresql DBMS role # # XXX Ideally this would have CASCADE/RESTRICT options, but since a role # might own objects in multiple databases, there is presently no way to # implement either cascading or restricting. Caveat DBA. ############################################################################# DropRoleStmt : DropRoleStmt_1 | DropRoleStmt_2 DropRoleStmt_1: DROP ROLE name_list DropRoleStmt_2: DROP ROLE IF EXISTS name_list ############################################################################# # # Drop a postgresql DBMS user # # XXX Ideally this would have CASCADE/RESTRICT options, but since a user # might own objects in multiple databases, there is presently no way to # implement either cascading or restricting. Caveat DBA. ############################################################################# DropUserStmt : DropUserStmt_1 | DropUserStmt_2 DropUserStmt_1: DROP USER name_list DropUserStmt_2: DROP USER IF EXISTS name_list ############################################################################# # # Create a postgresql group (role without login ability) # ############################################################################# CreateGroupStmt: CREATE GROUP RoleId opt_with OptRoleList ############################################################################# # # Alter a postgresql group # ############################################################################# AlterGroupStmt: ALTER GROUP RoleId add_drop USER name_list add_drop : add_drop_1 | add_drop_2 add_drop_1: ADD add_drop_2: DROP ############################################################################# # # Drop a postgresql group # # XXX see above notes about cascading DROP USER; groups have same problem. ############################################################################# DropGroupStmt : DropGroupStmt_1 | DropGroupStmt_2 DropGroupStmt_1: DROP GROUP name_list DropGroupStmt_2: DROP GROUP IF EXISTS name_list ############################################################################# # # Manipulate a schema # ############################################################################# CreateSchemaStmt : CreateSchemaStmt_1 | CreateSchemaStmt_2 CreateSchemaStmt_1: CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList CreateSchemaStmt_2: CREATE SCHEMA ColId OptSchemaEltList OptSchemaName: ColId? OptSchemaEltList: schema_stmt* % ~ # schema_stmt are the ones that can show up inside a CREATE SCHEMA # statement (in addition to by themselves). schema_stmt: CreateStmt | IndexStmt | CreateSeqStmt | CreateTrigStmt | GrantStmt | ViewStmt ############################################################################# # # Set PG internal variable # SET name TO 'var_value' # Include SQL92 syntax (thomas 1997-10-22): # SET TIME ZONE 'var_value' # ############################################################################# VariableSetStmt : VariableSetStmt_1 | VariableSetStmt_2 | VariableSetStmt_3 VariableSetStmt_1: SET set_rest VariableSetStmt_2: SET LOCAL set_rest VariableSetStmt_3: SET SESSION set_rest set_rest : set_rest_1 | set_rest_2 | set_rest_more set_rest_1: TRANSACTION transaction_mode_list set_rest_2: SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list set_rest_more : set_rest_more_1 | set_rest_more_2 | set_rest_more_3 | set_rest_more_4 | set_rest_more_5 | set_rest_more_6 | set_rest_more_7 | set_rest_more_8 | set_rest_more_9 | set_rest_more_10 | set_rest_more_11 | set_rest_more_12 | set_rest_more_13 | set_rest_more_14 set_rest_more_1 : # Generic SET syntaxes: var_name TO var_list set_rest_more_2 : var_name var_list set_rest_more_3 : var_name TO DEFAULT set_rest_more_4 : var_name DEFAULT set_rest_more_5 : var_name FROM CURRENT set_rest_more_6 : TIME ZONE zone_value set_rest_more_7 : CATALOG Sconst set_rest_more_8 : SCHEMA Sconst set_rest_more_9 : NAMES opt_encoding set_rest_more_10: ROLE ColId_or_Sconst set_rest_more_11: SESSION AUTHORIZATION ColId_or_Sconst set_rest_more_12: SESSION AUTHORIZATION DEFAULT set_rest_more_13: XML OPTION document_or_content set_rest_more_14: TRANSACTION SNAPSHOT Sconst var_name: ColId+ % / ~ ~ / var_list: var_value+ % / ~ ~ / var_value : var_value_1 | var_value_2 var_value_1: opt_boolean_or_string var_value_2: NumericOnly iso_level : iso_level_1 | iso_level_2 | iso_level_3 | iso_level_4 iso_level_1: READ UNCOMMITTED iso_level_2: READ COMMITTED iso_level_3: REPEATABLE READ iso_level_4: SERIALIZABLE opt_boolean_or_string : opt_boolean_or_string_1 | opt_boolean_or_string_2 | opt_boolean_or_string_3 | opt_boolean_or_string_4 opt_boolean_or_string_1: TRUE opt_boolean_or_string_2: FALSE opt_boolean_or_string_3: ON opt_boolean_or_string_4: ColId_or_Sconst # Timezone values can be: # - a string such as 'pst8pdt' # - an identifier such as "pst8pdt" # - an integer or floating point number # - a time interval per SQL99 # ColId gives reduce/reduce errors against ConstInterval and LOCAL, # so use IDENT (meaning we reject anything that is a key word). zone_value : zone_value_1 | zone_value_2 | zone_value_3 | zone_value_4 | zone_value_5 | zone_value_6 | zone_value_7 zone_value_1: Sconst zone_value_2: IDENT zone_value_3: ConstInterval Sconst opt_interval zone_value_4: ConstInterval Iconst Sconst opt_interval zone_value_5: NumericOnly zone_value_6: DEFAULT zone_value_7: LOCAL opt_encoding : ( opt_encoding_1 | opt_encoding_2 )? opt_encoding_1: Sconst opt_encoding_2: DEFAULT ColId_or_Sconst : ColId_or_Sconst_1 | ColId_or_Sconst_2 ColId_or_Sconst_1: ColId ColId_or_Sconst_2: Sconst VariableResetStmt : VariableResetStmt_1 | VariableResetStmt_2 | VariableResetStmt_3 | VariableResetStmt_4 | VariableResetStmt_5 VariableResetStmt_1: RESET var_name VariableResetStmt_2: RESET TIME ZONE VariableResetStmt_3: RESET TRANSACTION ISOLATION LEVEL VariableResetStmt_4: RESET SESSION AUTHORIZATION VariableResetStmt_5: RESET ALL # SetResetClause allows SET or RESET without LOCAL SetResetClause : SetResetClause_1 | SetResetClause_2 SetResetClause_1: SET set_rest SetResetClause_2: VariableResetStmt # SetResetClause allows SET or RESET without LOCAL FunctionSetResetClause : FunctionSetResetClause_1 | FunctionSetResetClause_2 FunctionSetResetClause_1: SET set_rest_more FunctionSetResetClause_2: VariableResetStmt VariableShowStmt : VariableShowStmt_1 | VariableShowStmt_2 | VariableShowStmt_3 | VariableShowStmt_4 | VariableShowStmt_5 VariableShowStmt_1: SHOW var_name VariableShowStmt_2: SHOW TIME ZONE VariableShowStmt_3: SHOW TRANSACTION ISOLATION LEVEL VariableShowStmt_4: SHOW SESSION AUTHORIZATION VariableShowStmt_5: SHOW ALL ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode constraints_set_list : constraints_set_list_1 | constraints_set_list_2 constraints_set_list_1: ALL constraints_set_list_2: qualified_name_list constraints_set_mode : constraints_set_mode_1 | constraints_set_mode_2 constraints_set_mode_1: DEFERRED constraints_set_mode_2: IMMEDIATE # Checkpoint statement CheckPointStmt: CHECKPOINT ############################################################################# # # DISCARD { ALL | TEMP | PLANS } # ############################################################################# DiscardStmt : DiscardStmt_1 | DiscardStmt_2 | DiscardStmt_3 | DiscardStmt_4 DiscardStmt_1: DISCARD ALL DiscardStmt_2: DISCARD TEMP DiscardStmt_3: DISCARD TEMPORARY DiscardStmt_4: DISCARD PLANS ############################################################################# # # ALTER [ TABLE | INDEX | SEQUENCE | VIEW ] variations # # Note: we accept all subcommands for each of the four variants, and sort # out what's really legal at execution time. ############################################################################# AlterTableStmt : AlterTableStmt_1 | AlterTableStmt_2 | AlterTableStmt_3 | AlterTableStmt_4 | AlterTableStmt_5 | AlterTableStmt_6 | AlterTableStmt_7 | AlterTableStmt_8 AlterTableStmt_1: ALTER TABLE relation_expr alter_table_cmds AlterTableStmt_2: ALTER TABLE IF EXISTS relation_expr alter_table_cmds AlterTableStmt_3: ALTER INDEX qualified_name alter_table_cmds AlterTableStmt_4: ALTER INDEX IF EXISTS qualified_name alter_table_cmds AlterTableStmt_5: ALTER SEQUENCE qualified_name alter_table_cmds AlterTableStmt_6: ALTER SEQUENCE IF EXISTS qualified_name alter_table_cmds AlterTableStmt_7: ALTER VIEW qualified_name alter_table_cmds AlterTableStmt_8: ALTER VIEW IF EXISTS qualified_name alter_table_cmds alter_table_cmds: alter_table_cmd+ % / ~ ~ / alter_table_cmd : alter_table_cmd_1 | alter_table_cmd_2 | alter_table_cmd_3 | alter_table_cmd_4 | alter_table_cmd_5 | alter_table_cmd_6 | alter_table_cmd_7 | alter_table_cmd_8 | alter_table_cmd_9 | alter_table_cmd_10 | alter_table_cmd_11 | alter_table_cmd_12 | alter_table_cmd_13 | alter_table_cmd_14 | alter_table_cmd_15 | alter_table_cmd_16 | alter_table_cmd_17 | alter_table_cmd_18 | alter_table_cmd_19 | alter_table_cmd_20 | alter_table_cmd_21 | alter_table_cmd_22 | alter_table_cmd_23 | alter_table_cmd_24 | alter_table_cmd_25 | alter_table_cmd_26 | alter_table_cmd_27 | alter_table_cmd_28 | alter_table_cmd_29 | alter_table_cmd_30 | alter_table_cmd_31 | alter_table_cmd_32 | alter_table_cmd_33 | alter_table_cmd_34 | alter_table_cmd_35 | alter_table_cmd_36 | alter_table_cmd_37 | alter_table_cmd_38 | alter_table_cmd_39 | alter_table_cmd_40 | alter_table_cmd_41 | alter_table_cmd_42 alter_table_cmd_1 : # ALTER TABLE ADD ADD columnDef alter_table_cmd_2 : ADD COLUMN columnDef alter_table_cmd_3 : ALTER opt_column ColId alter_column_default alter_table_cmd_4 : ALTER opt_column ColId DROP NOT NULL alter_table_cmd_5 : ALTER opt_column ColId SET NOT NULL alter_table_cmd_6 : ALTER opt_column ColId SET STATISTICS SignedIconst alter_table_cmd_7 : ALTER opt_column ColId SET reloptions alter_table_cmd_8 : ALTER opt_column ColId RESET reloptions alter_table_cmd_9 : ALTER opt_column ColId SET STORAGE ColId alter_table_cmd_10: DROP opt_column IF EXISTS ColId opt_drop_behavior alter_table_cmd_11: DROP opt_column ColId opt_drop_behavior alter_table_cmd_12: ALTER opt_column ColId opt_set_data TYPE Typename opt_collate_clause alter_using alter_table_cmd_13: ALTER opt_column ColId alter_generic_options alter_table_cmd_14: ADD TableConstraint alter_table_cmd_15: VALIDATE CONSTRAINT name alter_table_cmd_16: DROP CONSTRAINT IF EXISTS name opt_drop_behavior alter_table_cmd_17: DROP CONSTRAINT name opt_drop_behavior alter_table_cmd_18: SET WITH OIDS alter_table_cmd_19: SET WITHOUT OIDS alter_table_cmd_20: CLUSTER ON name alter_table_cmd_21: SET WITHOUT CLUSTER alter_table_cmd_22: ENABLE TRIGGER name alter_table_cmd_23: ENABLE ALWAYS TRIGGER name alter_table_cmd_24: ENABLE REPLICA TRIGGER name alter_table_cmd_25: ENABLE TRIGGER ALL alter_table_cmd_26: ENABLE TRIGGER USER alter_table_cmd_27: DISABLE TRIGGER name alter_table_cmd_28: DISABLE TRIGGER ALL alter_table_cmd_29: DISABLE TRIGGER USER alter_table_cmd_30: ENABLE RULE name alter_table_cmd_31: ENABLE ALWAYS RULE name alter_table_cmd_32: ENABLE REPLICA RULE name alter_table_cmd_33: DISABLE RULE name alter_table_cmd_34: INHERIT qualified_name alter_table_cmd_35: NO INHERIT qualified_name alter_table_cmd_36: OF any_name alter_table_cmd_37: NOT OF alter_table_cmd_38: OWNER TO RoleId alter_table_cmd_39: SET TABLESPACE name alter_table_cmd_40: SET reloptions alter_table_cmd_41: RESET reloptions alter_table_cmd_42: alter_generic_options alter_column_default : alter_column_default_1 | alter_column_default_2 alter_column_default_1: SET DEFAULT a_expr alter_column_default_2: DROP DEFAULT opt_drop_behavior : ( opt_drop_behavior_1 | opt_drop_behavior_2 )? opt_drop_behavior_1: CASCADE opt_drop_behavior_2: RESTRICT opt_collate_clause: ( COLLATE any_name )? alter_using: ( USING a_expr )? reloptions: reloption_list opt_reloptions: ( WITH reloptions )? reloption_list: reloption_elem+ % / ~ ~ / # This should match def_elem and also allow qualified names reloption_elem : reloption_elem_1 | reloption_elem_2 | reloption_elem_3 | reloption_elem_4 reloption_elem_1: ColLabel def_arg reloption_elem_2: ColLabel reloption_elem_3: ColLabel ColLabel def_arg reloption_elem_4: ColLabel ColLabel ############################################################################# # # ALTER TYPE # # really variants of the ALTER TABLE subcommands with different spellings ############################################################################# AlterCompositeTypeStmt: ALTER TYPE any_name alter_type_cmds alter_type_cmds: alter_type_cmd+ % / ~ ~ / alter_type_cmd : alter_type_cmd_1 | alter_type_cmd_2 | alter_type_cmd_3 | alter_type_cmd_4 alter_type_cmd_1: # ALTER TYPE ADD ATTRIBUTE [RESTRICT|CASCADE] ADD ATTRIBUTE TableFuncElement opt_drop_behavior alter_type_cmd_2: DROP ATTRIBUTE IF EXISTS ColId opt_drop_behavior alter_type_cmd_3: DROP ATTRIBUTE ColId opt_drop_behavior alter_type_cmd_4: ALTER ATTRIBUTE ColId opt_set_data TYPE Typename opt_collate_clause opt_drop_behavior ############################################################################# # # QUERY : # close # ############################################################################# ClosePortalStmt : ClosePortalStmt_1 | ClosePortalStmt_2 ClosePortalStmt_1: CLOSE cursor_name ClosePortalStmt_2: CLOSE ALL ############################################################################# # # QUERY : # COPY relname [(columnList)] FROM/TO file [WITH] [(options)] # COPY ( SELECT ... ) TO file [WITH] [(options)] # # In the preferred syntax the options are comma-separated # and use generic identifiers instead of keywords. The pre-9.0 # syntax had a hard-wired, space-separated set of options. # # Really old syntax, from versions 7.2 and prior: # COPY [ BINARY ] table [ WITH OIDS ] FROM/TO file # [ [ USING ] DELIMITERS 'delimiter' ] ] # [ WITH NULL AS 'null string' ] # This option placement is not supported with COPY (SELECT...). # ############################################################################# CopyStmt : CopyStmt_1 | CopyStmt_2 CopyStmt_1: COPY opt_binary qualified_name opt_column_list opt_oids copy_from copy_file_name copy_delimiter opt_with copy_options CopyStmt_2: COPY select_with_parens TO copy_file_name opt_with copy_options copy_from : copy_from_1 | copy_from_2 copy_from_1: FROM copy_from_2: TO # copy_file_name NULL indicates stdio is used. Whether stdin or stdout is # used depends on the direction. (It really doesn't make sense to copy from # stdout. We silently correct the "typo".) - AY 9/94 copy_file_name : copy_file_name_1 | copy_file_name_2 | copy_file_name_3 copy_file_name_1: Sconst copy_file_name_2: STDIN copy_file_name_3: STDOUT copy_options : copy_options_1 | copy_options_2 copy_options_1: copy_opt_list copy_options_2: copy_generic_opt_list # old COPY option syntax copy_opt_list: copy_opt_item* % ~ copy_opt_item : copy_opt_item_1 | copy_opt_item_2 | copy_opt_item_3 | copy_opt_item_4 | copy_opt_item_5 | copy_opt_item_6 | copy_opt_item_7 | copy_opt_item_8 | copy_opt_item_9 | copy_opt_item_10 | copy_opt_item_11 | copy_opt_item_12 copy_opt_item_1 : BINARY copy_opt_item_2 : OIDS copy_opt_item_3 : DELIMITER opt_as Sconst copy_opt_item_4 : NULL opt_as Sconst copy_opt_item_5 : CSV copy_opt_item_6 : HEADER copy_opt_item_7 : QUOTE opt_as Sconst copy_opt_item_8 : ESCAPE opt_as Sconst copy_opt_item_9 : FORCE QUOTE columnList copy_opt_item_10: FORCE QUOTE copy_opt_item_11: FORCE NOT NULL columnList copy_opt_item_12: ENCODING Sconst # The following exist for backward compatibility with very old versions opt_binary: BINARY? opt_oids: ( WITH OIDS )? copy_delimiter: ( opt_using DELIMITERS Sconst )? opt_using: USING? # new COPY option syntax copy_generic_opt_list: copy_generic_opt_elem+ % / ~ ~ / copy_generic_opt_elem: ColLabel copy_generic_opt_arg copy_generic_opt_arg : ( copy_generic_opt_arg_1 | copy_generic_opt_arg_2 | copy_generic_opt_arg_3 | copy_generic_opt_arg_4 )? copy_generic_opt_arg_1: opt_boolean_or_string copy_generic_opt_arg_2: NumericOnly copy_generic_opt_arg_3: copy_generic_opt_arg_4: copy_generic_opt_arg_list copy_generic_opt_arg_list: copy_generic_opt_arg_list_item+ % / ~ ~ / # beware of emitting non-string list elements here; see commands/define.c copy_generic_opt_arg_list_item: opt_boolean_or_string ############################################################################# # # QUERY : # CREATE TABLE relname # ############################################################################# CreateStmt : CreateStmt_1 | CreateStmt_2 | CreateStmt_3 | CreateStmt_4 CreateStmt_1: CREATE OptTemp TABLE qualified_name OptTableElementList OptInherit OptWith OnCommitOption OptTableSpace CreateStmt_2: CREATE OptTemp TABLE IF NOT EXISTS qualified_name OptTableElementList OptInherit OptWith OnCommitOption OptTableSpace CreateStmt_3: CREATE OptTemp TABLE qualified_name OF any_name OptTypedTableElementList OptWith OnCommitOption OptTableSpace CreateStmt_4: CREATE OptTemp TABLE IF NOT EXISTS qualified_name OF any_name OptTypedTableElementList OptWith OnCommitOption OptTableSpace # Redundancy here is needed to avoid shift/reduce conflicts, # since TEMP is not a reserved word. See also OptTempTableName. # # NOTE: we accept both GLOBAL and LOCAL options; since we have no modules # the LOCAL keyword is really meaningless. OptTemp : ( OptTemp_1 | OptTemp_2 | OptTemp_3 | OptTemp_4 | OptTemp_5 | OptTemp_6 | OptTemp_7 )? OptTemp_1: TEMPORARY OptTemp_2: TEMP OptTemp_3: LOCAL TEMPORARY OptTemp_4: LOCAL TEMP OptTemp_5: GLOBAL TEMPORARY OptTemp_6: GLOBAL TEMP OptTemp_7: UNLOGGED OptTableElementList: TableElementList? OptTypedTableElementList: ( TypedTableElementList )? TableElementList: TableElement+ % / ~ ~ / TypedTableElementList: TypedTableElement+ % / ~ ~ / TableElement : TableElement_1 | TableElement_2 | TableElement_3 TableElement_1: columnDef TableElement_2: TableLikeClause TableElement_3: TableConstraint TypedTableElement : TypedTableElement_1 | TypedTableElement_2 TypedTableElement_1: columnOptions TypedTableElement_2: TableConstraint columnDef: ColId Typename create_generic_options ColQualList columnOptions: ColId WITH OPTIONS ColQualList ColQualList: ColConstraint* % ~ ColConstraint : ColConstraint_1 | ColConstraint_2 | ColConstraint_3 | ColConstraint_4 ColConstraint_1: CONSTRAINT name ColConstraintElem ColConstraint_2: ColConstraintElem ColConstraint_3: ConstraintAttr ColConstraint_4: COLLATE any_name # DEFAULT NULL is already the default for Postgres. # But define it here and carry it forward into the system # to make it explicit. # - thomas 1998-09-13 # # WITH NULL and NULL are not SQL92-standard syntax elements, # so leave them out. Use DEFAULT NULL to explicitly indicate # that a column may have that value. WITH NULL leads to # shift/reduce conflicts with WITH TIME ZONE anyway. # - thomas 1999-01-08 # # DEFAULT expression must be b_expr not a_expr to prevent shift/reduce # conflict on NOT (since NOT might start a subsequent NOT NULL constraint, # or be part of a_expr NOT LIKE or similar constructs). ColConstraintElem : ColConstraintElem_1 | ColConstraintElem_2 | ColConstraintElem_3 | ColConstraintElem_4 | ColConstraintElem_5 | ColConstraintElem_6 | ColConstraintElem_7 ColConstraintElem_1: NOT NULL ColConstraintElem_2: NULL ColConstraintElem_3: UNIQUE opt_definition OptConsTableSpace ColConstraintElem_4: PRIMARY KEY opt_definition OptConsTableSpace ColConstraintElem_5: CHECK a_expr opt_no_inherit ColConstraintElem_6: DEFAULT b_expr ColConstraintElem_7: REFERENCES qualified_name opt_column_list key_match key_actions # ConstraintAttr represents constraint attributes, which we parse as if # they were independent constraint clauses, in order to avoid shift/reduce # conflicts (since NOT might start either an independent NOT NULL clause # or an attribute). parse_utilcmd.c is responsible for attaching the # attribute information to the preceding "real" constraint node, and for # complaining if attribute clauses appear in the wrong place or wrong # combinations. # # See also ConstraintAttributeSpec, which can be used in places where # there is no parsing conflict. (Note: currently, NOT VALID and NO INHERIT # are allowed clauses in ConstraintAttributeSpec, but not here. Someday we # might need to allow them here too, but for the moment it doesn't seem # useful in the statements that use ConstraintAttr.) ConstraintAttr : ConstraintAttr_1 | ConstraintAttr_2 | ConstraintAttr_3 | ConstraintAttr_4 ConstraintAttr_1: DEFERRABLE ConstraintAttr_2: NOT DEFERRABLE ConstraintAttr_3: INITIALLY DEFERRED ConstraintAttr_4: INITIALLY IMMEDIATE TableLikeClause: LIKE qualified_name TableLikeOptionList TableLikeOptionList : TableLikeOptionList_1 | TableLikeOptionList_2 TableLikeOptionList_1: TableLikeOption* % / ~ INCLUDING ~ / TableLikeOptionList_2: 2+ % / ~ EXCLUDING ~ / TableLikeOption : TableLikeOption_1 | TableLikeOption_2 | TableLikeOption_3 | TableLikeOption_4 | TableLikeOption_5 | TableLikeOption_6 TableLikeOption_1: DEFAULTS TableLikeOption_2: CONSTRAINTS TableLikeOption_3: INDEXES TableLikeOption_4: STORAGE TableLikeOption_5: COMMENTS TableLikeOption_6: ALL # ConstraintElem specifies constraint syntax which is not embedded into # a column definition. ColConstraintElem specifies the embedded form. # - thomas 1997-12-03 TableConstraint : TableConstraint_1 | TableConstraint_2 TableConstraint_1: CONSTRAINT name ConstraintElem TableConstraint_2: ConstraintElem ConstraintElem : ConstraintElem_1 | ConstraintElem_2 | ConstraintElem_3 | ConstraintElem_4 | ConstraintElem_5 | ConstraintElem_6 | ConstraintElem_7 ConstraintElem_1: CHECK a_expr ConstraintAttributeSpec ConstraintElem_2: UNIQUE columnList opt_definition OptConsTableSpace ConstraintAttributeSpec ConstraintElem_3: UNIQUE ExistingIndex ConstraintAttributeSpec ConstraintElem_4: PRIMARY KEY columnList opt_definition OptConsTableSpace ConstraintAttributeSpec ConstraintElem_5: PRIMARY KEY ExistingIndex ConstraintAttributeSpec ConstraintElem_6: EXCLUDE access_method_clause ExclusionConstraintList opt_definition OptConsTableSpace ExclusionWhereClause ConstraintAttributeSpec ConstraintElem_7: FOREIGN KEY columnList REFERENCES qualified_name opt_column_list key_match key_actions ConstraintAttributeSpec opt_no_inherit: ( NO INHERIT )? opt_column_list: ( columnList )? columnList: columnElem+ % / ~ ~ / columnElem: ColId key_match : ( key_match_1 | key_match_2 | key_match_3 )? key_match_1: MATCH FULL key_match_2: MATCH PARTIAL key_match_3: MATCH SIMPLE ExclusionConstraintList: ExclusionConstraintElem+ % / ~ ~ / ExclusionConstraintElem : ExclusionConstraintElem_1 | ExclusionConstraintElem_2 ExclusionConstraintElem_1: index_elem WITH any_operator ExclusionConstraintElem_2: index_elem WITH OPERATOR any_operator ExclusionWhereClause: ( WHERE a_expr )? # We combine the update and delete actions into one value temporarily # for simplicity of parsing, and then break them down again in the # calling production. update is in the left 8 bits, delete in the right. # Note that NOACTION is the default. key_actions : ( key_actions_1 | key_actions_2 | key_actions_3 | key_actions_4 )? key_actions_1: key_update key_actions_2: key_delete key_actions_3: key_update key_delete key_actions_4: key_delete key_update key_update: ON UPDATE key_action key_delete: ON DELETE key_action key_action : key_action_1 | key_action_2 | key_action_3 | key_action_4 | key_action_5 key_action_1: NO ACTION key_action_2: RESTRICT key_action_3: CASCADE key_action_4: SET NULL key_action_5: SET DEFAULT OptInherit: ( INHERITS qualified_name_list )? # WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms OptWith : ( OptWith_1 | OptWith_2 | OptWith_3 )? OptWith_1: WITH reloptions OptWith_2: WITH OIDS OptWith_3: WITHOUT OIDS OnCommitOption : ( OnCommitOption_1 | OnCommitOption_2 | OnCommitOption_3 )? OnCommitOption_1: ON COMMIT DROP OnCommitOption_2: ON COMMIT DELETE ROWS OnCommitOption_3: ON COMMIT PRESERVE ROWS OptTableSpace: ( TABLESPACE name )? OptConsTableSpace: ( USING INDEX TABLESPACE name )? ExistingIndex: USING INDEX index_name ############################################################################# # # QUERY : # CREATE TABLE relname AS SelectStmt [ WITH [NO] DATA ] # # # Note: SELECT ... INTO is a now-deprecated alternative for this. # ############################################################################# CreateAsStmt: CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data create_as_target: qualified_name opt_column_list OptWith OnCommitOption OptTableSpace opt_with_data : ( opt_with_data_1 | opt_with_data_2 )? opt_with_data_1: WITH DATA opt_with_data_2: WITH NO DATA ############################################################################# # # QUERY : # CREATE SEQUENCE seqname # ALTER SEQUENCE seqname # ############################################################################# CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqOptList AlterSeqStmt : AlterSeqStmt_1 | AlterSeqStmt_2 AlterSeqStmt_1: ALTER SEQUENCE qualified_name SeqOptList AlterSeqStmt_2: ALTER SEQUENCE IF EXISTS qualified_name SeqOptList OptSeqOptList: SeqOptList? SeqOptList: SeqOptElem+ % ~ SeqOptElem : SeqOptElem_1 | SeqOptElem_2 | SeqOptElem_3 | SeqOptElem_4 | SeqOptElem_5 | SeqOptElem_6 | SeqOptElem_7 | SeqOptElem_8 | SeqOptElem_9 | SeqOptElem_10 | SeqOptElem_11 | SeqOptElem_12 SeqOptElem_1 : CACHE NumericOnly SeqOptElem_2 : CYCLE SeqOptElem_3 : NO CYCLE SeqOptElem_4 : INCREMENT opt_by NumericOnly SeqOptElem_5 : MAXVALUE NumericOnly SeqOptElem_6 : MINVALUE NumericOnly SeqOptElem_7 : NO MAXVALUE SeqOptElem_8 : NO MINVALUE SeqOptElem_9 : OWNED BY any_name SeqOptElem_10: START opt_with NumericOnly SeqOptElem_11: RESTART SeqOptElem_12: RESTART opt_with NumericOnly opt_by: BY? NumericOnly : NumericOnly_1 | NumericOnly_2 | NumericOnly_3 NumericOnly_1: FCONST NumericOnly_2: FCONST NumericOnly_3: SignedIconst NumericOnly_list: NumericOnly+ % / ~ ~ / ############################################################################# # # QUERIES : # CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ... # DROP [PROCEDURAL] LANGUAGE ... # ############################################################################# CreatePLangStmt : CreatePLangStmt_1 | CreatePLangStmt_2 CreatePLangStmt_1: CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst CreatePLangStmt_2: CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst HANDLER handler_name opt_inline_handler opt_validator opt_trusted: TRUSTED? # This ought to be just func_name, but that causes reduce/reduce conflicts # (CREATE LANGUAGE is the only place where func_name isn't followed by '('). # Work around by using simple names, instead. handler_name : handler_name_1 | handler_name_2 handler_name_1: name handler_name_2: name attrs opt_inline_handler: ( INLINE handler_name )? validator_clause : validator_clause_1 | validator_clause_2 validator_clause_1: VALIDATOR handler_name validator_clause_2: NO VALIDATOR opt_validator: validator_clause? DropPLangStmt : DropPLangStmt_1 | DropPLangStmt_2 DropPLangStmt_1: DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior DropPLangStmt_2: DROP opt_procedural LANGUAGE IF EXISTS ColId_or_Sconst opt_drop_behavior opt_procedural: PROCEDURAL? ############################################################################# # # QUERY: # CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'' # ############################################################################# CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst OptTableSpaceOwner: ( OWNER name )? ############################################################################# # # QUERY : # DROP TABLESPACE # # No need for drop behaviour as we cannot implement dependencies for # objects in other databases; we can only support RESTRICT. # ############################################################################ DropTableSpaceStmt : DropTableSpaceStmt_1 | DropTableSpaceStmt_2 DropTableSpaceStmt_1: DROP TABLESPACE name DropTableSpaceStmt_2: DROP TABLESPACE IF EXISTS name ############################################################################# # # QUERY: # CREATE EXTENSION extension # [ WITH ] [ SCHEMA schema ] [ VERSION version ] [ FROM oldversion ] # ############################################################################# CreateExtensionStmt : CreateExtensionStmt_1 | CreateExtensionStmt_2 CreateExtensionStmt_1: CREATE EXTENSION name opt_with create_extension_opt_list CreateExtensionStmt_2: CREATE EXTENSION IF NOT EXISTS name opt_with create_extension_opt_list create_extension_opt_list: create_extension_opt_item* % ~ create_extension_opt_item : create_extension_opt_item_1 | create_extension_opt_item_2 | create_extension_opt_item_3 create_extension_opt_item_1: SCHEMA name create_extension_opt_item_2: VERSION ColId_or_Sconst create_extension_opt_item_3: FROM ColId_or_Sconst ############################################################################# # # ALTER EXTENSION name UPDATE [ TO version ] # ############################################################################# AlterExtensionStmt: ALTER EXTENSION name UPDATE alter_extension_opt_list alter_extension_opt_list: alter_extension_opt_item* % ~ alter_extension_opt_item: TO ColId_or_Sconst ############################################################################# # # ALTER EXTENSION name ADD/DROP object-identifier # ############################################################################# AlterExtensionContentsStmt : AlterExtensionContentsStmt_1 | AlterExtensionContentsStmt_2 | AlterExtensionContentsStmt_3 | AlterExtensionContentsStmt_4 | AlterExtensionContentsStmt_5 | AlterExtensionContentsStmt_6 | AlterExtensionContentsStmt_7 | AlterExtensionContentsStmt_8 | AlterExtensionContentsStmt_9 | AlterExtensionContentsStmt_10 | AlterExtensionContentsStmt_11 | AlterExtensionContentsStmt_12 | AlterExtensionContentsStmt_13 | AlterExtensionContentsStmt_14 | AlterExtensionContentsStmt_15 | AlterExtensionContentsStmt_16 | AlterExtensionContentsStmt_17 | AlterExtensionContentsStmt_18 | AlterExtensionContentsStmt_19 | AlterExtensionContentsStmt_20 | AlterExtensionContentsStmt_21 | AlterExtensionContentsStmt_22 | AlterExtensionContentsStmt_23 AlterExtensionContentsStmt_1 : ALTER EXTENSION name add_drop AGGREGATE func_name aggr_args AlterExtensionContentsStmt_2 : ALTER EXTENSION name add_drop CAST Typename AS Typename AlterExtensionContentsStmt_3 : ALTER EXTENSION name add_drop COLLATION any_name AlterExtensionContentsStmt_4 : ALTER EXTENSION name add_drop CONVERSION any_name AlterExtensionContentsStmt_5 : ALTER EXTENSION name add_drop DOMAIN any_name AlterExtensionContentsStmt_6 : ALTER EXTENSION name add_drop FUNCTION function_with_argtypes AlterExtensionContentsStmt_7 : ALTER EXTENSION name add_drop opt_procedural LANGUAGE name AlterExtensionContentsStmt_8 : ALTER EXTENSION name add_drop OPERATOR any_operator oper_argtypes AlterExtensionContentsStmt_9 : ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING access_method AlterExtensionContentsStmt_10: ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING access_method AlterExtensionContentsStmt_11: ALTER EXTENSION name add_drop SCHEMA name AlterExtensionContentsStmt_12: ALTER EXTENSION name add_drop TABLE any_name AlterExtensionContentsStmt_13: ALTER EXTENSION name add_drop EVENT TRIGGER name AlterExtensionContentsStmt_14: ALTER EXTENSION name add_drop TEXT SEARCH PARSER any_name AlterExtensionContentsStmt_15: ALTER EXTENSION name add_drop TEXT SEARCH DICTIONARY any_name AlterExtensionContentsStmt_16: ALTER EXTENSION name add_drop TEXT SEARCH TEMPLATE any_name AlterExtensionContentsStmt_17: ALTER EXTENSION name add_drop TEXT SEARCH CONFIGURATION any_name AlterExtensionContentsStmt_18: ALTER EXTENSION name add_drop SEQUENCE any_name AlterExtensionContentsStmt_19: ALTER EXTENSION name add_drop VIEW any_name AlterExtensionContentsStmt_20: ALTER EXTENSION name add_drop FOREIGN TABLE any_name AlterExtensionContentsStmt_21: ALTER EXTENSION name add_drop FOREIGN DATA WRAPPER name AlterExtensionContentsStmt_22: ALTER EXTENSION name add_drop SERVER name AlterExtensionContentsStmt_23: ALTER EXTENSION name add_drop TYPE any_name ############################################################################# # # QUERY: # CREATE FOREIGN DATA WRAPPER name options # ############################################################################# CreateFdwStmt: CREATE FOREIGN DATA WRAPPER name opt_fdw_options create_generic_options fdw_option : fdw_option_1 | fdw_option_2 | fdw_option_3 | fdw_option_4 fdw_option_1: HANDLER handler_name fdw_option_2: NO HANDLER fdw_option_3: VALIDATOR handler_name fdw_option_4: NO VALIDATOR fdw_options: fdw_option+ % ~ opt_fdw_options: fdw_options? ############################################################################# # # QUERY : # DROP FOREIGN DATA WRAPPER name # ############################################################################ DropFdwStmt : DropFdwStmt_1 | DropFdwStmt_2 DropFdwStmt_1: DROP FOREIGN DATA WRAPPER name opt_drop_behavior DropFdwStmt_2: DROP FOREIGN DATA WRAPPER IF EXISTS name opt_drop_behavior ############################################################################# # # QUERY : # ALTER FOREIGN DATA WRAPPER name options # ############################################################################ AlterFdwStmt : AlterFdwStmt_1 | AlterFdwStmt_2 AlterFdwStmt_1: ALTER FOREIGN DATA WRAPPER name opt_fdw_options alter_generic_options AlterFdwStmt_2: ALTER FOREIGN DATA WRAPPER name fdw_options # Options definition for CREATE FDW, SERVER and USER MAPPING create_generic_options: ( OPTIONS generic_option_list )? generic_option_list: generic_option_elem+ % / ~ ~ / # Options definition for ALTER FDW, SERVER and USER MAPPING alter_generic_options: OPTIONS alter_generic_option_list alter_generic_option_list: alter_generic_option_elem+ % / ~ ~ / alter_generic_option_elem : alter_generic_option_elem_1 | alter_generic_option_elem_2 | alter_generic_option_elem_3 | alter_generic_option_elem_4 alter_generic_option_elem_1: generic_option_elem alter_generic_option_elem_2: SET generic_option_elem alter_generic_option_elem_3: ADD generic_option_elem alter_generic_option_elem_4: DROP generic_option_name generic_option_elem: generic_option_name generic_option_arg generic_option_name: ColLabel # We could use def_arg here, but the spec only requires string literals generic_option_arg: Sconst ############################################################################# # # QUERY: # CREATE SERVER name [TYPE] [VERSION] [OPTIONS] # ############################################################################# CreateForeignServerStmt: CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA WRAPPER name create_generic_options opt_type: ( TYPE Sconst )? foreign_server_version : foreign_server_version_1 | foreign_server_version_2 foreign_server_version_1: VERSION Sconst foreign_server_version_2: VERSION NULL opt_foreign_server_version: foreign_server_version? ############################################################################# # # QUERY : # DROP SERVER name # ############################################################################ DropForeignServerStmt : DropForeignServerStmt_1 | DropForeignServerStmt_2 DropForeignServerStmt_1: DROP SERVER name opt_drop_behavior DropForeignServerStmt_2: DROP SERVER IF EXISTS name opt_drop_behavior ############################################################################# # # QUERY : # ALTER SERVER name [VERSION] [OPTIONS] # ############################################################################ AlterForeignServerStmt : AlterForeignServerStmt_1 | AlterForeignServerStmt_2 | AlterForeignServerStmt_3 AlterForeignServerStmt_1: ALTER SERVER name foreign_server_version alter_generic_options AlterForeignServerStmt_2: ALTER SERVER name foreign_server_version AlterForeignServerStmt_3: ALTER SERVER name alter_generic_options ############################################################################# # # QUERY: # CREATE FOREIGN TABLE relname (...) SERVER name (...) # ############################################################################# CreateForeignTableStmt : CreateForeignTableStmt_1 | CreateForeignTableStmt_2 CreateForeignTableStmt_1: CREATE FOREIGN TABLE qualified_name OptForeignTableElementList SERVER name create_generic_options CreateForeignTableStmt_2: CREATE FOREIGN TABLE IF NOT EXISTS qualified_name OptForeignTableElementList SERVER name create_generic_options OptForeignTableElementList : OptForeignTableElementList_1 | OptForeignTableElementList_2 OptForeignTableElementList_1: ForeignTableElementList OptForeignTableElementList_2: ForeignTableElementList: ForeignTableElement+ % / ~ ~ / ForeignTableElement: columnDef ############################################################################# # # QUERY: # ALTER FOREIGN TABLE relname [...] # ############################################################################# AlterForeignTableStmt : AlterForeignTableStmt_1 | AlterForeignTableStmt_2 AlterForeignTableStmt_1: ALTER FOREIGN TABLE relation_expr alter_table_cmds AlterForeignTableStmt_2: ALTER FOREIGN TABLE IF EXISTS relation_expr alter_table_cmds ############################################################################# # # QUERY: # CREATE USER MAPPING FOR auth_ident SERVER name [OPTIONS] # ############################################################################# CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options # User mapping authorization identifier auth_ident : auth_ident_1 | auth_ident_2 | auth_ident_3 auth_ident_1: CURRENT_USER auth_ident_2: USER auth_ident_3: RoleId ############################################################################# # # QUERY : # DROP USER MAPPING FOR auth_ident SERVER name # ############################################################################ DropUserMappingStmt : DropUserMappingStmt_1 | DropUserMappingStmt_2 DropUserMappingStmt_1: DROP USER MAPPING FOR auth_ident SERVER name DropUserMappingStmt_2: DROP USER MAPPING IF EXISTS FOR auth_ident SERVER name ############################################################################# # # QUERY : # ALTER USER MAPPING FOR auth_ident SERVER name OPTIONS # ############################################################################ AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options ############################################################################# # # QUERIES : # CREATE TRIGGER ... # DROP TRIGGER ... # ############################################################################# CreateTrigStmt : CreateTrigStmt_1 | CreateTrigStmt_2 CreateTrigStmt_1: CREATE TRIGGER name TriggerActionTime TriggerEvents ON qualified_name TriggerForSpec TriggerWhen EXECUTE PROCEDURE func_name TriggerFuncArgs CreateTrigStmt_2: CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON qualified_name OptConstrFromTable ConstraintAttributeSpec FOR EACH ROW TriggerWhen EXECUTE PROCEDURE func_name TriggerFuncArgs TriggerActionTime : TriggerActionTime_1 | TriggerActionTime_2 | TriggerActionTime_3 TriggerActionTime_1: BEFORE TriggerActionTime_2: AFTER TriggerActionTime_3: INSTEAD OF TriggerEvents: TriggerOneEvent+ % / ~ OR ~ / TriggerOneEvent : TriggerOneEvent_1 | TriggerOneEvent_2 | TriggerOneEvent_3 | TriggerOneEvent_4 | TriggerOneEvent_5 TriggerOneEvent_1: INSERT TriggerOneEvent_2: DELETE TriggerOneEvent_3: UPDATE TriggerOneEvent_4: UPDATE OF columnList TriggerOneEvent_5: TRUNCATE TriggerForSpec: ( FOR TriggerForOptEach TriggerForType )? TriggerForOptEach: EACH? TriggerForType : TriggerForType_1 | TriggerForType_2 TriggerForType_1: ROW TriggerForType_2: STATEMENT TriggerWhen: ( WHEN a_expr )? TriggerFuncArgs : TriggerFuncArgs_1 | TriggerFuncArgs_2 TriggerFuncArgs_1: TriggerFuncArg TriggerFuncArgs_2: TriggerFuncArg* % / ~ ~ / TriggerFuncArg : TriggerFuncArg_1 | TriggerFuncArg_2 | TriggerFuncArg_3 | TriggerFuncArg_4 TriggerFuncArg_1: Iconst TriggerFuncArg_2: FCONST TriggerFuncArg_3: Sconst TriggerFuncArg_4: ColLabel OptConstrFromTable: ( FROM qualified_name )? ConstraintAttributeSpec: ConstraintAttributeElem* % ~ ConstraintAttributeElem : ConstraintAttributeElem_1 | ConstraintAttributeElem_2 | ConstraintAttributeElem_3 | ConstraintAttributeElem_4 | ConstraintAttributeElem_5 | ConstraintAttributeElem_6 ConstraintAttributeElem_1: NOT DEFERRABLE ConstraintAttributeElem_2: DEFERRABLE ConstraintAttributeElem_3: INITIALLY IMMEDIATE ConstraintAttributeElem_4: INITIALLY DEFERRED ConstraintAttributeElem_5: NOT VALID ConstraintAttributeElem_6: NO INHERIT DropTrigStmt : DropTrigStmt_1 | DropTrigStmt_2 DropTrigStmt_1: DROP TRIGGER name ON qualified_name opt_drop_behavior DropTrigStmt_2: DROP TRIGGER IF EXISTS name ON qualified_name opt_drop_behavior ############################################################################# # # QUERIES : # CREATE EVENT TRIGGER ... # DROP EVENT TRIGGER ... # ALTER EVENT TRIGGER ... # ############################################################################# CreateEventTrigStmt : CreateEventTrigStmt_1 | CreateEventTrigStmt_2 CreateEventTrigStmt_1: CREATE EVENT TRIGGER name ON ColLabel EXECUTE PROCEDURE func_name CreateEventTrigStmt_2: CREATE EVENT TRIGGER name ON ColLabel WHEN event_trigger_when_list EXECUTE PROCEDURE func_name event_trigger_when_list: event_trigger_when_item+ % / ~ AND ~ / event_trigger_when_item: ColId IN event_trigger_value_list event_trigger_value_list: SCONST+ % / ~ ~ / AlterEventTrigStmt: ALTER EVENT TRIGGER name enable_trigger enable_trigger : enable_trigger_1 | enable_trigger_2 | enable_trigger_3 | enable_trigger_4 enable_trigger_1: ENABLE enable_trigger_2: ENABLE REPLICA enable_trigger_3: ENABLE ALWAYS enable_trigger_4: DISABLE ############################################################################# # # QUERIES : # CREATE ASSERTION ... # DROP ASSERTION ... # ############################################################################# CreateAssertStmt: CREATE ASSERTION name CHECK a_expr ConstraintAttributeSpec DropAssertStmt: DROP ASSERTION name opt_drop_behavior ############################################################################# # # QUERY : # define (aggregate,operator,type) # ############################################################################# DefineStmt : DefineStmt_1 | DefineStmt_2 | DefineStmt_3 | DefineStmt_4 | DefineStmt_5 | DefineStmt_6 | DefineStmt_7 | DefineStmt_8 | DefineStmt_9 | DefineStmt_10 | DefineStmt_11 | DefineStmt_12 | DefineStmt_13 | DefineStmt_14 DefineStmt_1 : CREATE AGGREGATE func_name aggr_args definition DefineStmt_2 : CREATE AGGREGATE func_name old_aggr_definition DefineStmt_3 : CREATE OPERATOR any_operator definition DefineStmt_4 : CREATE TYPE any_name definition DefineStmt_5 : CREATE TYPE any_name DefineStmt_6 : CREATE TYPE any_name AS OptTableFuncElementList DefineStmt_7 : CREATE TYPE any_name AS ENUM opt_enum_val_list DefineStmt_8 : CREATE TYPE any_name AS RANGE definition DefineStmt_9 : CREATE TEXT SEARCH PARSER any_name definition DefineStmt_10: CREATE TEXT SEARCH DICTIONARY any_name definition DefineStmt_11: CREATE TEXT SEARCH TEMPLATE any_name definition DefineStmt_12: CREATE TEXT SEARCH CONFIGURATION any_name definition DefineStmt_13: CREATE COLLATION any_name definition DefineStmt_14: CREATE COLLATION any_name FROM any_name definition: def_list def_list: def_elem+ % / ~ ~ / def_elem : def_elem_1 | def_elem_2 def_elem_1: ColLabel def_arg def_elem_2: ColLabel # Note: any simple identifier will be returned as a type name! def_arg : def_arg_1 | def_arg_2 | def_arg_3 | def_arg_4 | def_arg_5 def_arg_1: func_type def_arg_2: reserved_keyword def_arg_3: qual_all_Op def_arg_4: NumericOnly def_arg_5: Sconst aggr_args : aggr_args_1 | aggr_args_2 aggr_args_1: type_list aggr_args_2: old_aggr_definition: old_aggr_list old_aggr_list: old_aggr_elem+ % / ~ ~ / # Must use IDENT here to avoid reduce/reduce conflicts; fortunately none of # the item names needed in old aggregate definitions are likely to become # SQL keywords. old_aggr_elem: IDENT def_arg opt_enum_val_list: enum_val_list? enum_val_list: Sconst+ % / ~ ~ / ############################################################################# # # ALTER TYPE enumtype ADD ... # ############################################################################# AlterEnumStmt : AlterEnumStmt_1 | AlterEnumStmt_2 | AlterEnumStmt_3 AlterEnumStmt_1: ALTER TYPE any_name ADD VALUE Sconst AlterEnumStmt_2: ALTER TYPE any_name ADD VALUE Sconst BEFORE Sconst AlterEnumStmt_3: ALTER TYPE any_name ADD VALUE Sconst AFTER Sconst ############################################################################# # # QUERIES : # CREATE OPERATOR CLASS ... # CREATE OPERATOR FAMILY ... # ALTER OPERATOR FAMILY ... # DROP OPERATOR CLASS ... # DROP OPERATOR FAMILY ... # ############################################################################# CreateOpClassStmt: CREATE OPERATOR CLASS any_name opt_default FOR TYPE Typename USING access_method opt_opfamily AS opclass_item_list opclass_item_list: opclass_item+ % / ~ ~ / opclass_item : opclass_item_1 | opclass_item_2 | opclass_item_3 | opclass_item_4 | opclass_item_5 opclass_item_1: OPERATOR Iconst any_operator opclass_purpose opt_recheck opclass_item_2: OPERATOR Iconst any_operator oper_argtypes opclass_purpose opt_recheck opclass_item_3: FUNCTION Iconst func_name func_args opclass_item_4: FUNCTION Iconst type_list func_name func_args opclass_item_5: STORAGE Typename opt_default: DEFAULT? opt_opfamily: ( FAMILY any_name )? opclass_purpose : ( opclass_purpose_1 | opclass_purpose_2 )? opclass_purpose_1: FOR SEARCH opclass_purpose_2: FOR ORDER BY any_name # RECHECK no longer does anything in opclass definitions, # but we still accept it to ease porting of old database # dumps. opt_recheck: RECHECK? CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method AlterOpFamilyStmt : AlterOpFamilyStmt_1 | AlterOpFamilyStmt_2 AlterOpFamilyStmt_1: ALTER OPERATOR FAMILY any_name USING access_method ADD opclass_item_list AlterOpFamilyStmt_2: ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list opclass_drop_list: opclass_drop+ % / ~ ~ / opclass_drop : opclass_drop_1 | opclass_drop_2 opclass_drop_1: OPERATOR Iconst type_list opclass_drop_2: FUNCTION Iconst type_list DropOpClassStmt : DropOpClassStmt_1 | DropOpClassStmt_2 DropOpClassStmt_1: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior DropOpClassStmt_2: DROP OPERATOR CLASS IF EXISTS any_name USING access_method opt_drop_behavior DropOpFamilyStmt : DropOpFamilyStmt_1 | DropOpFamilyStmt_2 DropOpFamilyStmt_1: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior DropOpFamilyStmt_2: DROP OPERATOR FAMILY IF EXISTS any_name USING access_method opt_drop_behavior ############################################################################# # # QUERY: # # DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ] # REASSIGN OWNED BY username [, username ...] TO username # ############################################################################# DropOwnedStmt: DROP OWNED BY name_list opt_drop_behavior ReassignOwnedStmt: REASSIGN OWNED BY name_list TO name ############################################################################# # # QUERY: # # DROP itemtype [ IF EXISTS ] itemname [, itemname ...] # [ RESTRICT | CASCADE ] # ############################################################################# DropStmt : DropStmt_1 | DropStmt_2 | DropStmt_3 | DropStmt_4 DropStmt_1: DROP drop_type IF EXISTS any_name_list opt_drop_behavior DropStmt_2: DROP drop_type any_name_list opt_drop_behavior DropStmt_3: DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior DropStmt_4: DROP INDEX CONCURRENTLY IF EXISTS any_name_list opt_drop_behavior drop_type : drop_type_1 | drop_type_2 | drop_type_3 | drop_type_4 | drop_type_5 | drop_type_6 | drop_type_7 | drop_type_8 | drop_type_9 | drop_type_10 | drop_type_11 | drop_type_12 | drop_type_13 | drop_type_14 | drop_type_15 | drop_type_16 drop_type_1 : TABLE drop_type_2 : SEQUENCE drop_type_3 : VIEW drop_type_4 : INDEX drop_type_5 : FOREIGN TABLE drop_type_6 : EVENT_TRIGGER drop_type_7 : TYPE drop_type_8 : DOMAIN drop_type_9 : COLLATION drop_type_10: CONVERSION drop_type_11: SCHEMA drop_type_12: EXTENSION drop_type_13: TEXT SEARCH PARSER drop_type_14: TEXT SEARCH DICTIONARY drop_type_15: TEXT SEARCH TEMPLATE drop_type_16: TEXT SEARCH CONFIGURATION any_name_list: any_name+ % / ~ ~ / any_name : any_name_1 | any_name_2 any_name_1: ColId any_name_2: ColId attrs attrs : attrs_1 | attrs_2 attrs_1: attr_name attrs_2: 2+ % / ~ ~ / ############################################################################# # # QUERY: # truncate table relname1, relname2, ... # ############################################################################# TruncateStmt: TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior opt_restart_seqs : ( opt_restart_seqs_1 | opt_restart_seqs_2 )? opt_restart_seqs_1: CONTINUE IDENTITY opt_restart_seqs_2: RESTART IDENTITY ############################################################################# # # The COMMENT ON statement can take different forms based upon the type of # the object associated with the comment. The form of the statement is: # # COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW | # COLLATION | CONVERSION | LANGUAGE | OPERATOR CLASS | # LARGE OBJECT | CAST | COLUMN | SCHEMA | TABLESPACE | # EXTENSION | ROLE | TEXT SEARCH PARSER | # TEXT SEARCH DICTIONARY | TEXT SEARCH TEMPLATE | # TEXT SEARCH CONFIGURATION | FOREIGN TABLE | # FOREIGN DATA WRAPPER | SERVER | EVENT TRIGGER ] | # AGGREGATE (arg1, ...) | # FUNCTION (arg1, arg2, ...) | # OPERATOR (leftoperand_typ, rightoperand_typ) | # TRIGGER ON | # CONSTRAINT ON | # RULE ON ] # IS 'text' # ############################################################################# CommentStmt : CommentStmt_1 | CommentStmt_2 | CommentStmt_3 | CommentStmt_4 | CommentStmt_5 | CommentStmt_6 | CommentStmt_7 | CommentStmt_8 | CommentStmt_9 | CommentStmt_10 | CommentStmt_11 | CommentStmt_12 | CommentStmt_13 | CommentStmt_14 | CommentStmt_15 | CommentStmt_16 | CommentStmt_17 CommentStmt_1 : COMMENT ON comment_type any_name IS comment_text CommentStmt_2 : COMMENT ON AGGREGATE func_name aggr_args IS comment_text CommentStmt_3 : COMMENT ON FUNCTION func_name func_args IS comment_text CommentStmt_4 : COMMENT ON OPERATOR any_operator oper_argtypes IS comment_text CommentStmt_5 : COMMENT ON CONSTRAINT name ON any_name IS comment_text CommentStmt_6 : COMMENT ON RULE name ON any_name IS comment_text CommentStmt_7 : COMMENT ON RULE name IS comment_text CommentStmt_8 : COMMENT ON TRIGGER name ON any_name IS comment_text CommentStmt_9 : COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text CommentStmt_10: COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text CommentStmt_11: COMMENT ON LARGE OBJECT NumericOnly IS comment_text CommentStmt_12: COMMENT ON CAST Typename AS Typename IS comment_text CommentStmt_13: COMMENT ON opt_procedural LANGUAGE any_name IS comment_text CommentStmt_14: COMMENT ON TEXT SEARCH PARSER any_name IS comment_text CommentStmt_15: COMMENT ON TEXT SEARCH DICTIONARY any_name IS comment_text CommentStmt_16: COMMENT ON TEXT SEARCH TEMPLATE any_name IS comment_text CommentStmt_17: COMMENT ON TEXT SEARCH CONFIGURATION any_name IS comment_text comment_type : comment_type_1 | comment_type_2 | comment_type_3 | comment_type_4 | comment_type_5 | comment_type_6 | comment_type_7 | comment_type_8 | comment_type_9 | comment_type_10 | comment_type_11 | comment_type_12 | comment_type_13 | comment_type_14 | comment_type_15 | comment_type_16 | comment_type_17 | comment_type_18 comment_type_1 : COLUMN comment_type_2 : DATABASE comment_type_3 : SCHEMA comment_type_4 : INDEX comment_type_5 : SEQUENCE comment_type_6 : TABLE comment_type_7 : DOMAIN comment_type_8 : TYPE comment_type_9 : VIEW comment_type_10: COLLATION comment_type_11: CONVERSION comment_type_12: TABLESPACE comment_type_13: EXTENSION comment_type_14: ROLE comment_type_15: FOREIGN TABLE comment_type_16: SERVER comment_type_17: FOREIGN DATA WRAPPER comment_type_18: EVENT TRIGGER comment_text : comment_text_1 | comment_text_2 comment_text_1: Sconst comment_text_2: NULL ############################################################################# # # SECURITY LABEL [FOR ] ON IS