packages feed

Pugs 6.2.13.8 → 6.2.13.9

raw patch · 41 files changed

+27141/−40 lines, 41 filesdep ~haskelinedep ~pugs-compatsetup-changed

Dependency ranges changed: haskeline, pugs-compat

Files

Pugs.cabal view
@@ -1,5 +1,5 @@ Name            : Pugs-Version         : 6.2.13.8+Version         : 6.2.13.9 license         : BSD3 license-file    : LICENSE cabal-version   : >= 1.2@@ -13,10 +13,40 @@ description     : A Perl 6 Implementation author          : Audrey Tang <audreyt@audreyt.org> tested-with     : GHC--- c-sources       : src/perl5/p5embed.c--- hs-source-dirs  : src--- extensions      : ForeignFunctionInterface--- include-dirs    : /usr/local/include /opt/local/include /usr/local/lib/perl5/5.9.5/darwin-2level/CORE+data-files      :+    blib6/pugs/perl5/lib/Parse/Yapp/Driver.pm+    blib6/pugs/perl5/lib/Parse/Yapp/Grammar.pm+    blib6/pugs/perl5/lib/Parse/Yapp/Lalr.pm+    blib6/pugs/perl5/lib/Parse/Yapp/Options.pm+    blib6/pugs/perl5/lib/Parse/Yapp/Output.pm+    blib6/pugs/perl5/lib/Parse/Yapp/Parse.pm+    blib6/pugs/perl5/lib/Parse/Yapp.pm+    blib6/pugs/perl5/lib/Pugs/AST/Expression.pm+    blib6/pugs/perl5/lib/Pugs/Compiler/Grammar.pm+    blib6/pugs/perl5/lib/Pugs/Compiler/Regex.pm+    blib6/pugs/perl5/lib/Pugs/Compiler/RegexPerl5.pm+    blib6/pugs/perl5/lib/Pugs/Compiler/Rule.pm+    blib6/pugs/perl5/lib/Pugs/Compiler/Token.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Grammar/Perl5.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Parsec.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/CharClass.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/Ratchet.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/Regex.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5.pm+    blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl6/Ratchet.pm+    blib6/pugs/perl5/lib/Pugs/Grammar/Base.pm+    blib6/pugs/perl5/lib/Pugs/Grammar/Precedence.pm+    blib6/pugs/perl5/lib/Pugs/Grammar/Rule.pm+    blib6/pugs/perl5/lib/Pugs/Grammar/Rule.pmc+    blib6/pugs/perl5/lib/Pugs/Grammar/Rule2.pm+    blib6/pugs/perl5/lib/Pugs/Grammar/RulePure.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Common.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Match/HsBridge.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Match.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Regex.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Rule.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/StrPos.pm+    blib6/pugs/perl5/lib/Pugs/Runtime/Tracer.pm extra-source-files:     src/Pugs.hs     src/Pugs/AST.hs@@ -115,13 +145,9 @@     src/Pugs/Val/Code.hs     src/Pugs/Version.hs -flag Optimize-    description: Enable optimizations-    default:     False---- flag Debug---     description: Enable debugging hooks---     default:     False+flag Perl5+    description: Enable Perl 5 Embedding+    default:     True  executable pugs     main-is:            Main.hs@@ -130,27 +156,22 @@     build-depends:         base, haskell98, filepath, mtl, stm, parsec < 3.0.0, network,         pretty, time, random, process, containers, bytestring,-        array, directory, utf8-string, binary, haskeline >= 0.2,+        array, directory, utf8-string, binary, haskeline >= 0.2.1,          MetaObject       >= 0.0.4,         HsParrot         >= 0.0.2,-        pugs-compat      >= 0.0.4,+        pugs-compat      >= 0.0.5,         pugs-DrIFT       >= 2.2.3.0,         stringtable-atom >= 0.0.4,         HsSyck           >= 0.44         -- HsPerl5 -    if flag(Optimize)-        ghc-options: -O2-        -    -- if flag(Debug)-    --     ghc-options: -prof -auto-all--    -- cpp-options: -DPUGS_HAVE_PERL5=1+    if flag(Perl5)+        cpp-options: -DPUGS_HAVE_PERL5=1      c-sources:         cbits/Prelude_pm.c cbits/Test_pm.c-    --        perl5/p5embed.c+        perl5/p5embed.c -    --    includes:-    --        perl5/p5embed.h+    includes:+        perl5/p5embed.h
Setup.lhs view
@@ -1,3 +1,8 @@-#!/usr/bin/env runhaskell+#!/usr/bin/env runghc > import Distribution.Simple-> main = defaultMain+> import System.Cmd (rawSystem)+> +> main :: IO ()+> main = writeBuildInfo >> defaultMainWithHooks defaultUserHooks+>     where+>     writeBuildInfo = rawSystem "perl" ["Configure.PL"]
+ blib6/pugs/perl5/lib/Parse/Yapp.pm view
@@ -0,0 +1,512 @@+#+# Module Parse::Yapp.pm.+#+# Copyright (c) 1998-2001, Francois Desarmenien, all right reserved.+#+# See the Copyright section at the end of the Parse/Yapp.pm pod section+# for usage and distribution rights.+#+#+package Parse::Yapp;++use strict;+use vars qw($VERSION @ISA);+@ISA = qw(Parse::Yapp::Output);++use Parse::Yapp::Output;++# $VERSION is in Parse/Yapp/Driver.pm+++1;++__END__++=head1 NAME++Parse::Yapp - Perl extension for generating and using LALR parsers. ++=head1 SYNOPSIS++  yapp -m MyParser grammar_file.yp++  ...++  use MyParser;++  $parser=new MyParser();+  $value=$parser->YYParse(yylex => \&lexer_sub, yyerror => \&error_sub);++  $nberr=$parser->YYNberr();++  $parser->YYData->{DATA}= [ 'Anything', 'You Want' ];++  $data=$parser->YYData->{DATA}[0];++=head1 DESCRIPTION++Parse::Yapp (Yet Another Perl Parser compiler) is a collection of modules+that let you generate and use yacc like thread safe (reentrant) parsers with+perl object oriented interface.++The script yapp is a front-end to the Parse::Yapp module and let you+easily create a Perl OO parser from an input grammar file.++=head2 The Grammar file++=over 4++=item C<Comments>++Through all your files, comments are either Perl style, introduced by I<#>+up to the end of line, or C style, enclosed between  I</*> and I<*/>.+++=item C<Tokens and string literals>+++Through all the grammar files, two kind of symbols may appear:+I<Non-terminal> symbols, called also I<left-hand-side> symbols,+which are the names of your rules, and I<Terminal> symbols, called+also I<Tokens>.++Tokens are the symbols your lexer function will feed your parser with+(see below). They are of two flavours: symbolic tokens and string+literals.++Non-terminals and symbolic tokens share the same identifier syntax:++		[A-Za-z][A-Za-z0-9_]*++String literals are enclosed in single quotes and can contain almost+anything. They will be output to your parser file double-quoted, making+any special character as such. '"', '$' and '@' will be automatically+quoted with '\', making their writing more natural. On the other hand,+if you need a single quote inside your literal, just quote it with '\'.++You cannot have a literal I<'error'> in your grammar as it would+confuse the driver with the I<error> token. Use a symbolic token instead.+In case you inadvertently use it, this will produce a warning telling you+you should have written it I<error> and will treat it as if it were the+I<error> token, which is certainly NOT what you meant.+++=item C<Grammar file syntax>++It is very close to yacc syntax (in fact, I<Parse::Yapp> should compile+a clean I<yacc> grammar without any modification, whereas the opposite+is not true).++This file is divided in three sections, separated by C<%%>:++	header section+	%%+	rules section+	%%+	footer section++=over 4++=item B<The Header Section> section may optionally contain:++=item *++One or more code blocks enclosed inside C<%{> and C<%}> just like in+yacc. They may contain any valid Perl code and will be copied verbatim+at the very beginning of the parser module. They are not as useful as+they are in yacc, but you can use them, for example, for global variable+declarations, though you will notice later that such global variables can+be avoided to make a reentrant parser module.++=item *++Precedence declarations, introduced by C<%left>, C<%right> and C<%nonassoc>+specifying associativity, followed by the list of tokens or litterals+having the same precedence and associativity.+The precedence beeing the latter declared will be having the highest level.+(see the yacc or bison manuals for a full explanation of how they work,+as they are implemented exactly the same way in Parse::Yapp)++=item *++C<%start> followed by a rule's left hand side, declaring this rule to+be the starting rule of your grammar. The default, when C<%start> is not+used, is the first rule in your grammar section.++=item *++C<%token> followed by a list of symbols, forcing them to be recognized+as tokens, generating a syntax error if used in the left hand side of+a rule declaration.+Note that in Parse::Yapp, you I<don't> need to declare tokens as in yacc: any+symbol not appearing as a left hand side of a rule is considered to be+a token.+Other yacc declarations or constructs such as C<%type> and C<%union> are+parsed but (almost) ignored.++=item *++C<%expect> followed by a number, suppress warnings about number of Shift/Reduce+conflicts when both numbers match, a la bison.+++=item B<The Rule Section> contains your grammar rules:++A rule is made of a left-hand-side symbol, followed by a C<':'> and one+or more right-hand-sides separated by C<'|'> and terminated by a C<';'>:++    exp:    exp '+' exp+        |   exp '-' exp+        ;++A right hand side may be empty:++    input:  #empty+        |   input line+        ;++(if you have more than one empty rhs, Parse::Yapp will issue a warning,+as this is usually a mistake, and you will certainly have a reduce/reduce+conflict)+++A rhs may be followed by an optional C<%prec> directive, followed+by a token, giving the rule an explicit precedence (see yacc manuals+for its precise meaning) and optionnal semantic action code block (see+below).++    exp:   '-' exp %prec NEG { -$_[1] }+        |  exp '+' exp       { $_[1] + $_[3] }+        |  NUM+        ;++Note that in Parse::Yapp, a lhs I<cannot> appear more than once as+a rule name (This differs from yacc).+++=item C<The footer section>++may contain any valid Perl code and will be appended at the very end+of your parser module. Here you can write your lexer, error report+subs and anything relevant to you parser.++=item C<Semantic actions>++Semantic actions are run every time a I<reduction> occurs in the+parsing flow and they must return a semantic value.++They are (usually, but see below C<In rule actions>) written at+the very end of the rhs, enclosed with C<{ }>, and are copied verbatim+to your parser file, inside of the rules table.++Be aware that matching braces in Perl is much more difficult than+in C: inside strings they don't need to match. While in C it is+very easy to detect the beginning of a string construct, or a+single character, it is much more difficult in Perl, as there+are so many ways of writing such literals. So there is no check+for that today. If you need a brace in a double-quoted string, just+quote it (C<\{> or C<\}>). For single-quoted strings, you will need+to make a comment matching it I<in th right order>.+Sorry for the inconvenience.++    {+        "{ My string block }".+        "\{ My other string block \}".+        qq/ My unmatched brace \} /.+        # Force the match: {+        q/ for my closing brace } /+        q/ My opening brace { /+        # must be closed: }+    }++All of these constructs should work.+++In Parse::Yapp, semantic actions are called like normal Perl sub calls,+with their arguments passed in C<@_>, and their semantic value are+their return values.++$_[1] to $_[n] are the parameters just as $1 to $n in yacc, while+$_[0] is the parser object itself.++Having $_[0] beeing the parser object itself allows you to call+parser methods. Thats how the yacc macros are implemented:++	yyerrok is done by calling $_[0]->YYErrok+	YYERROR is done by calling $_[0]->YYError+	YYACCEPT is done by calling $_[0]->YYAccept+	YYABORT is done by calling $_[0]->YYAbort++All those methods explicitly return I<undef>, for convenience.++    YYRECOVERING is done by calling $_[0]->YYRecovering++Four useful methods in error recovery sub++    $_[0]->YYCurtok+    $_[0]->YYCurval+    $_[0]->YYExpect+    $_[0]->YYLexer++return respectivly the current input token that made the parse fail,+its semantic value (both can be used to modify their values too, but+I<know what you are doing> ! See I<Error reporting routine> section for+an example), a list which contains the tokens the parser expected when+the failure occured and a reference to the lexer routine.++Note that if C<$_[0]-E<gt>YYCurtok> is declared as a C<%nonassoc> token,+it can be included in C<$_[0]-E<gt>YYExpect> list whenever the input+try to use it in an associative way. This is not a bug: the token+IS expected to report an error if encountered.++To detect such a thing in your error reporting sub, the following+example should do the trick:++        grep { $_[0]->YYCurtok eq $_ } $_[0]->YYExpect+    and do {+        #Non-associative token used in an associative expression+    };++Accessing semantics values on the left of your reducing rule is done+through the method++    $_[0]->YYSemval( index )++where index is an integer. Its value being I<1 .. n> returns the same values+than I<$_[1] .. $_[n]>, but I<-n .. 0> returns values on the left of the rule+beeing reduced (It is related to I<$-n .. $0 .. $n> in yacc, but you+cannot use I<$_[0]> or I<$_[-n]> constructs in Parse::Yapp for obvious reasons)+++There is also a provision for a user data area in the parser object,+accessed by the method:++    $_[0]->YYData++which returns a reference to an anonymous hash, which let you have+all of your parsing data held inside the object (see the Calc.yp+or ParseYapp.yp files in the distribution for some examples).+That's how you can make you parser module reentrant: all of your+module states and variables are held inside the parser object.++Note: unfortunatly, method calls in Perl have a lot of overhead,+      and when YYData is used, it may be called a huge number+      of times. If your are not a *real* purist and efficiency+      is your concern, you may access directly the user-space+      in the object: $parser->{USER} wich is a reference to an+      anonymous hash array, and then benchmark.++If no action is specified for a rule, the equivalant of a default+action is run, which returns the first parameter:++   { $_[1] }++=item C<In rule actions>++It is also possible to embed semantic actions inside of a rule:++    typedef:    TYPE { $type = $_[1] } identlist { ... } ;++When the Parse::Yapp's parser encounter such an embedded action, it modifies+the grammar as if you wrote (although @x-1 is not a legal lhs value):++    @x-1:   /* empty */ { $type = $_[1] };+    typedef:    TYPE @x-1 identlist { ... } ;++where I<x> is a sequential number incremented for each "in rule" action,+and I<-1> represents the "dot position" in the rule where the action arises.++In such actions, you can use I<$_[1]..$_[n]> variables, which are the+semantic values on the left of your action.++Be aware that the way Parse::Yapp modifies your grammar because of+I<in rule actions> can produce, in some cases, spurious conflicts+that wouldn't happen otherwise.  ++=item C<Generating the Parser Module>++Now that you grammar file is written, you can use yapp on it+to generate your parser module:++    yapp -v Calc.yp++will create two files F<Calc.pm>, your parser module, and F<Calc.output>+a verbose output of your parser rules, conflicts, warnings, states+and summary.++What your are missing now is a lexer routine.++=item C<The Lexer sub>++is called each time the parser need to read the next token.++It is called with only one argument that is the parser object itself,+so you can access its methods, specially the++    $_[0]->YYData++data area.++It is its duty to return the next token and value to the parser.+They C<must> be returned as a list of two variables, the first one+is the token known by the parser (symbolic or literal), the second+one beeing anything you want (usualy the content of the token, or the+literal value) from a simple scalar value to any complex reference,+as the parsing driver never use it but to call semantic actions:++    ( 'NUMBER', $num )+or+    ( '>=', '>=' )+or+    ( 'ARRAY', [ @values ] )++When the lexer reach the end of input, it must return the C<''>+empty token with an undef value:++     ( '', undef )++Note that your lexer should I<never> return C<'error'> as token+value: for the driver, this is the error token used for error+recovery and would lead to odd reactions.++Now that you have your lexer written, maybe you will need to output+meaningful error messages, instead of the default which is to print+'Parse error.' on STDERR.++So you will need an Error reporting sub.++item C<Error reporting routine>++If you want one, write it knowing that it is passed as parameter+the parser object. So you can share information whith the lexer+routine quite easily.++You can also use the C<$_[0]-E<gt>YYErrok> method in it, which will+resume parsing as if no error occured. Of course, since the invalid+token is still invalid, you're supposed to fix the problem by+yourself.++The method C<$_[0]-E<gt>YYLexer> may help you, as it returns a reference+to the lexer routine, and can be called as++    ($tok,$val)=&{$_[0]->Lexer}++to get the next token and semantic value from the input stream. To+make them current for the parser, use:++    ($_[0]->YYCurtok, $_[0]->YYCurval) = ($tok, $val)++and know what you're doing...++=item C<Parsing>++Now you've got everything to do the parsing.++First, use the parser module:++    use Calc;++Then create the parser object:++    $parser=new Calc;++Now, call the YYParse method, telling it where to find the lexer+and error report subs:++    $result=$parser->YYParse(yylex => \&Lexer,+                           yyerror => \&ErrorReport);++(assuming Lexer and ErrorReport subs have been written in your current+package)++The order in which parameters appear is unimportant.++Et voila.++The YYParse method will do the parse, then return the last semantic+value returned, or undef if error recovery cannot recover.++If you need to be sure the parse has been successful (in case your+last returned semantic value I<is> undef) make a call to:++    $parser->YYNberr()++which returns the total number of time the error reporting sub has been called.++=item C<Error Recovery>++in Parse::Yapp is implemented the same way it is in yacc.++=item C<Debugging Parser>++To debug your parser, you can call the YYParse method with a debug parameter:++    $parser->YYParse( ... , yydebug => value, ... )++where value is a bitfield, each bit representing a specific debug output:++    Bit Value    Outputs+    0x01         Token reading (useful for Lexer debugging)+    0x02         States information+    0x04         Driver actions (shifts, reduces, accept...)+    0x08         Parse Stack dump+    0x10         Error Recovery tracing++To have a full debugging ouput, use++    debug => 0x1F++Debugging output is sent to STDERR, and be aware that it can produce+C<huge> outputs.++=item C<Standalone Parsers>++By default, the parser modules generated will need the Parse::Yapp+module installed on the system to run. They use the Parse::Yapp::Driver+which can be safely shared between parsers in the same script.++In the case you'd prefer to have a standalone module generated, use+the C<-s> switch with yapp: this will automagically copy the driver+code into your module so you can use/distribute it without the need+of the Parse::Yapp module, making it really a C<Standalone Parser>.++If you do so, please remember to include Parse::Yapp's copyright notice+in your main module copyright, so others can know about Parse::Yapp module.++=item C<Source file line numbers>++by default will be included in the generated parser module, which will help+to find the guilty line in your source file in case of a syntax error.+You can disable this feature by compiling your grammar with yapp using+the C<-n> switch.++=back++=head1 BUGS AND SUGGESTIONS++If you find bugs, think of anything that could improve Parse::Yapp+or have any questions related to it, feel free to contact the author.++=head1 AUTHOR++Francois Desarmenien  <francois@fdesar.net>++=head1 SEE ALSO++yapp(1) perl(1) yacc(1) bison(1).++=head1 COPYRIGHT++The Parse::Yapp module and its related modules and shell scripts are copyright+(c) 1998-2001 Francois Desarmenien, France. All rights reserved.++You may use and distribute them under the terms of either+the GNU General Public License or the Artistic License,+as specified in the Perl README file.++If you use the "standalone parser" option so people don't need to install+Parse::Yapp on their systems in order to run you software, this copyright+noticed should be included in your software copyright too, and the copyright+notice in the embedded driver should be left untouched.++=cut
+ blib6/pugs/perl5/lib/Parse/Yapp/Driver.pm view
@@ -0,0 +1,471 @@+#+# Module Parse::Yapp::Driver+#+# This module is part of the Parse::Yapp package available on your+# nearest CPAN+#+# Any use of this module in a standalone parser make the included+# text under the same copyright as the Parse::Yapp module itself.+#+# This notice should remain unchanged.+#+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.+# (see the pod text in Parse::Yapp module for use and distribution rights)+#++package Parse::Yapp::Driver;++require 5.004;++use strict;++use vars qw ( $VERSION $COMPATIBLE $FILENAME );++$VERSION = '1.05';+$COMPATIBLE = '0.07';+$FILENAME=__FILE__;++use Carp;++#Known parameters, all starting with YY (leading YY will be discarded)+my(%params)=(YYLEX => 'CODE', 'YYERROR' => 'CODE', YYVERSION => '',+			 YYRULES => 'ARRAY', YYSTATES => 'ARRAY', YYDEBUG => '');+#Mandatory parameters+my(@params)=('LEX','RULES','STATES');++sub new {+    my($class)=shift;+	my($errst,$nberr,$token,$value,$check,$dotpos);+    my($self)={ ERROR => \&_Error,+				ERRST => \$errst,+                NBERR => \$nberr,+				TOKEN => \$token,+				VALUE => \$value,+				DOTPOS => \$dotpos,+				STACK => [],+				DEBUG => 0,+				CHECK => \$check };++	_CheckParams( [], \%params, \@_, $self );++		exists($$self{VERSION})+	and	$$self{VERSION} < $COMPATIBLE+	and	croak "Yapp driver version $VERSION ".+			  "incompatible with version $$self{VERSION}:\n".+			  "Please recompile parser module.";++        ref($class)+    and $class=ref($class);++    bless($self,$class);+}++sub YYParse {+    my($self)=shift;+    my($retval);++	_CheckParams( \@params, \%params, \@_, $self );++	if($$self{DEBUG}) {+		_DBLoad();+		$retval = eval '$self->_DBParse()';#Do not create stab entry on compile+        $@ and die $@;+	}+	else {+		$retval = $self->_Parse();+	}+    $retval+}++sub YYData {+	my($self)=shift;++		exists($$self{USER})+	or	$$self{USER}={};++	$$self{USER};+	+}++sub YYErrok {+	my($self)=shift;++	${$$self{ERRST}}=0;+    undef;+}++sub YYNberr {+	my($self)=shift;++	${$$self{NBERR}};+}++sub YYRecovering {+	my($self)=shift;++	${$$self{ERRST}} != 0;+}++sub YYAbort {+	my($self)=shift;++	${$$self{CHECK}}='ABORT';+    undef;+}++sub YYAccept {+	my($self)=shift;++	${$$self{CHECK}}='ACCEPT';+    undef;+}++sub YYError {+	my($self)=shift;++	${$$self{CHECK}}='ERROR';+    undef;+}++sub YYSemval {+	my($self)=shift;+	my($index)= $_[0] - ${$$self{DOTPOS}} - 1;++		$index < 0+	and	-$index <= @{$$self{STACK}}+	and	return $$self{STACK}[$index][1];++	undef;	#Invalid index+}++sub YYCurtok {+	my($self)=shift;++        @_+    and ${$$self{TOKEN}}=$_[0];+    ${$$self{TOKEN}};+}++sub YYCurval {+	my($self)=shift;++        @_+    and ${$$self{VALUE}}=$_[0];+    ${$$self{VALUE}};+}++sub YYExpect {+    my($self)=shift;++    keys %{$self->{STATES}[$self->{STACK}[-1][0]]{ACTIONS}}+}++sub YYLexer {+    my($self)=shift;++	$$self{LEX};+}+++#################+# Private stuff #+#################+++sub _CheckParams {+	my($mandatory,$checklist,$inarray,$outhash)=@_;+	my($prm,$value);+	my($prmlst)={};++	while(($prm,$value)=splice(@$inarray,0,2)) {+        $prm=uc($prm);+			exists($$checklist{$prm})+		or	croak("Unknow parameter '$prm'");+			ref($value) eq $$checklist{$prm}+		or	croak("Invalid value for parameter '$prm'");+        $prm=unpack('@2A*',$prm);+		$$outhash{$prm}=$value;+	}+	for (@$mandatory) {+			exists($$outhash{$_})+		or	croak("Missing mandatory parameter '".lc($_)."'");+	}+}++sub _Error {+	print "Parse error.\n";+}++sub _DBLoad {+	{+		no strict 'refs';++			exists(${__PACKAGE__.'::'}{_DBParse})#Already loaded ?+		and	return;+	}+	my($fname)=__FILE__;+	my(@drv);+	open(DRV,"<$fname") or die "Report this as a BUG: Cannot open $fname";+	while(<DRV>) {+                	/^\s*sub\s+_Parse\s*{\s*$/ .. /^\s*}\s*#\s*_Parse\s*$/+        	and     do {+                	s/^#DBG>//;+                	push(@drv,$_);+        	}+	}+	close(DRV);++	$drv[0]=~s/_P/_DBP/;+	eval join('',@drv);+}++#Note that for loading debugging version of the driver,+#this file will be parsed from 'sub _Parse' up to '}#_Parse' inclusive.+#So, DO NOT remove comment at end of sub !!!+sub _Parse {+    my($self)=shift;++	my($rules,$states,$lex,$error)+     = @$self{ 'RULES', 'STATES', 'LEX', 'ERROR' };+	my($errstatus,$nberror,$token,$value,$stack,$check,$dotpos)+     = @$self{ 'ERRST', 'NBERR', 'TOKEN', 'VALUE', 'STACK', 'CHECK', 'DOTPOS' };++#DBG>	my($debug)=$$self{DEBUG};+#DBG>	my($dbgerror)=0;++#DBG>	my($ShowCurToken) = sub {+#DBG>		my($tok)='>';+#DBG>		for (split('',$$token)) {+#DBG>			$tok.=		(ord($_) < 32 or ord($_) > 126)+#DBG>					?	sprintf('<%02X>',ord($_))+#DBG>					:	$_;+#DBG>		}+#DBG>		$tok.='<';+#DBG>	};++	$$errstatus=0;+	$$nberror=0;+	($$token,$$value)=(undef,undef);+	@$stack=( [ 0, undef ] );+	$$check='';++    while(1) {+        my($actions,$act,$stateno);++        $stateno=$$stack[-1][0];+        $actions=$$states[$stateno];++#DBG>	print STDERR ('-' x 40),"\n";+#DBG>		$debug & 0x2+#DBG>	and	print STDERR "In state $stateno:\n";+#DBG>		$debug & 0x08+#DBG>	and	print STDERR "Stack:[".+#DBG>					 join(',',map { $$_[0] } @$stack).+#DBG>					 "]\n";+++        if  (exists($$actions{ACTIONS})) {++				defined($$token)+            or	do {+				($$token,$$value)=&$lex($self);+#DBG>				$debug & 0x01+#DBG>			and	print STDERR "Need token. Got ".&$ShowCurToken."\n";+			};++            $act=   exists($$actions{ACTIONS}{$$token})+                    ?   $$actions{ACTIONS}{$$token}+                    :   exists($$actions{DEFAULT})+                        ?   $$actions{DEFAULT}+                        :   undef;+        }+        else {+            $act=$$actions{DEFAULT};+#DBG>			$debug & 0x01+#DBG>		and	print STDERR "Don't need token.\n";+        }++            defined($act)+        and do {++                $act > 0+            and do {        #shift++#DBG>				$debug & 0x04+#DBG>			and	print STDERR "Shift and go to state $act.\n";++					$$errstatus+				and	do {+					--$$errstatus;++#DBG>					$debug & 0x10+#DBG>				and	$dbgerror+#DBG>				and	$$errstatus == 0+#DBG>				and	do {+#DBG>					print STDERR "**End of Error recovery.\n";+#DBG>					$dbgerror=0;+#DBG>				};+				};+++                push(@$stack,[ $act, $$value ]);++					$$token ne ''	#Don't eat the eof+				and	$$token=$$value=undef;+                next;+            };++            #reduce+            my($lhs,$len,$code,@sempar,$semval);+            ($lhs,$len,$code)=@{$$rules[-$act]};++#DBG>			$debug & 0x04+#DBG>		and	$act+#DBG>		and	print STDERR "Reduce using rule ".-$act." ($lhs,$len): ";++                $act+            or  $self->YYAccept();++            $$dotpos=$len;++                unpack('A1',$lhs) eq '@'    #In line rule+            and do {+                    $lhs =~ /^\@[0-9]+\-([0-9]+)$/+                or  die "In line rule name '$lhs' ill formed: ".+                        "report it as a BUG.\n";+                $$dotpos = $1;+            };++            @sempar =       $$dotpos+                        ?   map { $$_[1] } @$stack[ -$$dotpos .. -1 ]+                        :   ();++            $semval = $code ? &$code( $self, @sempar )+                            : @sempar ? $sempar[0] : undef;++            splice(@$stack,-$len,$len);++                $$check eq 'ACCEPT'+            and do {++#DBG>			$debug & 0x04+#DBG>		and	print STDERR "Accept.\n";++				return($semval);+			};++                $$check eq 'ABORT'+            and	do {++#DBG>			$debug & 0x04+#DBG>		and	print STDERR "Abort.\n";++				return(undef);++			};++#DBG>			$debug & 0x04+#DBG>		and	print STDERR "Back to state $$stack[-1][0], then ";++                $$check eq 'ERROR'+            or  do {+#DBG>				$debug & 0x04+#DBG>			and	print STDERR +#DBG>				    "go to state $$states[$$stack[-1][0]]{GOTOS}{$lhs}.\n";++#DBG>				$debug & 0x10+#DBG>			and	$dbgerror+#DBG>			and	$$errstatus == 0+#DBG>			and	do {+#DBG>				print STDERR "**End of Error recovery.\n";+#DBG>				$dbgerror=0;+#DBG>			};++			    push(@$stack,+                     [ $$states[$$stack[-1][0]]{GOTOS}{$lhs}, $semval ]);+                $$check='';+                next;+            };++#DBG>			$debug & 0x04+#DBG>		and	print STDERR "Forced Error recovery.\n";++            $$check='';++        };++        #Error+            $$errstatus+        or   do {++            $$errstatus = 1;+            &$error($self);+                $$errstatus # if 0, then YYErrok has been called+            or  next;       # so continue parsing++#DBG>			$debug & 0x10+#DBG>		and	do {+#DBG>			print STDERR "**Entering Error recovery.\n";+#DBG>			++$dbgerror;+#DBG>		};++            ++$$nberror;++        };++			$$errstatus == 3	#The next token is not valid: discard it+		and	do {+				$$token eq ''	# End of input: no hope+			and	do {+#DBG>				$debug & 0x10+#DBG>			and	print STDERR "**At eof: aborting.\n";+				return(undef);+			};++#DBG>			$debug & 0x10+#DBG>		and	print STDERR "**Dicard invalid token ".&$ShowCurToken.".\n";++			$$token=$$value=undef;+		};++        $$errstatus=3;++		while(	  @$stack+			  and (		not exists($$states[$$stack[-1][0]]{ACTIONS})+			        or  not exists($$states[$$stack[-1][0]]{ACTIONS}{error})+					or	$$states[$$stack[-1][0]]{ACTIONS}{error} <= 0)) {++#DBG>			$debug & 0x10+#DBG>		and	print STDERR "**Pop state $$stack[-1][0].\n";++			pop(@$stack);+		}++			@$stack+		or	do {++#DBG>			$debug & 0x10+#DBG>		and	print STDERR "**No state left on stack: aborting.\n";++			return(undef);+		};++		#shift the error token++#DBG>			$debug & 0x10+#DBG>		and	print STDERR "**Shift \$error token and go to state ".+#DBG>						 $$states[$$stack[-1][0]]{ACTIONS}{error}.+#DBG>						 ".\n";++		push(@$stack, [ $$states[$$stack[-1][0]]{ACTIONS}{error}, undef ]);++    }++    #never reached+	croak("Error in driver logic. Please, report it as a BUG");++}#_Parse+#DO NOT remove comment++1;+
+ blib6/pugs/perl5/lib/Parse/Yapp/Grammar.pm view
@@ -0,0 +1,381 @@+#+# Module Parse::Yapp::Grammar+#+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.+# (see the pod text in Parse::Yapp module for use and distribution rights)+#+package Parse::Yapp::Grammar;+@ISA=qw( Parse::Yapp::Options );++require 5.004;++use Carp;+use strict;+use Parse::Yapp::Options;+use Parse::Yapp::Parse;++###############+# Constructor #+###############+sub new {+    my($class)=shift;+    my($values);++    my($self)=$class->SUPER::new(@_);++    my($parser)=new Parse::Yapp::Parse;++        defined($self->Option('input'))+    or  croak "No input grammar";++    $values = $parser->Parse($self->Option('input'));++    undef($parser);++    $$self{GRAMMAR}=_ReduceGrammar($values);++        ref($class)+    and $class=ref($class);++    bless($self, $class);+}++###########+# Methods #+###########+##########################+# Method To View Grammar #+##########################+sub ShowRules {+    my($self)=shift;+    my($rules)=$$self{GRAMMAR}{RULES};+    my($ruleno)=-1;+    my($text);++    for (@$rules) {+        my($lhs,$rhs)=@$_;++        $text.=++$ruleno.":\t".$lhs." -> ";+        if(@$rhs) {+            $text.=join(' ',map { $_ eq chr(0) ? '$end' : $_ } @$rhs);+        }+        else {+            $text.="/* empty */";+        }+        $text.="\n";+    }+    $text;+}++###########################+# Method To View Warnings #+###########################+sub Warnings {+    my($self)=shift;+    my($text);+    my($grammar)=$$self{GRAMMAR};++        exists($$grammar{UUTERM})+    and    do {+            $text="Unused terminals:\n\n";+            for (@{$$grammar{UUTERM}}) {+                $text.="\t$$_[0], declared line $$_[1]\n";    +            }+        $text.="\n";+        };+        exists($$grammar{UUNTERM})+    and    do {+            $text.="Useless non-terminals:\n\n";+            for (@{$$grammar{UUNTERM}}) {+                $text.="\t$$_[0], declared line $$_[1]\n";    +            }+        $text.="\n";+        };+        exists($$grammar{UURULES})+    and    do {+            $text.="Useless rules:\n\n";+            for (@{$$grammar{UURULES}}) {+                $text.="\t$$_[0] -> ".join(' ',@{$$_[1]})."\n";    +            }+        $text.="\n";+        };+    $text;+}++######################################+# Method to get summary about parser #+######################################+sub Summary {+    my($self)=shift;+    my($text);++    $text ="Number of rules         : ".+            scalar(@{$$self{GRAMMAR}{RULES}})."\n";+    $text.="Number of terminals     : ".+            scalar(keys(%{$$self{GRAMMAR}{TERM}}))."\n";+    $text.="Number of non-terminals : ".+            scalar(keys(%{$$self{GRAMMAR}{NTERM}}))."\n";+    $text;+}++###############################+# Method to Ouput rules table #+###############################+sub RulesTable {+    my($self)=shift;+    my($inputfile)=$self->Option('inputfile');+    my($linenums)=$self->Option('linenumbers');+    my($rules)=$$self{GRAMMAR}{RULES};+    my($ruleno);+    my($text);++        defined($inputfile)+    or  $inputfile = 'unkown';++    $text="[\n\t";++    $text.=join(",\n\t",+                map {+                    my($lhs,$rhs,$code)=@$_[0,1,3];+                    my($len)=scalar(@$rhs);+                    my($text);++                    $text.="[#Rule ".$ruleno++."\n\t\t '$lhs', $len,";+                    if($code) {+                        $text.= "\nsub".+                                (  $linenums+                                 ? qq(\n#line $$code[1] "$inputfile"\n)+                                 : " ").+                                "{$$code[0]}";+                    }+                    else {+                        $text.=' undef';+                    }+                    $text.="\n\t]";++                    $text;+                } @$rules);++    $text.="\n]";++    $text;+}++################################+# Methods to get HEAD and TAIL #+################################+sub Head {+    my($self)=shift;+    my($inputfile)=$self->Option('inputfile');+    my($linenums)=$self->Option('linenumbers');+    my($text);++        $$self{GRAMMAR}{HEAD}[0]+    or  return '';++        defined($inputfile)+    or  $inputfile = 'unkown';++    for (@{$$self{GRAMMAR}{HEAD}}) {+            $linenums+        and $text.=qq(#line $$_[1] "$inputfile"\n);+        $text.=$$_[0];+    }+    $text+}++sub Tail {+    my($self)=shift;+    my($inputfile)=$self->Option('inputfile');+    my($linenums)=$self->Option('linenumbers');+    my($text);++        $$self{GRAMMAR}{TAIL}[0]+    or  return '';++        defined($inputfile)+    or  $inputfile = 'unkown';++        $linenums+    and $text=qq(#line $$self{GRAMMAR}{TAIL}[1] "$inputfile"\n);+    $text.=$$self{GRAMMAR}{TAIL}[0];++    $text+}+++#################+# Private Stuff #+#################++sub _UsefulRules {+    my($rules,$nterm) = @_;+    my($ufrules,$ufnterm);+    my($done);++    $ufrules=pack('b'.@$rules);+    $ufnterm={};++    vec($ufrules,0,1)=1;    #start rules IS always useful++    RULE:+    for (1..$#$rules) { # Ignore start rule+        for my $sym (@{$$rules[$_][1]}) {+                exists($$nterm{$sym})+            and next RULE;+        }+        vec($ufrules,$_,1)=1;+        ++$$ufnterm{$$rules[$_][0]};+    }++    do {+        $done=1;++        RULE:+        for (grep { vec($ufrules,$_,1) == 0 } 1..$#$rules) {+            for my $sym (@{$$rules[$_][1]}) {+                    exists($$nterm{$sym})+                and not exists($$ufnterm{$sym})+                and next RULE;+            }+            vec($ufrules,$_,1)=1;+                exists($$ufnterm{$$rules[$_][0]})+            or  do {+                $done=0;+                ++$$ufnterm{$$rules[$_][0]};+            };+        }++    }until($done);++    ($ufrules,$ufnterm)++}#_UsefulRules++sub _Reachable {+    my($rules,$nterm,$term,$ufrules,$ufnterm)=@_;+    my($reachable);+    my(@fifo)=( 0 );++    $reachable={ '$start' => 1 }; #$start is always reachable++    while(@fifo) {+        my($ruleno)=shift(@fifo);++        for my $sym (@{$$rules[$ruleno][1]}) {++                exists($$term{$sym})+            and do {+                ++$$reachable{$sym};+                next;+            };++                (   not exists($$ufnterm{$sym})+                 or exists($$reachable{$sym}) )+            and next;++            ++$$reachable{$sym};+            push(@fifo, grep { vec($ufrules,$_,1) } @{$$nterm{$sym}});+        }+    }++    $reachable++}#_Reachable++sub _SetNullable {+    my($rules,$term,$nullable) = @_;+    my(@nrules);+    my($done);++    RULE:+    for (@$rules) {+        my($lhs,$rhs)=@$_;++            exists($$nullable{$lhs})+        and next;++        for (@$rhs) {+                exists($$term{$_})+            and next RULE;+        }+        push(@nrules,[$lhs,$rhs]);+    }++    do {+        $done=1;++        RULE:+        for (@nrules) {+            my($lhs,$rhs)=@$_;++                    exists($$nullable{$lhs})+                and next;++                for (@$rhs) {+                        exists($$nullable{$_})+                    or  next RULE;+                }+            $done=0;+            ++$$nullable{$lhs};+        }++    }until($done);+}++sub _ReduceGrammar {+    my($values)=@_;+    my($ufrules,$ufnterm,$reachable);+    my($grammar)={ HEAD => $values->{HEAD},+                   TAIL => $values->{TAIL},+                   EXPECT => $values->{EXPECT} };+    my($rules,$nterm,$term) =  @$values {'RULES', 'NTERM', 'TERM'};++    ($ufrules,$ufnterm) = _UsefulRules($rules,$nterm);++        exists($$ufnterm{$values->{START}})+    or  die "*Fatal* Start symbol $values->{START} derives nothing, at eof\n";++    $reachable = _Reachable($rules,$nterm,$term,$ufrules,$ufnterm);++    $$grammar{TERM}{chr(0)}=undef;+    for my $sym (keys %$term) {+            (   exists($$reachable{$sym})+             or exists($values->{PREC}{$sym}) )+        and do {+            $$grammar{TERM}{$sym}+                = defined($$term{$sym}[0]) ? $$term{$sym} : undef;+            next;+        };+        push(@{$$grammar{UUTERM}},[ $sym, $values->{SYMS}{$sym} ]);+    }++    $$grammar{NTERM}{'$start'}=[];+    for my $sym (keys %$nterm) {+            exists($$reachable{$sym})+        and do {+                exists($values->{NULL}{$sym})+            and ++$$grammar{NULLABLE}{$sym};+            $$grammar{NTERM}{$sym}=[];+            next;+        };+        push(@{$$grammar{UUNTERM}},[ $sym, $values->{SYMS}{$sym} ]);+    }++    for my $ruleno (0..$#$rules) {+            vec($ufrules,$ruleno,1)+        and exists($$grammar{NTERM}{$$rules[$ruleno][0]})+        and do {+            push(@{$$grammar{RULES}},$$rules[$ruleno]);+            push(@{$$grammar{NTERM}{$$rules[$ruleno][0]}},$#{$$grammar{RULES}});+            next;+        };+        push(@{$$grammar{UURULES}},[ @{$$rules[$ruleno]}[0,1] ]);+    }++    _SetNullable(@$grammar{'RULES', 'TERM', 'NULLABLE'});++    $grammar;+}#_ReduceGrammar++1;
+ blib6/pugs/perl5/lib/Parse/Yapp/Lalr.pm view
@@ -0,0 +1,939 @@+#+# Module Parse::Yapp::Lalr+#+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.+# (see the pod text in Parse::Yapp module for use and distribution rights)+#+package Parse::Yapp::Lalr;+@ISA=qw( Parse::Yapp::Grammar );++require 5.004;++use Parse::Yapp::Grammar;++=for nobody++Parse::Yapp::Compile Object Structure:+--------------------------------------+{+   GRAMMAR =>    Parse::Yapp::Grammar,+   STATES  =>    [ { CORE    => [ items... ],+                     ACTIONS  => { term => action }+                     GOTOS   => { nterm => stateno }+                   }... ]+   CONFLICTS=>{ SOLVED => { stateno  => [ ruleno, token, solved ] }, +                FORCED => { TOTAL => [ nbsr, nbrr ],+                            DETAIL => { stateno => { TOTAL => [ nbsr, nbrr ] }+                                                     LIST => [ ruleno, token ]+                                                   }+                                      }+                          } +}++'items' are of form: [ ruleno, dotpos ]+'term' in ACTIONS is '' means default action+'action' may be:+    undef:  explicit error (nonassociativity)+    0    :  accept+    >0   :  shift and go to state 'action'+    <0   :  reduce using rule -'action'+'solved' may have values of:+         'shift'  if solved as Shift+         'reduce' if solved as Reduce+         'error'  if solved by discarding both Shift and Reduce (nonassoc)++SOLVED is a set of states containing Solved conflicts+FORCED are forced conflict resolutions++nbsr and nbrr are number of shift/reduce and reduce/reduce conflicts++TOTAL is the total number of SR/RR conflicts for the parser++DETAIL is the detail of conflicts for each state+TOTAL is the total number of SR/RR conflicts for a state+LIST is the list of discarded reductions (for display purpose only)+++=cut++use strict;++use Carp;++###############+# Constructor #+###############+sub new {+    my($class)=shift;++		ref($class)+	and	$class=ref($class);++	my($self)=$class->SUPER::new(@_);+    $self->_Compile();+    bless($self,$class);+}+###########+# Methods #+###########++###########################+# Method To View Warnings #+###########################+sub Warnings {+    my($self)=shift;+    my($text);+    my($nbsr,$nbrr)=@{$$self{CONFLICTS}{FORCED}{TOTAL}};++	$text=$self->SUPER::Warnings();++        $nbsr != $$self{GRAMMAR}{EXPECT}+    and $text.="$nbsr shift/reduce conflict".($nbsr > 1 ? "s" : "");++        $nbrr+    and do {+            $nbsr+        and $text.=" and ";+        $text.="$nbrr reduce/reduce conflict".($nbrr > 1 ? "s" : "");+    };++       (    $nbsr != $$self{GRAMMAR}{EXPECT}+        or  $nbrr)+    and $text.="\n";++    $text;+}+#############################+# Method To View DFA States #+#############################+sub ShowDfa {+    my($self)=shift;+    my($text);+    my($grammar,$states)=($$self{GRAMMAR}, $$self{STATES});++    for my $stateno (0..$#$states) {+        my(@shifts,@reduces,@errors,$default);++        $text.="State $stateno:\n\n";++        #Dump Kernel Items+        for (sort {     $$a[0] <=> $$b[0]+                    or  $$a[1] <=> $$b[1] } @{$$states[$stateno]{'CORE'}}) {+            my($ruleno,$pos)=@$_;+            my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1];+            my(@rhscopy)=@$rhs;+        +                $ruleno+            or  $rhscopy[-1] = '$end';++            splice(@rhscopy,$pos,0,'.');+            $text.= "\t$lhs -> ".join(' ',@rhscopy)."\t(Rule $ruleno)\n";+        }++        #Prepare Actions+        for (keys(%{$$states[$stateno]{ACTIONS}})) {+            my($term,$action)=($_,$$states[$stateno]{ACTIONS}{$_});++                $term eq chr(0)+            and $term = '$end';++                not defined($action)+            and do {+                push(@errors,$term);+                next;+            };++                $action > 0+            and do {+                push(@shifts,[ $term, $action ]);+                next;+            };++            $action = -$action;++                $term+            or  do {+                $default= [ '$default', $action ];+                next;+            };++            push(@reduces,[ $term, $action ]);+        }++            #Dump shifts+            @shifts+        and do {+            $text.="\n";+            for (sort { $$a[0] cmp $$b[0] } @shifts) {+                my($term,$shift)=@$_;++                $text.="\t$term\tshift, and go to state $shift\n";+            }+        };++            #Dump errors+            @errors+        and do {+            $text.="\n";+            for my $term (sort { $a cmp $b } @errors) {+                $text.="\t$term\terror (nonassociative)\n";+            }+        };++        #Prepare reduces+            exists($$self{CONFLICTS}{FORCED}{DETAIL}{$stateno})+        and push(@reduces,@{$$self{CONFLICTS}{FORCED}{DETAIL}{$stateno}{LIST}});++        @reduces=sort { $$a[0] cmp $$b[0] or $$a[1] <=> $$b[1] } @reduces;++            defined($default)+        and push(@reduces,$default);++        #Dump reduces+            @reduces+        and do {+            $text.="\n";+            for (@reduces) {+                my($term,$ruleno)=@$_;+                my($discard);++                    $ruleno < 0+                and do {+                    ++$discard;+                    $ruleno = -$ruleno;+                };++                $text.= "\t$term\t".($discard  ? "[" : "");+                if($ruleno) {+                    $text.= "reduce using rule $ruleno ".+                            "($$grammar{RULES}[$ruleno][0])";+                }+                else {+                    $text.='accept';+                }+                $text.=($discard  ? "]" : "")."\n";+            }+        };++            #Dump gotos+            exists($$states[$stateno]{GOTOS})+        and    do {+                $text.= "\n";+                for (keys(%{$$states[$stateno]{GOTOS}})) {+                    $text.= "\t$_\tgo to state $$states[$stateno]{GOTOS}{$_}\n";+                }+            };++        $text.="\n";+    }+    $text;+}++######################################+# Method to get summary about parser #+######################################+sub Summary {+    my($self)=shift;+    my($text);++	$text=$self->SUPER::Summary();+    $text.="Number of states        : ".+            scalar(@{$$self{STATES}})."\n";+    $text;+}++#######################################+# Method To Get Infos about conflicts #+#######################################+sub Conflicts {+    my($self)=shift;+    my($states)=$$self{STATES};+    my($conflicts)=$$self{CONFLICTS};+    my($text);++    for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{SOLVED}})) {++        for (@{$$conflicts{SOLVED}{$stateno}}) {+            my($ruleno,$token,$how)=@$_;++                $token eq chr(0)+            and $token = '$end';++            $text.="Conflict in state $stateno between rule ".+                   "$ruleno and token $token resolved as $how.\n"; +        }+    };++    for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{FORCED}{DETAIL}})) {+        my($nbsr,$nbrr)=@{$$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}};++        $text.="State $stateno contains ";++            $nbsr+        and $text.="$nbsr shift/reduce conflict".+                   ($nbsr > 1 ? "s" : "");++            $nbrr+        and do {+                $nbsr+            and $text.=" and ";++            $text.="$nbrr reduce/reduce conflict".+                   ($nbrr > 1 ? "s" : "");+        };+        $text.="\n";+    };++    $text;+}++#################################+# Method to dump parsing tables #+#################################+sub DfaTable {+    my($self)=shift;+    my($states)=$$self{STATES};+    my($stateno);+    my($text);++    $text="[\n\t{";++    $text.=join("\n\t},\n\t{",+                map {+                    my($state)=$_;+                    my($text);++                    $text="#State ".$stateno++."\n\t\t";++                       (    not exists($$state{ACTIONS}{''})+                        or  keys(%{$$state{ACTIONS}}) > 1)+                    and do {++                        $text.="ACTIONS => {\n\t\t\t";++                        $text.=join(",\n\t\t\t",+                                map {+                                    my($term,$action)=($_,$$state{ACTIONS}{$_});+                                    my($text);++                                    if(substr($term,0,1) eq "'") {+									    $term=~s/([\@\$\"])/\\$1/g;+                                        $term=~s/^'|'$/"/g;+                                    }+                                    else {+                                        $term=      $term eq chr(0)+                                                ?   "''" +                                                :   "'$term'";+                                    }++                                    if(defined($action)) {+                                        $action=int($action);+                                    }+                                    else {+                                        $action='undef';+                                    }++                                    "$term => $action";+                                +                                } grep { $_ } keys(%{$$state{ACTIONS}}));++                        $text.="\n\t\t}";+                    };++                        exists($$state{ACTIONS}{''})+                    and do {+                            keys(%{$$state{ACTIONS}}) > 1+                        and $text.=",\n\t\t";++                        $text.="DEFAULT => $$state{ACTIONS}{''}";+                    };++                        exists($$state{GOTOS})+                    and do {+                        $text.=",\n\t\tGOTOS => {\n\t\t\t";+                        $text.=join(",\n\t\t\t",+                                map {+                                    my($nterm,$stateno)=($_,$$state{GOTOS}{$_});+                                    my($text);++                                    "'$nterm' => $stateno";+                                +                                } keys(%{$$state{GOTOS}}));+                        $text.="\n\t\t}";+                    };++                    $text;++                }@$states);++    $text.="\n\t}\n]";++    $text;++}+++####################################+# Method to build Dfa from Grammar #+####################################+sub _Compile {+	my($self)=shift;+	my($grammar,$states);++	$grammar=$self->{GRAMMAR};++    $states = _LR0($grammar);++    $self->{CONFLICTS} = _LALR($grammar,$states);++    $self->{STATES}=$states;+}++#########################+# LR0 States Generation #+#########################+#+###########################+# General digraph routine #+###########################+sub _Digraph {+    my($rel,$F)=@_;+    my(%N,@S);+    my($infinity)=(~(1<<31));+    my($Traverse);++    $Traverse = sub {+        my($x,$d)=@_;+        my($y);++        push(@S,$x);+        $N{$x}=$d;++            exists($$rel{$x})+        and do {+            for $y (keys(%{$$rel{$x}})) {+                    exists($N{$y})+                or  &$Traverse($y,$d+1);++                    $N{$y} < $N{$x}+                and $N{$x} = $N{$y};++                $$F{$x}|=$$F{$y};+            }+        };++            $N{$x} == $d+        and do {+            for(;;) {+                $y=pop(@S);+                $N{$y}=$infinity;+                    $y eq $x+                and last;+                $$F{$y}=$$F{$x};+            }+        };+    };++    for (keys(%$rel)) {+            exists($N{$_})+        or  &$Traverse($_,1);+    }+}+#######################+# Generate LR0 states # +#######################+=for nobody+Formula used for closures:++    CLOSE(A) = DCLOSE(A) u U (CLOSE(B) | A close B)++where:++    DCLOSE(A) = { [ A -> alpha ] in P }++    A close B iff [ A -> B gamma ] in P++=cut+sub _SetClosures {+	my($grammar)=@_;+    my($rel,$closures);++    for my $symbol (keys(%{$$grammar{NTERM}})) {+        $closures->{$symbol}=pack('b'.@{$$grammar{RULES}});++        for my $ruleno (@{$$grammar{NTERM}{$symbol}}) {+            my($rhs)=$$grammar{RULES}[$ruleno][1];++            vec($closures->{$symbol},$ruleno,1)=1;++                @$rhs > 0+            and exists($$grammar{NTERM}{$$rhs[0]})+            and ++$rel->{$symbol}{$$rhs[0]};+        }+    }+    _Digraph($rel,$closures);++	$closures+}++sub _Closures {+    my($grammar,$core,$closures)=@_;+    my($ruleset)=pack('b'.@{$$grammar{RULES}});++    for (@$core) {+        my($ruleno,$pos)=@$_;+        my($rhs)=$$grammar{RULES}[$ruleno][1];++            $pos < @$rhs+        and exists($closures->{$$rhs[$pos]})+        and $ruleset|=$closures->{$$rhs[$pos]};+    }+    [ @$core, map  { [ $_, 0 ] }+              grep { vec($ruleset,$_,1) }+              0..$#{$$grammar{RULES}} ];+}++sub _Transitions {+    my($grammar,$cores,$closures,$states,$stateno)=@_;+    my($core)=$$states[$stateno]{'CORE'};+    my(%transitions);++    for (@{_Closures($grammar,$core,$closures)}) {+        my($ruleno,$pos)=@$_;+        my($rhs)=$$grammar{RULES}[$ruleno][1];++            $pos == @$rhs+        and do {+            push(@{$$states[$stateno]{ACTIONS}{''}},$ruleno);+            next;+        };+        push(@{$transitions{$$rhs[$pos]}},[ $ruleno, $pos+1 ]);+    }++    for (keys(%transitions)) {+        my($symbol,$core)=($_,$transitions{$_});+        my($corekey)=join(',',map  { join('.',@$_) }+                              sort {    $$a[0] <=> $$b[0]+                                    or  $$a[1] <=> $$b[1] }+                              @$core);+        my($tostateno);++            exists($cores->{$corekey})+        or  do {+            push(@$states,{ 'CORE' => $core });+            $cores->{$corekey}=$#$states;+        };++        $tostateno=$cores->{$corekey};+        push(@{$$states[$tostateno]{FROM}},$stateno);++			exists($$grammar{TERM}{$_})+		and	do {+            $$states[$stateno]{ACTIONS}{$_} = [ $tostateno ];+			next;+		};+        $$states[$stateno]{GOTOS}{$_} = $tostateno;+    }+}++sub _LR0 {+	my($grammar)=@_;+	my($states) = [];+    my($stateno);+    my($closures);  #$closures={ nterm => ruleset,... }+	my($cores)={};  # { "itemlist" => stateno, ... }+					# where "itemlist" has the form:+					# "ruleno.pos,ruleno.pos" ordered by ruleno,pos++    $closures = _SetClosures($grammar);+    push(@$states,{ 'CORE' => [ [ 0, 0 ] ] });+    for($stateno=0;$stateno<@$states;++$stateno) {+        _Transitions($grammar,$cores,$closures,$states,$stateno);+    }++	$states+}++#########################################################+# Add Lookahead tokens where needed to make LALR states #+#########################################################+=for nobody+    Compute First sets for non-terminal using the following formula:++    FIRST(A) =      { a in T u { epsilon } | A l a }+                u+                U   { FIRST(B) | B in V and A l B }++    where:++    A l x iff [ A -> X1 X2 .. Xn x alpha ] in P and Xi =>* epsilon, 1 <= i <= n+=cut+sub _SetFirst {+	my($grammar,$termlst,$terminx)=@_;+    my($rel,$first)=( {}, {} );++    for my $symbol (keys(%{$$grammar{NTERM}})) {+        $first->{$symbol}=pack('b'.@$termlst);++        RULE:+        for my $ruleno (@{$$grammar{NTERM}{$symbol}}) {+            my($rhs)=$$grammar{RULES}[$ruleno][1];++            for (@$rhs) {+                    exists($terminx->{$_})+                and do {+                    vec($first->{$symbol},$terminx->{$_},1)=1;+                    next RULE;+                };+                ++$rel->{$symbol}{$_};+                    exists($$grammar{NULLABLE}{$_})+                or  next RULE;+            }+            vec($first->{$symbol},0,1)=1;+        }+    }+    _Digraph($rel,$first);++	$first+}++sub _Preds {+    my($states,$stateno,$len)=@_;+    my($queue, $preds);++        $len+    or  return [ $stateno ];++    $queue=[ [ $stateno, $len ] ];+    while(@$queue) {+        my($pred) = shift(@$queue);+        my($stateno, $len) = @$pred;++            $len == 1+        and do {+			push(@$preds,@{$states->[$stateno]{FROM}});+            next;+        };++        push(@$queue, map { [ $_, $len - 1 ] }+					  @{$states->[$stateno]{FROM}});+    }++    # Pass @$preds through a hash to ensure unicity+    [ keys( %{ +{ map { ($_,1) } @$preds } } ) ];+}++sub _FirstSfx {+    my($grammar,$firstset,$termlst,$terminx,$ruleno,$pos,$key)=@_;+    my($first)=pack('b'.@$termlst);+    my($rhs)=$$grammar{RULES}[$ruleno][1];++    for (;$pos < @$rhs;++$pos) {+            exists($terminx->{$$rhs[$pos]})+        and do {+            vec($first,$terminx->{$$rhs[$pos]},1)=1;+            return($first);+        };+        $first|=$firstset->{$$rhs[$pos]};++            vec($first,0,1)+        and vec($first,0,1)=0;++            exists($$grammar{NULLABLE}{$$rhs[$pos]})+        or  return($first);++    }+    vec($first,0,1)=1;+    $first;+}++=for noboby+    Compute Follow sets using following formula:++    FOLLOW(p,A) =       READ(p,A)+                    u+                    U   { FOLLOW(q,B) | (p,A) include (q,B)++    where:+ +    READ(p,A) = U { FIRST(beta) | [ A -> alpha A . beta ] in KERNEL(GOTO(p,A))+                  } - { epsilon }++    (p,a) include (q,B) iff [ B -> alpha A . beta ] in KERNEL(GOTO(p,A),+                            epsilon in FIRST(beta) and+                            q in PRED(p,alpha)+=cut+sub _ComputeFollows {+	my($grammar,$states,$termlst)=@_;+	my($firstset,$terminx);+	my($inconsistent, $rel, $follows, $sfx)= ( {}, {}, {}, {} );++    %$terminx= map { ($termlst->[$_],$_) } 0..$#$termlst;++    $firstset=_SetFirst($grammar,$termlst,$terminx);++    for my $stateno (0..$#$states) {+		my($state)=$$states[$stateno];++           	exists($$state{ACTIONS}{''})+        and (   @{$$state{ACTIONS}{''}} > 1+             or keys(%{$$state{ACTIONS}}) > 1 )+		and do {+			++$inconsistent->{$stateno};++			for my $ruleno (@{$$state{ACTIONS}{''}}) {+				my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1];++                for my $predno (@{_Preds($states,$stateno,scalar(@$rhs))}) {+                    ++$rel->{"$stateno.$ruleno"}{"$predno.$lhs"};+                }+			}+		};++    		exists($$state{GOTOS})+		or	next;++        for my $symbol (keys(%{$$state{GOTOS}})) {+            my($tostate)=$$states[$$state{GOTOS}{$symbol}];+            my($goto)="$stateno.$symbol";++            $follows->{$goto}=pack('b'.@$termlst);++            for my $item (@{$$tostate{'CORE'}}) {+                my($ruleno,$pos)=@$item;+				my($key)="$ruleno.$pos";++					exists($sfx->{$key})+				or	$sfx->{$key} = _FirstSfx($grammar,$firstset,+											 $termlst,$terminx,+											 $ruleno,$pos,$key);++                $follows->{$goto}|=$sfx->{$key};++                    vec($follows->{$goto},0,1)+                and do {+                    my($lhs)=$$grammar{RULES}[$ruleno][0];++                    vec($follows->{$goto},0,1)=0;++                    for my $predno (@{_Preds($states,$stateno,$pos-1)}) {+                        ++$rel->{$goto}{"$predno.$lhs"};+                    }+                };+            }+        }+    }+    _Digraph($rel,$follows);++	($follows,$inconsistent)+}++sub _ComputeLA {+	my($grammar,$states)=@_;+	my($termlst)= [ '',keys(%{$$grammar{TERM}}) ];++    my($follows,$inconsistent) = _ComputeFollows($grammar,$states,$termlst);++    for my $stateno ( keys(%$inconsistent ) ) {+        my($state)=$$states[$stateno];+        my($conflict);++        #NB the sort is VERY important for conflicts resolution order+        for my $ruleno (sort { $a <=> $b }+                        @{$$state{ACTIONS}{''}}) {+            for my $term ( map { $termlst->[$_] } grep {+                           vec($follows->{"$stateno.$ruleno"},$_,1) }+                           0..$#$termlst) {+                    exists($$state{ACTIONS}{$term})+                and ++$conflict;+                push(@{$$state{ACTIONS}{$term}},-$ruleno);+            }+        }+        delete($$state{ACTIONS}{''});+            $conflict+        or  delete($inconsistent->{$stateno});+    }++	$inconsistent+}++#############################+# Solve remaining conflicts #+#############################++sub _SolveConflicts {+	my($grammar,$states,$inconsistent)=@_;+    my(%rulesprec,$RulePrec);+    my($conflicts)={    SOLVED  =>  {},+                    	FORCED  =>  {   TOTAL   =>  [ 0, 0 ],+                                    	DETAIL  =>  {}+                                 	}+                };++    $RulePrec = sub {+        my($ruleno)=@_;+        my($rhs,$rprec)=@{$$grammar{RULES}[$ruleno]}[1,2];+        my($lastterm);++            defined($rprec)+        and return($rprec);++            exists($rulesprec{$ruleno})+        and return($rulesprec{$ruleno});++        $lastterm=(grep { exists($$grammar{TERM}{$_}) } @$rhs)[-1];++            defined($lastterm)+        and ref($$grammar{TERM}{$lastterm})+        and do {+            $rulesprec{$ruleno}=$$grammar{TERM}{$lastterm}[1];+            return($rulesprec{$ruleno});+        };++        undef;+    };++    for my $stateno (keys(%$inconsistent)) {+        my($state)=$$states[$stateno];+        my($actions)=$$state{ACTIONS};+        my($nbsr,$nbrr);++        for my $term ( keys(%$actions) ) {+            my($act)=$$actions{$term};++                @$act > 1+            or  next;++                $$act[0] > 0+            and ref($$grammar{TERM}{$term})+            and do {+                my($assoc,$tprec)=@{$$grammar{TERM}{$term}};+                my($k,$error);++                for ($k=1;$k<@$act;++$k) {+                    my($ruleno)=-$$act[$k];+                    my($rprec)=&$RulePrec($ruleno);++                        defined($rprec)+                    or  next;++                        (     $tprec > $rprec+                         or ( $tprec == $rprec and $assoc eq 'RIGHT'))+                    and do {+                        push(@{$$conflicts{SOLVED}{$stateno}},+                             [ $ruleno, $term, 'shift' ]);+                        splice(@$act,$k--,1);+                        next;+                    };+                        (   $tprec < $rprec+                         or $assoc eq 'LEFT')+                    and do {+                        push(@{$$conflicts{SOLVED}{$stateno}},+                             [ $ruleno, $term, 'reduce' ]);+                            $$act[0] > 0+                        and do {+                            splice(@$act,0,1);+                            --$k;+                        };+                        next;+                    };+                    push(@{$$conflicts{SOLVED}{$stateno}},+                         [ $ruleno, $term, 'error' ]);+                    splice(@$act,$k--,1);+                        $$act[0] > 0+                    and do {+                        splice(@$act,0,1);+                        ++$error;+                        --$k;+                    };+                }+                    $error+                and unshift(@$act,undef);+            };++                @$act > 1+            and do {+                $nbrr += @$act - 2;+                ($$act[0] > 0 ? $nbsr : $nbrr) += 1;+                push(@{$$conflicts{FORCED}{DETAIL}{$stateno}{LIST}},+                    map { [ $term, $_ ] } splice(@$act,1));+            };+        }++            $nbsr+        and do {+            $$conflicts{FORCED}{TOTAL}[0]+=$nbsr;+            $$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[0]+=$nbsr;+        };++            $nbrr+        and do {+            $$conflicts{FORCED}{TOTAL}[1]+=$nbrr;+            $$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[1]+=$nbrr;+        };++    }++	$conflicts+}++###############################+# Make default reduce actions #+###############################+sub _SetDefaults {+	my($states)=@_;++    for my $state (@$states) {+        my($actions)=$$state{ACTIONS};+        my(%reduces,$default,$nodefault);++            exists($$actions{''})+        and do {+            $$actions{''}[0] = -$$actions{''}[0];+			++$nodefault;+        };++		#shift error token => no default+            exists($$actions{error})+        and $$actions{error}[0] > 0+        and ++$nodefault;++        for my $term (keys(%$actions)) {++			$$actions{$term}=$$actions{$term}[0];++                (   not defined($$actions{$term})+                 or $$actions{$term} > 0+                 or $nodefault)+            and next;++            push(@{$reduces{$$actions{$term}}},$term);+        }++			keys(%reduces) > 0+		or	next;++        $default=( map { $$_[0] }+                   sort { $$b[1] <=> $$a[1] or $$b[0] <=> $$a[0] }+                   map { [ $_, scalar(@{$reduces{$_}}) ] }+                   keys(%reduces))[0];++        delete(@$actions{ @{$reduces{$default}} });+        $$state{ACTIONS}{''}=$default;+    }+}++sub _LALR {+	my($grammar,$states) = @_;+	my($conflicts,$inconsistent);++    $inconsistent = _ComputeLA($grammar,$states);++    $conflicts = _SolveConflicts($grammar,$states,$inconsistent);+    _SetDefaults($states);++	$conflicts+}+++1;
+ blib6/pugs/perl5/lib/Parse/Yapp/Options.pm view
@@ -0,0 +1,186 @@+#+# Module Parse::Yapp::Options+#+# (c) Copyright 1999-2001 Francois Desarmenien, all rights reserved.+# (see the pod text in Parse::Yapp module for use and distribution rights)+#+package Parse::Yapp::Options;++use strict;+use Carp;++############################################################################+#Definitions of options+#+# %known_options    allowed options+#+# %default_options  default+#+# %actions          sub refs to execute if option is set with ($self,$value)+#                   as parameters+############################################################################+#+#A value of '' means any value can do+#+my(%known_options)= (+    language    =>  {+        perl    => "Ouput parser for Perl language",+# for future use...+#       'c++'   =>  "Output parser for C++ language",+#       c       =>  "Output parser for C language"+    },+    linenumbers =>  {+        0       =>  "Don't embbed line numbers in parser",+        1       =>  "Embbed source line numbers in parser"+    },+    inputfile   =>  {+        ''      =>  "Input file name: will automagically fills input"+    },+    classname   =>  {+        ''      =>  "Class name of parser object (Perl and C++)"+    },+    standalone  =>  {+        0       =>  "Don't create a standalone parser (Perl and C++)",+        1       =>  "Create a standalone parser"+    },+    input       =>  {+        ''      =>  "Input text of grammar"+    },+    template    => {+        ''      =>  "Template text for generating grammar file"+    },+);++my(%default_options)= (+    language => 'perl',+    linenumbers => 1,+    inputfile => undef,+    classname   => 'Parser',+    standalone => 0,+    input => undef,+    template => undef,+    shebang => undef,+);++my(%actions)= (+    inputfile => \&__LoadFile+);++#############################################################################+#+# Actions+#+# These are NOT a method, although they look like...+#+# They are super-private routines (that's why I prepend __ to their names)+#+#############################################################################+sub __LoadFile {+    my($self,$filename)=@_;++        open(IN,"<$filename")+    or  croak "Cannot open input file '$filename' for reading";+    $self->{OPTIONS}{input}=join('',<IN>);+    close(IN);+}++#############################################################################+#+# Private methods+#+#############################################################################++sub _SetOption {+    my($self)=shift;+    my($key,$value)=@_;++    $key=lc($key);++        @_ == 2+    or  croak "Invalid number of arguments";++        exists($known_options{$key})+    or  croak "Unknown option: '$key'";++    if(exists($known_options{$key}{lc($value)})) {+        $value=lc($value);+    }+    elsif(not exists($known_options{$key}{''})) {+        croak "Invalid value '$value' for option '$key'";+    }++        exists($actions{$key})+    and &{$actions{$key}}($self,$value);++    $self->{OPTIONS}{$key}=$value;+}++sub _GetOption {+    my($self)=shift;+    my($key)=map { lc($_) } @_;++        @_ == 1+    or  croak "Invalid number of arguments";++        exists($known_options{$key})+    or  croak "Unknown option: '$key'";++    $self->{OPTIONS}{$key};+}++#############################################################################+#+# Public methods+#+#############################################################################++#+# Constructor+#+sub new {+    my($class)=shift;+    my($self)={ OPTIONS => { %default_options } };++        ref($class)+    and $class=ref($class);+    +    bless($self,$class);++    $self->Options(@_);++    $self;+}++#+# Specify one or more options to set+#+sub Options {+    my($self)=shift;+    my($key,$value);++        @_ % 2 == 0+    or  croak "Invalid number of arguments";++    while(($key,$value)=splice(@_,0,2)) {+        $self->_SetOption($key,$value);+    }+}++#+# Set (2 parameters) or Get (1 parameter) values for one option+#+sub Option {+    my($self)=shift;+    my($key,$value)=@_;++        @_ == 1+    and return $self->_GetOption($key);++        @_ == 2+    and return $self->_SetOption($key,$value);++    croak "Invalid number of arguments";++}++1;
+ blib6/pugs/perl5/lib/Parse/Yapp/Output.pm view
@@ -0,0 +1,92 @@+#+# Module Parse::Yapp::Output+#+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.+# (see the pod text in Parse::Yapp module for use and distribution rights)+#+package Parse::Yapp::Output;+@ISA=qw ( Parse::Yapp::Lalr );++require 5.004;++use Parse::Yapp::Lalr;+use Parse::Yapp::Driver;++use strict;++use Carp;++sub _CopyDriver {+	my($text)='#Included Parse/Yapp/Driver.pm file'.('-' x 40)."\n";+		open(DRV,$Parse::Yapp::Driver::FILENAME)+	or	die "BUG: could not open $Parse::Yapp::Driver::FILENAME";+	$text.="{\n".join('',<DRV>)."}\n";+	close(DRV);+	$text.='#End of include'.('-' x 50)."\n";+}++sub Output {+    my($self)=shift;++    $self->Options(@_);++    my($package)=$self->Option('classname');+    my($head,$states,$rules,$tail,$driver);+    my($version)=$Parse::Yapp::Driver::VERSION;+    my($datapos);+    my($text)=$self->Option('template') ||<<'EOT';+####################################################################+#+#    This file was generated using Parse::Yapp version <<$version>>.+#+#        Don't edit this file, use source file instead.+#+#             ANY CHANGE MADE HERE WILL BE LOST !+#+####################################################################+package <<$package>>;+use vars qw ( @ISA );+use strict;++@ISA= qw ( Parse::Yapp::Driver );+<<$driver>>++<<$head>>++sub new {+        my($class)=shift;+        ref($class)+    and $class=ref($class);++    my($self)=$class->SUPER::new( yyversion => '<<$version>>',+                                  yystates =>+<<$states>>,+                                  yyrules  =>+<<$rules>>,+                                  @_);+    bless($self,$class);+}++<<$tail>>+1;+EOT++	$driver='use Parse::Yapp::Driver;';++        defined($package)+    or $package='Parse::Yapp::Default';++	$head= $self->Head();+	$rules=$self->RulesTable();+	$states=$self->DfaTable();+	$tail= $self->Tail();++		$self->Option('standalone')+	and	$driver=_CopyDriver();++	$text=~s/<<(\$.+)>>/$1/gee;++	$text;+}++1;
+ blib6/pugs/perl5/lib/Parse/Yapp/Parse.pm view
@@ -0,0 +1,1093 @@+####################################################################+#+#    This file was generated using Parse::Yapp version 1.05.+#+#        Don't edit this file, use source file instead.+#+#             ANY CHANGE MADE HERE WILL BE LOST !+#+####################################################################+package Parse::Yapp::Parse;+use vars qw ( @ISA );+use strict;++@ISA= qw ( Parse::Yapp::Driver );+use Parse::Yapp::Driver;++#line 1 "YappParse.yp"+# (c) Copyright Francois Desarmenien 1998-2001, all rights reserved.+# (see COPYRIGHT in Parse::Yapp.pm pod section for use and distribution rights)+#+# Parse/Yapp/Parser.yp: Parse::Yapp::Parser.pm source file+#+# Use: yapp -m 'Parse::Yapp::Parse' -o Parse/Yapp/Parse.pm YappParse.yp+#+# to generate the Parser module.+# +#line 12 "YappParse.yp"++require 5.004;++use Carp;++my($input,$lexlevel,@lineno,$nberr,$prec,$labelno);+my($syms,$head,$tail,$token,$term,$nterm,$rules,$precterm,$start,$nullable);+my($expect);++++sub new {+        my($class)=shift;+        ref($class)+    and $class=ref($class);++    my($self)=$class->SUPER::new( yyversion => '1.05',+                                  yystates =>+[+	{#State 0+		ACTIONS => {+			"%%" => -6,+			'HEADCODE' => 3,+			'UNION' => 2,+			'TOKEN' => 5,+			'ASSOC' => 7,+			'START' => 6,+			'error' => 9,+			'TYPE' => 10,+			"\n" => 11,+			'EXPECT' => 13+		},+		GOTOS => {+			'head' => 1,+			'decls' => 12,+			'yapp' => 4,+			'decl' => 14,+			'headsec' => 8+		}+	},+	{#State 1+		ACTIONS => {+			'error' => 19,+			"%%" => 16,+			'IDENT' => 18+		},+		GOTOS => {+			'rules' => 15,+			'rulesec' => 20,+			'body' => 17+		}+	},+	{#State 2+		ACTIONS => {+			'CODE' => 21+		}+	},+	{#State 3+		ACTIONS => {+			"\n" => 22+		}+	},+	{#State 4+		ACTIONS => {+			'' => 23+		}+	},+	{#State 5+		ACTIONS => {+			"<" => 25+		},+		DEFAULT => -19,+		GOTOS => {+			'typedecl' => 24+		}+	},+	{#State 6+		ACTIONS => {+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 27+		}+	},+	{#State 7+		ACTIONS => {+			"<" => 25+		},+		DEFAULT => -19,+		GOTOS => {+			'typedecl' => 28+		}+	},+	{#State 8+		ACTIONS => {+			"%%" => 29+		}+	},+	{#State 9+		ACTIONS => {+			"\n" => 30+		}+	},+	{#State 10+		ACTIONS => {+			"<" => 25+		},+		DEFAULT => -19,+		GOTOS => {+			'typedecl' => 31+		}+	},+	{#State 11+		DEFAULT => -10+	},+	{#State 12+		ACTIONS => {+			"%%" => -7,+			'HEADCODE' => 3,+			'UNION' => 2,+			'TOKEN' => 5,+			'ASSOC' => 7,+			'START' => 6,+			'error' => 9,+			'TYPE' => 10,+			"\n" => 11,+			'EXPECT' => 13+		},+		GOTOS => {+			'decl' => 32+		}+	},+	{#State 13+		ACTIONS => {+			'NUMBER' => 33+		}+	},+	{#State 14+		DEFAULT => -9+	},+	{#State 15+		DEFAULT => -28+	},+	{#State 16+		DEFAULT => -26+	},+	{#State 17+		ACTIONS => {+			'TAILCODE' => 34+		},+		DEFAULT => -45,+		GOTOS => {+			'tail' => 35+		}+	},+	{#State 18+		ACTIONS => {+			":" => 36+		}+	},+	{#State 19+		ACTIONS => {+			";" => 37+		}+	},+	{#State 20+		ACTIONS => {+			'error' => 19,+			"%%" => 39,+			'IDENT' => 18+		},+		GOTOS => {+			'rules' => 38+		}+	},+	{#State 21+		ACTIONS => {+			"\n" => 40+		}+	},+	{#State 22+		DEFAULT => -14+	},+	{#State 23+		DEFAULT => -0+	},+	{#State 24+		ACTIONS => {+			'LITERAL' => 41,+			'IDENT' => 26+		},+		GOTOS => {+			'symlist' => 43,+			'ident' => 44,+			'symbol' => 42+		}+	},+	{#State 25+		ACTIONS => {+			'IDENT' => 45+		}+	},+	{#State 26+		DEFAULT => -4+	},+	{#State 27+		ACTIONS => {+			"\n" => 46+		}+	},+	{#State 28+		ACTIONS => {+			'LITERAL' => 41,+			'IDENT' => 26+		},+		GOTOS => {+			'symlist' => 47,+			'ident' => 44,+			'symbol' => 42+		}+	},+	{#State 29+		DEFAULT => -5+	},+	{#State 30+		DEFAULT => -18+	},+	{#State 31+		ACTIONS => {+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 48,+			'identlist' => 49+		}+	},+	{#State 32+		DEFAULT => -8+	},+	{#State 33+		ACTIONS => {+			"\n" => 50+		}+	},+	{#State 34+		DEFAULT => -46+	},+	{#State 35+		DEFAULT => -1+	},+	{#State 36+		ACTIONS => {+			'CODE' => 57,+			'LITERAL' => 41,+			'IDENT' => 26+		},+		DEFAULT => -35,+		GOTOS => {+			'rhselts' => 56,+			'rule' => 51,+			'code' => 52,+			'rhs' => 53,+			'ident' => 44,+			'rhselt' => 58,+			'rhss' => 55,+			'symbol' => 54+		}+	},+	{#State 37+		DEFAULT => -30+	},+	{#State 38+		DEFAULT => -27+	},+	{#State 39+		DEFAULT => -25+	},+	{#State 40+		DEFAULT => -15+	},+	{#State 41+		DEFAULT => -2+	},+	{#State 42+		DEFAULT => -22+	},+	{#State 43+		ACTIONS => {+			"\n" => 60,+			'LITERAL' => 41,+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 44,+			'symbol' => 59+		}+	},+	{#State 44+		DEFAULT => -3+	},+	{#State 45+		ACTIONS => {+			">" => 61+		}+	},+	{#State 46+		DEFAULT => -13+	},+	{#State 47+		ACTIONS => {+			"\n" => 62,+			'LITERAL' => 41,+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 44,+			'symbol' => 59+		}+	},+	{#State 48+		DEFAULT => -24+	},+	{#State 49+		ACTIONS => {+			"\n" => 63,+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 64+		}+	},+	{#State 50+		DEFAULT => -17+	},+	{#State 51+		DEFAULT => -32+	},+	{#State 52+		DEFAULT => -40+	},+	{#State 53+		ACTIONS => {+			'PREC' => 66+		},+		DEFAULT => -34,+		GOTOS => {+			'prec' => 65+		}+	},+	{#State 54+		DEFAULT => -39+	},+	{#State 55+		ACTIONS => {+			"|" => 68,+			";" => 67+		}+	},+	{#State 56+		ACTIONS => {+			'CODE' => 57,+			'LITERAL' => 41,+			'IDENT' => 26+		},+		DEFAULT => -36,+		GOTOS => {+			'code' => 52,+			'ident' => 44,+			'rhselt' => 69,+			'symbol' => 54+		}+	},+	{#State 57+		DEFAULT => -44+	},+	{#State 58+		DEFAULT => -38+	},+	{#State 59+		DEFAULT => -21+	},+	{#State 60+		DEFAULT => -11+	},+	{#State 61+		DEFAULT => -20+	},+	{#State 62+		DEFAULT => -12+	},+	{#State 63+		DEFAULT => -16+	},+	{#State 64+		DEFAULT => -23+	},+	{#State 65+		ACTIONS => {+			'CODE' => 57+		},+		DEFAULT => -42,+		GOTOS => {+			'code' => 70,+			'epscode' => 71+		}+	},+	{#State 66+		ACTIONS => {+			'LITERAL' => 41,+			'IDENT' => 26+		},+		GOTOS => {+			'ident' => 44,+			'symbol' => 72+		}+	},+	{#State 67+		DEFAULT => -29+	},+	{#State 68+		ACTIONS => {+			'CODE' => 57,+			'LITERAL' => 41,+			'IDENT' => 26+		},+		DEFAULT => -35,+		GOTOS => {+			'rhselts' => 56,+			'rule' => 73,+			'code' => 52,+			'rhs' => 53,+			'ident' => 44,+			'rhselt' => 58,+			'symbol' => 54+		}+	},+	{#State 69+		DEFAULT => -37+	},+	{#State 70+		DEFAULT => -43+	},+	{#State 71+		DEFAULT => -33+	},+	{#State 72+		DEFAULT => -41+	},+	{#State 73+		DEFAULT => -31+	}+],+                                  yyrules  =>+[+	[#Rule 0+		 '$start', 2, undef+	],+	[#Rule 1+		 'yapp', 3, undef+	],+	[#Rule 2+		 'symbol', 1,+sub+#line 30 "YappParse.yp"+{+                        exists($$syms{$_[1][0]})+                    or  do {+                        $$syms{$_[1][0]} = $_[1][1];+                        $$term{$_[1][0]} = undef;+                    };+                    $_[1]+                }+	],+	[#Rule 3+		 'symbol', 1, undef+	],+	[#Rule 4+		 'ident', 1,+sub+#line 41 "YappParse.yp"+{+                        exists($$syms{$_[1][0]})+                    or  do {+                        $$syms{$_[1][0]} = $_[1][1];+                        $$term{$_[1][0]} = undef;+                    };+                    $_[1]+                }+	],+	[#Rule 5+		 'head', 2, undef+	],+	[#Rule 6+		 'headsec', 0, undef+	],+	[#Rule 7+		 'headsec', 1, undef+	],+	[#Rule 8+		 'decls', 2, undef+	],+	[#Rule 9+		 'decls', 1, undef+	],+	[#Rule 10+		 'decl', 1, undef+	],+	[#Rule 11+		 'decl', 4,+sub+#line 66 "YappParse.yp"+{+                for (@{$_[3]}) {+                    my($symbol,$lineno)=@$_;++                        exists($$token{$symbol})+                    and do {+                        _SyntaxError(0,+                                "Token $symbol redefined: ".+                                "Previously defined line $$syms{$symbol}",+                                $lineno);+                        next;+                    };+                    $$token{$symbol}=$lineno;+                    $$term{$symbol} = [ ];+                }+                undef+            }+	],+	[#Rule 12+		 'decl', 4,+sub+#line 84 "YappParse.yp"+{+                for (@{$_[3]}) {+                    my($symbol,$lineno)=@$_;++                        defined($$term{$symbol}[0])+                    and do {+                        _SyntaxError(1,+                            "Precedence for symbol $symbol redefined: ".+                            "Previously defined line $$syms{$symbol}",+                            $lineno);+                        next;+                    };+                    $$token{$symbol}=$lineno;+                    $$term{$symbol} = [ $_[1][0], $prec ];+                }+                ++$prec;+                undef+            }+	],+	[#Rule 13+		 'decl', 3,+sub+#line 102 "YappParse.yp"+{ $start=$_[2][0]; undef }+	],+	[#Rule 14+		 'decl', 2,+sub+#line 103 "YappParse.yp"+{ push(@$head,$_[1]); undef }+	],+	[#Rule 15+		 'decl', 3,+sub+#line 104 "YappParse.yp"+{ undef }+	],+	[#Rule 16+		 'decl', 4,+sub+#line 106 "YappParse.yp"+{+                for ( @{$_[3]} ) {+                    my($symbol,$lineno)=@$_;++                        exists($$nterm{$symbol})+                    and do {+                        _SyntaxError(0,+                                "Non-terminal $symbol redefined: ".+                                "Previously defined line $$syms{$symbol}",+                                $lineno);+                        next;+                    };+                    delete($$term{$symbol});   #not a terminal+                    $$nterm{$symbol}=undef;    #is a non-terminal+                }+            }+	],+	[#Rule 17+		 'decl', 3,+sub+#line 122 "YappParse.yp"+{ $expect=$_[2][0]; undef }+	],+	[#Rule 18+		 'decl', 2,+sub+#line 123 "YappParse.yp"+{ $_[0]->YYErrok }+	],+	[#Rule 19+		 'typedecl', 0, undef+	],+	[#Rule 20+		 'typedecl', 3, undef+	],+	[#Rule 21+		 'symlist', 2,+sub+#line 130 "YappParse.yp"+{ push(@{$_[1]},$_[2]); $_[1] }+	],+	[#Rule 22+		 'symlist', 1,+sub+#line 131 "YappParse.yp"+{ [ $_[1] ] }+	],+	[#Rule 23+		 'identlist', 2,+sub+#line 134 "YappParse.yp"+{ push(@{$_[1]},$_[2]); $_[1] }+	],+	[#Rule 24+		 'identlist', 1,+sub+#line 135 "YappParse.yp"+{ [ $_[1] ] }+	],+	[#Rule 25+		 'body', 2,+sub+#line 140 "YappParse.yp"+{+                    $start+                or  $start=$$rules[1][0];++                    ref($$nterm{$start})+                or  _SyntaxError(2,"Start symbol $start not found ".+                                   "in rules section",$_[2][1]);++                $$rules[0]=[ '$start', [ $start, chr(0) ], undef, undef ];+            }+	],+	[#Rule 26+		 'body', 1,+sub+#line 150 "YappParse.yp"+{ _SyntaxError(2,"No rules in input grammar",$_[1][1]); }+	],+	[#Rule 27+		 'rulesec', 2, undef+	],+	[#Rule 28+		 'rulesec', 1, undef+	],+	[#Rule 29+		 'rules', 4,+sub+#line 157 "YappParse.yp"+{ _AddRules($_[1],$_[3]); undef }+	],+	[#Rule 30+		 'rules', 2,+sub+#line 158 "YappParse.yp"+{ $_[0]->YYErrok }+	],+	[#Rule 31+		 'rhss', 3,+sub+#line 161 "YappParse.yp"+{ push(@{$_[1]},$_[3]); $_[1] }+	],+	[#Rule 32+		 'rhss', 1,+sub+#line 162 "YappParse.yp"+{ [ $_[1] ] }+	],+	[#Rule 33+		 'rule', 3,+sub+#line 165 "YappParse.yp"+{ push(@{$_[1]}, $_[2], $_[3]); $_[1] }+	],+	[#Rule 34+		 'rule', 1,+sub+#line 166 "YappParse.yp"+{+                                my($code)=undef;++                                    defined($_[1])+                                and $_[1][-1][0] eq 'CODE'+                                and $code = ${pop(@{$_[1]})}[1];++                                push(@{$_[1]}, undef, $code);++                                $_[1]+                            }+	],+	[#Rule 35+		 'rhs', 0, undef+	],+	[#Rule 36+		 'rhs', 1, undef+	],+	[#Rule 37+		 'rhselts', 2,+sub+#line 183 "YappParse.yp"+{ push(@{$_[1]},$_[2]); $_[1] }+	],+	[#Rule 38+		 'rhselts', 1,+sub+#line 184 "YappParse.yp"+{ [ $_[1] ] }+	],+	[#Rule 39+		 'rhselt', 1,+sub+#line 187 "YappParse.yp"+{ [ 'SYMB', $_[1] ] }+	],+	[#Rule 40+		 'rhselt', 1,+sub+#line 188 "YappParse.yp"+{ [ 'CODE', $_[1] ] }+	],+	[#Rule 41+		 'prec', 2,+sub+#line 192 "YappParse.yp"+{+                       	defined($$term{$_[2][0]})+                    or  do {+                        _SyntaxError(1,"No precedence for symbol $_[2][0]",+                                         $_[2][1]);+                        return undef;+                    };++                    ++$$precterm{$_[2][0]};+                    $$term{$_[2][0]}[1];+				}+	],+	[#Rule 42+		 'epscode', 0,+sub+#line 205 "YappParse.yp"+{ undef }+	],+	[#Rule 43+		 'epscode', 1,+sub+#line 206 "YappParse.yp"+{ $_[1] }+	],+	[#Rule 44+		 'code', 1,+sub+#line 209 "YappParse.yp"+{ $_[1] }+	],+	[#Rule 45+		 'tail', 0, undef+	],+	[#Rule 46+		 'tail', 1,+sub+#line 215 "YappParse.yp"+{ $tail=$_[1] }+	]+],+                                  @_);+    bless($self,$class);+}++#line 218 "YappParse.yp"++sub _Error {+    my($value)=$_[0]->YYCurval;++    my($what)= $token ? "input: '$$value[0]'" : "end of input";++    _SyntaxError(1,"Unexpected $what",$$value[1]);+}++sub _Lexer {+ +    #At EOF+        pos($$input) >= length($$input)+    and return('',[ undef, -1 ]);++    #In TAIL section+        $lexlevel > 1+    and do {+        my($pos)=pos($$input);++        $lineno[0]=$lineno[1];+        $lineno[1]=-1;+        pos($$input)=length($$input);+        return('TAILCODE',[ substr($$input,$pos), $lineno[0] ]);+    };++    #Skip blanks+            $lexlevel == 0+        ?   $$input=~m{\G((?:+                                [\t\ ]+    # Any white space char but \n+                            |   \#[^\n]*  # Perl like comments+                            |   /\*.*?\*/ # C like comments+                            )+)}xsgc+        :   $$input=~m{\G((?:+                                \s+       # any white space char+                            |   \#[^\n]*  # Perl like comments+                            |   /\*.*?\*/ # C like comments+                            )+)}xsgc+    and do {+        my($blanks)=$1;++        #Maybe At EOF+            pos($$input) >= length($$input)+        and return('',[ undef, -1 ]);++        $lineno[1]+= $blanks=~tr/\n//;+    };++    $lineno[0]=$lineno[1];++        $$input=~/\G([A-Za-z_][A-Za-z0-9_]*)/gc+    and return('IDENT',[ $1, $lineno[0] ]);++        $$input=~/\G('(?:[^'\\]|\\\\|\\'|\\)+?')/gc+    and do {+            $1 eq "'error'"+        and do {+            _SyntaxError(0,"Literal 'error' ".+                           "will be treated as error token",$lineno[0]);+            return('IDENT',[ 'error', $lineno[0] ]);+        };+        return('LITERAL',[ $1, $lineno[0] ]);+    };++        $$input=~/\G(%%)/gc+    and do {+        ++$lexlevel;+        return($1, [ $1, $lineno[0] ]);+    };++        $$input=~/\G{/gc+    and do {+        my($level,$from,$code);++        $from=pos($$input);++        $level=1;+        while($$input=~/([{}])/gc) {+                substr($$input,pos($$input)-1,1) eq '\\' #Quoted+            and next;+                $level += ($1 eq '{' ? 1 : -1)+            or last;+        }+            $level+        and  _SyntaxError(2,"Unmatched { opened line $lineno[0]",-1);+        $code = substr($$input,$from,pos($$input)-$from-1);+        $lineno[1]+= $code=~tr/\n//;+        return('CODE',[ $code, $lineno[0] ]);+    };++    if($lexlevel == 0) {# In head section+            $$input=~/\G%(left|right|nonassoc)/gc+        and return('ASSOC',[ uc($1), $lineno[0] ]);+            $$input=~/\G%(start)/gc+        and return('START',[ undef, $lineno[0] ]);+            $$input=~/\G%(expect)/gc+        and return('EXPECT',[ undef, $lineno[0] ]);+            $$input=~/\G%{/gc+        and do {+            my($code);++                $$input=~/\G(.*?)%}/sgc+            or  _SyntaxError(2,"Unmatched %{ opened line $lineno[0]",-1);++            $code=$1;+            $lineno[1]+= $code=~tr/\n//;+            return('HEADCODE',[ $code, $lineno[0] ]);+        };+            $$input=~/\G%(token)/gc+        and return('TOKEN',[ undef, $lineno[0] ]);+            $$input=~/\G%(type)/gc+        and return('TYPE',[ undef, $lineno[0] ]);+            $$input=~/\G%(union)/gc+        and return('UNION',[ undef, $lineno[0] ]);+            $$input=~/\G([0-9]+)/gc+        and return('NUMBER',[ $1, $lineno[0] ]);++    }+    else {# In rule section+            $$input=~/\G%(prec)/gc+        and return('PREC',[ undef, $lineno[0] ]);+    }++    #Always return something+        $$input=~/\G(.)/sg+    or  die "Parse::Yapp::Grammar::Parse: Match (.) failed: report as a BUG";++        $1 eq "\n"+    and ++$lineno[1];++    ( $1 ,[ $1, $lineno[0] ]);++}++sub _SyntaxError {+    my($level,$message,$lineno)=@_;++    $message= "*".+              [ 'Warning', 'Error', 'Fatal' ]->[$level].+              "* $message, at ".+              ($lineno < 0 ? "eof" : "line $lineno").+              ".\n";++        $level > 1+    and die $message;++    warn $message;++        $level > 0+    and ++$nberr;++        $nberr == 20 +    and die "*Fatal* Too many errors detected.\n"+}++sub _AddRules {+    my($lhs,$lineno)=@{$_[0]};+    my($rhss)=$_[1];++        ref($$nterm{$lhs})+    and do {+        _SyntaxError(1,"Non-terminal $lhs redefined: ".+                       "Previously declared line $$syms{$lhs}",$lineno);+        return;+    };++        ref($$term{$lhs})+    and do {+        my($where) = exists($$token{$lhs}) ? $$token{$lhs} : $$syms{$lhs};+        _SyntaxError(1,"Non-terminal $lhs previously ".+                       "declared as token line $where",$lineno);+        return;+    };++        ref($$nterm{$lhs})      #declared through %type+    or  do {+            $$syms{$lhs}=$lineno;   #Say it's declared here+            delete($$term{$lhs});   #No more a terminal+    };+    $$nterm{$lhs}=[];       #It's a non-terminal now++    my($epsrules)=0;        #To issue a warning if more than one epsilon rule++    for my $rhs (@$rhss) {+        my($tmprule)=[ $lhs, [ ], splice(@$rhs,-2) ]; #Init rule++            @$rhs+        or  do {+            ++$$nullable{$lhs};+            ++$epsrules;+        };++        for (0..$#$rhs) {+            my($what,$value)=@{$$rhs[$_]};++                $what eq 'CODE'+            and do {+                my($name)='@'.++$labelno."-$_";+                push(@$rules,[ $name, [], undef, $value ]);+                push(@{$$tmprule[1]},$name);+                next;+            };+            push(@{$$tmprule[1]},$$value[0]);+        }+        push(@$rules,$tmprule);+        push(@{$$nterm{$lhs}},$#$rules);+    }++        $epsrules > 1+    and _SyntaxError(0,"More than one empty rule for symbol $lhs",$lineno);+}++sub Parse {+    my($self)=shift;++        @_ > 0+    or  croak("No input grammar\n");++    my($parsed)={};++    $input=\$_[0];++    $lexlevel=0;+    @lineno=(1,1);+    $nberr=0;+    $prec=0;+    $labelno=0;++    $head=();+    $tail="";++    $syms={};+    $token={};+    $term={};+    $nterm={};+    $rules=[ undef ];   #reserve slot 0 for start rule+    $precterm={};++    $start="";+    $nullable={};+    $expect=0;++    pos($$input)=0;+++    $self->YYParse(yylex => \&_Lexer, yyerror => \&_Error);++        $nberr+    and _SyntaxError(2,"Errors detected: No output",-1);++    @$parsed{ 'HEAD', 'TAIL', 'RULES', 'NTERM', 'TERM',+              'NULL', 'PREC', 'SYMS',  'START', 'EXPECT' }+    =       (  $head,  $tail,  $rules,  $nterm,  $term,+               $nullable, $precterm, $syms, $start, $expect);++    undef($input);+    undef($lexlevel);+    undef(@lineno);+    undef($nberr);+    undef($prec);+    undef($labelno);++    undef($head);+    undef($tail);++    undef($syms);+    undef($token);+    undef($term);+    undef($nterm);+    undef($rules);+    undef($precterm);++    undef($start);+    undef($nullable);+    undef($expect);++    $parsed+}+++1;
+ blib6/pugs/perl5/lib/Pugs/AST/Expression.pm view
@@ -0,0 +1,36 @@+package Pugs::AST::Expression;++use strict;+use warnings;+use Data::Dumper;++sub term {+    { term => $_[1]{'term'}->() ,}+}++sub operator {+    my $self = shift;+    my $match = shift;+    # die "not a match" unless ref($match) eq 'Pugs::Runtime::Match';+    my %h = %$match;+    my %opt = @_;+    +    #print "capture ", Dumper($match) if $opt{'fixity'} eq 'circumfix';+    for ( keys %h ) {+        $h{$_} = $h{$_}->();+    }+    my @a = @$match;+    if ( @a ) {+        $a = shift @a;+        for ( @$a ) {+            $_ = $self->operator( $_ );+            ${$_}{fixity} = $opt{fixity};+        }+        $h{list} = $a;+        delete $opt{fixity};+    }+    $h{$_} = $opt{$_} for keys %opt;+    return \%h;+}++1;
+ blib6/pugs/perl5/lib/Pugs/Compiler/Grammar.pm view
@@ -0,0 +1,120 @@+use strict;+use warnings;+#use Smart::Comments;++package Pugs::Compiler::Grammar;++our $VERSION = '0.28';++use Pugs::Grammar::Rule;+use Pugs::Emitter::Grammar::Perl5;+use Carp qw(carp croak);++sub compile {+    my ($class, $src, $opts) = @_;+    $opts ||= {};+    my $match = Pugs::Grammar::Rule->spec($src);+    if ($match->bool) {+        ## $match+        my $capture = $match->();+        my $leading_block = $capture->{block};+        ### leading block: $leading_block+        my $ast = $capture->{grammar};+        ## $ast+        my $perl5;+        for my $g (@$ast) {+            ### Grammar found...+            $g = $g->();+            my ($name) = keys %$g;+            ### Grammar: $name+            $perl5 .= Pugs::Emitter::Grammar::Perl5::emit($g, $opts);+        }+        bless {+            source => $src,+            ast => $ast,+            perl5 => $perl5,+        }, $class;+    } else {+        carp "Failed to compile the grammar source";+    }+}++sub perl5 {+    $_[0]->{perl5};+}++1;+__END__++=head1 NAME++Pugs::Compiler::Grammar - Compiler for Perl 6 Grammars++=head1 SYNOSPIS++    use Pugs::Compiler::Grammar;+    my $grammar = q{+        grammar MyC;++        token def {+            <type> <?ws> <var_list> <?ws>? ';'+        }++        token type { int | float | double | char }++        token var_list {+            <ident>**{1} <?ws>? [ ',' <?ws>? <ident> ]*+        }++        grammar MyVB;++        token def {+            'Dim' <?ws> <MyC.var_list>+            [ <?ws> 'As' <?ws> <MyC.type> ]? <?ws>? ';'+        }+    };+    my $obj = Pugs::Compiler::Grammar->compile($grammar);+    my $perl5 = $obj->perl5;+    eval $perl5; die $@ if $@;+    my $match = MyC->def("float foo;");+    print "type: ", $match->{type}, "\n";+    print "vars: ", $match->{var_list}, "\n";+    $match = MyVB->def("Dim foo, bar;");+    print "vars: ", $match->{'MyC.var_list'}, "\n";++=head1 METHODS++=over++=item C<< $obj = Pugs::Compile::Grammar->compile($src) >>++Acts as contructor. Accepts a string containing the grammar+specs and returns a Pugs::Compiler::Grammar instance.++=item C<< $perl5 = $obj->perl5() >>++Returns a string containing the Perl source for the grammars+compiled.++=back++=head1 AUTHOR++The Pugs contributors E<lt>perl6-compiler@perl.orgE<gt>.++=head1 COPYRIGHT++Copyright 2007 by Agent Zhang and others.++This program is free software; you can redistribute it+and/or modify it under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=head1 SEE ALSO++L<compile_p6grammar.pl>,+L<Pugs::Compiler::Regex>,+L<Pugs::Grammar::Rule>,+L<Pugs::Emitter::Grammar::Perl5>.+
+ blib6/pugs/perl5/lib/Pugs/Compiler/Regex.pm view
@@ -0,0 +1,506 @@+package Pugs::Compiler::Regex;++#use Smart::Comments;++our $VERSION = '0.28';+# Documentation in the __END__+use strict;+use warnings;++use Pugs::Grammar::Rule;+use Pugs::Compiler::RegexPerl5;++use Pugs::Emitter::Rule::Perl5;+use Pugs::Emitter::Rule::Perl5::Ratchet;++use Pugs::Runtime::Regex;++# complete the dependency circularity+push @Pugs::Grammar::Rule::ISA, 'Pugs::Grammar::Base';++use Carp qw( croak carp );+use Data::Dumper;+use Symbol 'qualify_to_ref';+use Digest::MD5 'md5_hex';++our $NoCache = $ENV{PCR_NO_CACHE}; # Depresses any caching if set to true++my $cache;+eval {+    require Cache::FileCache;+    $cache = new Cache::FileCache( { 'namespace' => 'v6-rules' } );+};++sub new { $_[0] }++sub compile {+    local $::_V6_MATCH_;  # avoid messing with global $/++    # $class->compile( $source )+    # $class->compile( $source, { p=>1 } )+    # $class->compile( $source, { signature => $sig } ) -- TODO++    my ( $class, $rule_source, $param ) = @_;++    return Pugs::Compiler::RegexPerl5->compile( $rule_source, $param )+        if exists $param->{P5} || exists $param->{Perl5};+    #warn length($rule_source);++    my $self = { source => $rule_source };++    #print Dumper @_;++    # XXX - should use user's lexical pad instead of an explicit grammar?+    $self->{grammar}  = delete $param->{grammar}  ||+                        'Pugs::Grammar::Base';+    $self->{ratchet}  = delete $param->{ratchet}  ||+                        0;++    $self->{p}        = delete $param->{pos}      ||+                        delete $param->{p};+                        # default = undef;+    delete $param->{p};++    $self->{sigspace} = delete $param->{sigspace} ||+                        delete $param->{s}        ||+                        0;+    delete $param->{s};++    $self->{continue} = delete $param->{continue} ||+                        delete $param->{c}        ||+                        0;+    delete $param->{c};++    $self->{ignorecase} = delete $param->{ignorecase} ||+                          delete $param->{i}        ||+                          0;+    delete $param->{i};++    my $error;+    $error .= "Error in rule: unknown parameter '$_'"+        for keys %$param;+    croak $error if %$param;++    my $digest = md5_hex(Dumper($self));+    my $cached;++    if (!$NoCache && $cache && ($cached = $cache->get($digest))) {+        ### using cached rule...+        $self->{perl5} = $cached;+    }+    else {+        ### compiling rule...++        #print 'rule source: ', $self->{source}, "\n";+        #print "match: ", Dumper( Pugs::Grammar::Rule->rule( $self->{source} ) );+        my $ast = Pugs::Grammar::Rule->rule(+            $self->{source} )->();+        if (!defined $ast) {+            carp "Invalid regex syntax";+            return undef;+        }+        ### rule AST: $ast++        # save the ast for debugging+        $self->{ast} = $ast;++        #warn "ast: ",Dumper($ast),"\n";+        #die "Error in rule: '$rule_source' at: '$ast->tail'\n" if $ast->tail;+        #print 'rule ast: ', do{use Data::Dumper; Dumper($ast{capture})};++        #use Pugs::Emitter::Rule::Perl5::Preprocess;+        #my $ast2 = Pugs::Emitter::Rule::Perl5::Preprocess::emit(+        #         $self->{grammar}, $ast, $self );++        if ( $self->{ratchet} ) {+            $self->{perl5} = Pugs::Emitter::Rule::Perl5::Ratchet::emit(+                 $self->{grammar}, $ast, $self );+            #print "token: ", $self->{perl5};+        }+        else {+            $self->{perl5} = Pugs::Emitter::Rule::Perl5::emit(+                $self->{grammar}, $ast, $self );+        }+        #print 'rule perl5: ', do{use Data::Dumper; Dumper($self->{perl5})};++        $cache->set($digest, $self->{perl5}, 'never') if $cache;+    }++    #our $evals++;++    local $@;+    $self->{code} = eval+        # "\#line " . ($evals*1000) . "\n" .+        $self->{perl5};+    die "Error in evaluation: $@\nSource:\n$self->{perl5}\n" if $@;++    #my $code = $self->{code};+    #my $e = $evals;+    #my $c = $self->{perl5};+    #my $x = 1;+    #$c =~ s/\n/"\n".++$x.": "/seg;+    #$self->{code} = sub { print "calling #$e <<< $rule_source >>> compiles to <<< $c >>>\n"; $code->(@_); };++    bless $self, $class;+}++sub code {+    my $rule = shift;+    sub {+        $rule->match( $_[1], $_[0], $_[2], $_[3] );+    }+}++sub match {+    my ( $rule, $str, $grammar, $flags, $state ) = @_;++    #print "match: ",Dumper($rule);+    #print "match: ",Dumper(\@_);+    #print "PCR::match: ",Dumper($_[2]);++    return Pugs::Runtime::Match->new( { bool => \0 } )+        unless defined $str;   # XXX - fix?++    if ( ref $grammar eq 'HASH' ) {+        # backwards compatibility - grammar can now be specified in $flags+        $state = $flags;+        $flags = $grammar;+        $grammar = $flags->{grammar};+    }++    $grammar ||= $rule->{grammar};+    #print "match: grammar $rule->{grammar}, $_[0], $flags\n";+    #print "match: Variables: ", Dumper ( $flags->{args} ) if defined $flags->{args};+    #print "match: Flags: ", Dumper ( $flags ) if defined $flags;++    my $p = defined $flags->{p}+            ? $flags->{p}+            : defined $flags->{pos}+            ? $flags->{pos}+            : $rule->{p};++    my $continue = defined $flags->{c}+            ? $flags->{c}+            : defined $flags->{continue}+            ? $flags->{continue}+            : $rule->{continue};++    my $ignorecase = defined $flags->{i}+            ? $flags->{i}+            : defined $flags->{ignorecase}+            ? $flags->{ignorecase}+            : $rule->{ignorecase};++        #print "flag p";+        #print "match: grammar $rule->{grammar}, $str, %$flags\n";+        #print $rule->{code};++        # XXX BUG! - $rule->{code} disappeared - in t/08-hash.t ???+        unless ( defined $rule->{code} ) {+            local $@;+            if (!defined $rule->{perl5}) {+                croak "Error in evaluation: \$rule->{perl5} is missing";+            }+            $rule->{code} = eval+                $rule->{perl5};+            croak "Error in evaluation: $@\nSource:\n$rule->{perl5}" if $@;+        }++        my %args;+        %args = %{$flags->{args}} if defined $flags && defined $flags->{args};+        $args{p} = $p;+        $args{continue} = $continue;+        $args{ignorecase} = $ignorecase;++        #print "calling code with ",Dumper([ $grammar,$str, $state,\%args ] );+        my $match = $rule->{code}(+            $grammar,+            $_[1], # pass $str itself instead of a copy so as to make pos work+            $state,+            \%args,+        );+        #print __PACKAGE__ . ": match result: ", $match->perl;+        return $match;+}++sub reinstall {+    _install(0, scalar(caller), @_);+}++sub install {+    _install(1, scalar(caller), @_);+}++sub _install {+  my($check, $caller, $class, $name, @etc) = @_;++  # If we have a fully qualified name, use that, otherwise extrapolate.+  my $rule = index($name, '::') > -1 ? $name : $caller."::$name";+  my $slot = qualify_to_ref($rule);++  croak "Can't install regex '$name' as '$rule' which already exists"+    if $check && *$slot{CODE};++  eval {+      no warnings 'redefine';+      *$slot = $class->compile(@etc)->code;+  };+  warn $@ if $@;+}++sub _str { defined $_[0] ? $_[0] : 'undef' }+sub _quot {+    my $s = $_[0];+    $s =~ s/\\/\\\\/sg;+    return $s;+}++sub perl5 {+    my $self = shift;+    return "bless {\n" .+        "  grammar "  .  "=> q(" . _str( $self->{grammar} )  . "),\n" .+        "  ratchet "  .  "=> q(" . _str( $self->{ratchet} )  . "),\n" .+        "  p "        .  "=> " . _str( $self->{p} )        . ",\n" .+        "  sigspace " .  "=> q(" . _str( $self->{sigspace} ) . "),\n" .+        "  ignorecase ". "=> q(" . _str( $self->{ignorecase} )."),\n" .+        "  code "     .  "=> "   . $self->{perl5}    . ",\n" .+        "  perl5 "    .  "=> q(" . _quot( $self->{perl5} )  . "), }, " .+        "q(" . ref($self) . ")";+}++sub perl { perl5(@_) }++1;++__END__++=head1 NAME++Pugs::Compiler::Regex - Compiler for Perl 6 Regex++=head1 SYNOPSIS++    use Pugs::Compiler::Regex;+    use Pugs::Runtime::Match;++    $regex = Pugs::Compiler::Regex->compile('a*b');+    $match = $regex->match('aaab');+    print $match->(), "\n";+    print $match->from, "\n";+    print $match->to, "\n";++    package MyGrammar;+    $regex = Pugs::Compiler::Regex->compile(+        'a*', { ratchet => 1, continue => 1, sigspace => 1 }+    );+    *my_match = $regex->code();+    $match = MyGrammar->my_match('aaaa');+    print "$match\n";++    package MyGrammar2;+    $regex = Pugs::Compiler::Regex->install(+        my_match => 'a*',+        { ratchet => 1, continue => 1, sigspace => 1 }+    );+    $match = MyGrammar->my_match('aaaa');+    print "$match\n";++=head1 DESCRIPTION++This class provides an implementation for Perl 6 regexes.+It serves as a base class for L<Pugs::Compiler::Rule> and+L<Pugs::Compiler::Token>.++=head1 METHODS++=over++=item C<< $regex = Pugs::Compiler::Regex->compile($str, $params); >>++This method acts like a constructor, which returns a+L<Pugs::Compiler::Regex> object from the p6 regex+specified in C<$str>, or throws an exception on+invalid rule syntax.++C<$params> is an optional argument which specifies the+following p6 regex modifiers:++=over++=item C<< grammar => 'Pugs::Grammar::Base' >>++Specify which namespace (Grammar) the rule belongs to.+if C<grammar> is not specified, then C<"Pugs::Grammar::Base"> will+be assumed.++=item C<< continue => 0 >>++=item C<< c => 0 >>++These modifiers cause the pattern to continue+scanning from the string's current C<pos>:++Note that in Perl 6 form++    m:c/pattern/++is roughlh equivalent to++    m:p/ .*? pattern /++Here is an example:++    package Foo;+    Pugs::Compiler::Regex->install(+        word => '\w+',+        { ratchet => 1, continue => 1 }+    );+    $s = 'hello world';+    $match = Foo->word($s); # got 'hello'+    $match = Foo->word($s); # got 'world'++XXX Note that C<continue> or C<c> currently are+not supported in non-ratchet mode.++=item C<< ratchet => 0 >>++Disable backtracking. Much faster. Defaults to 0.+(L<Pugs::Compiler::Rule> and+L<Pugs::Compiler::Token> have the default+value of 1).++=item C<< pos => undef >>++=item C<< p => undef >>++Specify a string position to match. Starts from zero.+Defaults to C<undef>, which matches anywhere in the string.++=item C<< sigspace => 0 >>++Whitespace is significant. Defaults to 0 for+L<Pugs::Compiler::Regex> while 1 for+L<Pugs::Compiler::Rule>.++=item C<< ignorecase => 0 >>++Ignore character case. Defaults to 0 for+L<Pugs::Compiler::Regex>.++=back++=item C<< $regex->perl5() >>++=item C<< $regex->perl() >>++Return a string holding the Perl 5 code for reconstructing+the current L<Pugs::Compiler::Regex> object.++We are trying to make the C<perl5> method does something+like serializing a L<Pugs::Compiler::Regex> instance.++If you want the raw Perl 5 code generated by the+various emitters, use C<< $regex->{perl5} >> directly.++=item C<< $regex->match($str, $grammar, $params) >>++Performs matching action on C<$str>. Note that it's+a thin wrapper around the p5 code compiled from the p6+regex with run-time modifier handling via the C<$params>+argument.++Here is an example:++    $regex = Pugs::Compiler::regex->compile('a*\w');+    my $match = $regex->match('aaa');+    print "Capture: $match";+    print "From: ", $match->from;+    print "To: ", $match->to;++=item C<< $regex->code() >>++Returns a closure (or an anonymous sub) which does the actual+matching task. For example:++  $regex = Pugs::Compiler::Regex->compile('a|b', { ratchet => 1 });+  my $sub = $regex->code();+  my $match = $sub->('MyGrammar', 'aaa');++Or inserts the sub into the current package:++  package Foo;+  $regex = Pugs::Compiler::Regex->compile('a*');+  *match = $regex->code();+  my $match = __PACKAGE__->match('aaa');++Technically it's a thin wrapper around the C<match> method.++=item C<< $regex->install($name, @args_for_compile) >>++Installs the subroutine returned from the C<code> method as+a named subroutine using the name specified by C<$name>;++If C<$name> is fully qualified, then the corresponding+package is used, otherwise the current package is assumed.++C<@args_for_compile> are those arguments fed into the C<compile>+method.++It will croak if there's already a sub with the same name+exists. If that's not what you want, use the C<reinstall>+method instead.++Here are some examples:++  package Bar;+  Pugs::Compiler::Regex->install(match => 'a*', {ratchet => 1});+  $match = Bar->match('aaa');++  # The following line dies with the message+  # "Can't install regex 'match' as 'Bar::match' which already+  # exists":+  Pugs::Compiler::Regex->install(match => 'b*');++=item C<< $regex->reinstall($name, @args_for_compile) >>++Like the C<install> method but it can replaces the named sub+if it already exists:++  package Bar;+  Pugs::Compiler::Regex->install('match', 'a*', {ratchet => 1});+  Pugs::Compiler::Regex->reinstall('match', 'b*');+  };+  $match = Bar->match('bbb'); # matched here++=back++=head1 PACKAGE VARIABLES++=over++=item C<< $Pugs::Compiler::Regex::NoCache >>++By default, the C<compile> method will cache the compiled+form (p5 source) of the p6 regex. The C<NoCache> variable+prevents any caching.++=back++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 SEE ALSO++The Perl 6 Rules Spec: L<http://dev.perl.org/perl6/doc/design/syn/S05.html>++=head1 COPYRIGHT++Copyright 2006 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut
+ blib6/pugs/perl5/lib/Pugs/Compiler/RegexPerl5.pm view
@@ -0,0 +1,123 @@+package Pugs::Compiler::RegexPerl5;++# Version in Pugs::Compiler::Rule+# Documentation in the __END__+use 5.006;+use strict;+use warnings;++#use base 'Pugs::Compiler::Regex';++#use Pugs::Compiler::Regex;+#sub code { (+shift)->Pugs::Compiler::Regex::code( @_ ) }++# http://www.foo.be/docs/tpj/issues/vol2_3/tpj0203-0002.html+# is a good reference on the use of pos()++sub compile {+    my ( $class, $rule_source, $param ) = @_;+    my $self = { source => $rule_source };+    $param = ref $param ? { %$param } : {}; +    delete $param->{P5};+    delete $param->{Perl5};+    $self->{continue} = delete $param->{continue} ||+                        delete $param->{c}        || +                        0;+    warn "Error in rule: unknown parameter '$_'" +        for keys %$param;+        +    # TODO - set "prior"+        +    my $captures = q'+      for ( 1 .. $#+ ) {+        push @match, Pugs::Runtime::Match->new({+          str => $_[1], from => \\(0+$-[$_]), to => \\(0+$+[$_]),+          bool => \\1, match => [], named => {}, capture => undef,+        });+      }+      ' . +      #print "POS $bool ",(0+$-[0]),"-",(0+$+[0]),"\n";select(undef, undef, undef, 0.1);+      'return Pugs::Runtime::Match->new({+        str => $_[1], from => \\(0+$-[0]), to => \\(0+$+[0]),+        bool => \\$bool, match => \\@match, named => {}, capture => undef,+      });+      ';+    $self->{perl5} = +q(do {+  my $rule; +  $rule = sub { # grammar, string, state, args+  no warnings 'uninitialized';+  my $bool;+  my @match;+  +  return $rule->($_[0], \\$_[1], $_[2], $_[3])+    unless ref( $_[1] );  # backwards compatibility+  +  #print "POS ${$_[1]} ",pos(${$_[1]}),"\n";+  #print "p5 $_[3]{p} \n";+  +  if( $_[3]{continue} ) {+    pos(${$_[1]}) = $_[3]{p}+      if defined $_[3]{p};+    $bool = \( ${$_[1]} =~ /) . $rule_source . q(/g \) ? 1 : 0; ) . +    $captures . q(+  }+  +  if ( defined $_[3]{p} ) {+      pos(${$_[1]}) = $_[3]{p};+      $bool = \( ${$_[1]} =~ /\G\(?:) . $rule_source . q(\)/ \) ? 1 : 0; ) . +      $captures . q(+  }+  else {+      $bool = \( ${$_[1]} =~ /) . $rule_source . q(/ \) ? 1 : 0; ) . +      $captures . q(+  }+};+}+);+    # print 'rule perl5: ', do{use Data::Dumper; Dumper($self->{perl5})};++    local $@;+    $self->{code} = eval +        $self->{perl5};+    die "Error in evaluation: $@\nSource:\n$self->{perl5}\n" if $@;++    bless $self, 'Pugs::Compiler::Regex';+}++1;++__END__++=head1 NAME ++Pugs::Compiler::RegexPerl5 - Compiler for Perl 6 style "Perl5" regex++=head1 DESCRIPTION++This module provides an implementation for Perl 6 regexes that use the "Perl5" switch:++    :Perl5 /.*/++    :P5 /.*/++See L<Pugs::Compiler::Rule> for documentation.++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 SEE ALSO++The Perl 6 Rules Spec: L<http://dev.perl.org/perl6/doc/design/syn/S05.html>++=head1 COPYRIGHT++Copyright 2006 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut
+ blib6/pugs/perl5/lib/Pugs/Compiler/Rule.pm view
@@ -0,0 +1,219 @@+use 5.006001;+use strict;+use warnings;++package Pugs::Compiler::Rule;++our $VERSION = '0.28';++use base 'Pugs::Compiler::Regex';++sub compile {+    my ( $class, $rule_source, $param ) = @_;+    $param = ref $param ? { %$param } : {};+    $param->{ratchet} = 1+        unless exists $param->{ratchet};+    $param->{sigspace} = 1+        unless exists $param->{sigspace} ||+               exists $param->{s};+    $class->SUPER::compile( $rule_source, $param );+}++1;+__END__++=head1 NAME++Pugs::Compiler::Rule - Compiler for Perl 6 regexes++=head1 VERSION++This document describes Pugs::Compiler::Rule 0.28 released+on 31 Oct, 2007.++=head1 SYNOPSIS++Un-named rules are objects:++    use Pugs::Compiler::Rule;++    my $rule = Pugs::Compiler::Rule->compile( '((.).).' );+    my $match = $rule->match( 'abc' );++    if ($match) {               # true+        print $match;           # "abc"+        print $match->from;     # 0+        print $match->to;       # 3+        print $match->[0];      # "ab"+        print $match->[0][0];   # "a"+    }++Named rules are methods in a Grammar:++    package MyGrammar;+    use Pugs::Compiler::Rule;+    use base 'Pugs::Grammar::Base';++    Pugs::Compiler::Rule->install( rule => '((.).).' );+    my $match = MyGrammar->rule( 'abc' );++Rules may have parameters:++    $grammar->install(subrule => $source, { signature => $sig } );++    $grammar->install(rule => q{+            <subrule: param1, param2>+    });++where C<$grammar> is normally a Perl 5 package.++=head1 DESCRIPTION++This module provides an pure Perl 5 implementation for Perl 6 regexes,+which does not depend on the Haskell Pugs.++It is a front-end to several other modules:++Front-end Modules++=over 4++=item * L<Pugs::Compiler::Grammar> compiles Perl 6 grammars to Perl 5.++=item * L<Pugs::Compiler::Rule> compiles Perl 6 rules to Perl 5.++=item * L<Pugs::Compiler::Token> compiles Perl 6 tokens to Perl 5.++=item * L<Pugs::Compiler::Regex> compiles Perl 6 regexes to Perl 5.++=item * L<Pugs::Compiler::RegexPerl5> wraps Perl 5 regexes to return a B<Match> object.++=back++Runtime Classes++=over 4++=item * L<Pugs::Runtime::Rule> provides the runtime engine for Rules.++=item * L<Pugs::Runtime::Match> represents a B<Match> object.++=item * L<Pugs::Runtime::Grammar> represents a B<Grammar> class / object.++=back++Grammars++=over 4++=item * L<Pugs::Grammar::Rule> parses the Rules syntax.++=item * L<Pugs::Grammar::Base> is the base Grammar: <ws>, <space>.++=back++Code Emitters++=over 4++=item * L<Pugs::Emitter::Rule::Perl5> converts parsed Rules to Perl 5 code.++=item * L<Pugs::Emitter::Rule::Perl5::Ratchet> converts parsed :ratchet Rules to Perl 5 code.++=item * L<Pugs::Emitter::Grammar::Perl5> converts parsed grammars to Perl 5 code.++=back++=head1 INHERITANCE++  Pugs::Compiler::Rule+     isa Pugs::Compiler::Regex++=head1 METHODS++This class (i.e. L<Pugs::Compiler::Rule>) is a+subclass of L<Pugs::Compiler::Regex> and thus owns+all the methods of its base class. See+L<Pugs::Compiler::Regex> for the detailed docs.++=over++=item C<< $rule = Pugs::Compiler::Rule->compile($p6_regex, $params) >>++Specifically, this class overrides the C<compile>+method of L<Pugs::Compiler::Regex> which resets+the following options' default values:++=over++=item C<< ratchet => 1 >>++Here is an example:++    $rule = Pugs::Compiler::Rule->compile(+        'a*\w',+    );+    my $match = $rule->match('aaa');+    # $match->bool is false since no backtracking+    # happened++=item C<< sigspace => 1 >>++Here is an example:++    my $rule = Pugs::Compiler::Rule->compile(+        'a b',+    );+    my $match = $rule->match('a     b');+    ok $match->bool, 'sigspace works';+    is $match->(), 'a     b', 'sigspace works (2)';++=back++=back++=head1 CAVEATS++This is an experimental development version. The API is still in flux.++The set of implemented features depend on the C<ratchet> switch.++=head1 AUTHORS++The Pugs Team C<< <perl6-compiler@perl.org> >>.++Please join us on irc.freenode.net C<#perl6> if you'd like to participate.++=head1 SEE ALSO++=over++=item *++L<Pugs::Compiler::Regex>++=item *++L<Pugs::Compiler::Grammar>++=item *++L<compile_p6grammar.pl>++=item *++The Perl 6 Rules Spec: L<http://perlcabal.org/syn/S05.html>++=back++=head1 COPYRIGHT++Copyright 2006, 2007 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut+
+ blib6/pugs/perl5/lib/Pugs/Compiler/Token.pm view
@@ -0,0 +1,48 @@+package Pugs::Compiler::Token;++our $VERSION = '0.28';++use strict;+use warnings;++use base 'Pugs::Compiler::Regex';++sub compile {+    my ( $class, $rule_source, $param ) = @_;+    $param = ref $param ? { %$param } : {}; +    $param->{ratchet} = 1 +        unless defined $param->{ratchet};+    $class->SUPER::compile( $rule_source, $param );   +}++1;++__END__++=head1 NAME ++Pugs::Compiler::Token - Compiler for Perl 6 Token++=head1 DESCRIPTION++This module provides an implementation for Perl 6 Token.+See L<Pugs::Compiler::Rule> for documentation.++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 SEE ALSO++The Perl 6 Rules Spec: L<http://dev.perl.org/perl6/doc/design/syn/S05.html>++=head1 COPYRIGHT++Copyright 2006 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut
+ blib6/pugs/perl5/lib/Pugs/Emitter/Grammar/Perl5.pm view
@@ -0,0 +1,169 @@+package Pugs::Emitter::Grammar::Perl5;++our $VERSION = '0.28';++#use Smart::Comments;+use strict;+use warnings;+use Pugs::Emitter::Rule::Perl5::Ratchet;++# for safe mode+sub _prune_actions {+    my ($ast) = @_;+    while (my ($key, $node) = each %$ast) {+        next if $key =~ /^_/ or !ref $node;+        #warn $key;+        if ($key eq 'closure') {+            #die "Found closures!";+            next if ref $node ne 'HASH';+            my $code = $node->{closure};+            if ($code and !ref $code and $code =~ /\w+/) {+                die "ERROR: code blocks not allowed in safe mode: \"$code\"\n";+            }+        }+        if (ref $node) {+            my $ref = ref $node;+            if ($ref eq 'HASH') {+                _prune_actions($node); +            } elsif ($ref eq 'ARRAY') {+                for my $child (@$node) {+                    if (ref $child and ref $child eq 'HASH') {+                        _prune_actions($child);+                    }+                }+            }+        }+    }+}++sub emit {+    my $ast = shift;+    my $opts = shift;+    $opts ||= {};+    ## $ast+    my ($name, $stmts) = each %$ast;+    my $p5_methods = '';+    ### $name+    for my $stmt (@$stmts) {+        my $regex = $stmt->();+        my $type = $regex->{type};+        ## $regex+        if ($type eq 'block') {+            my $code = $regex->{value};+            if ($opts->{safe_mode} && $code =~ /\w+/) {+                die "ERROR: verbatim Perl 5 blocks not allowed in safe mode: \"$code\"\n";+            }+            $p5_methods .= <<"_EOC_";+# Code block from grammar spec+$code++_EOC_+            next;+        }+        ### struct: $regex->{name}+        ## regex AST: $regex->{ast}+        my $params = {};+        if ($type eq 'rule') {+            $params->{sigspace} = 1;+        }+        my $body;++        my $ast = $regex->{ast};+        if ($opts->{safe_mode}) {+            _prune_actions($ast);+        }++        if ($type eq 'regex') {+            $body = Pugs::Emitter::Rule::Perl5::emit(+                'Pugs::Grammar::Rule',+                $ast,+            )+        } else {+            $body = Pugs::Emitter::Rule::Perl5::Ratchet::emit(+                'Pugs::Grammar::Rule',+                $ast,+                $params,+            );+        }+        $body =~ s/^/    /gm;+        $p5_methods .= <<_EOC_;+# $regex->{type} $regex->{name}+*$regex->{name} =+$body;++_EOC_+    }+    # bootstrap the regex parser itself:+    my $prefix = $name eq 'Pugs::Grammar::Rule' ?+        "#" : '';+    return <<"_EOC_";+package $name;++${prefix}use base 'Pugs::Grammar::Base';++use Pugs::Runtime::Match;+use Pugs::Runtime::Regex;+use Pugs::Runtime::Tracer ();++$p5_methods++1;+_EOC_+}++1;+__END__++=head1 NAME++Pugs::Emitter::Grammar::Perl5 - Perl 5 emitter for grammar ASTs++=head1 SYNOPSIS++    use Pugs::Compiler::Grammar;+    use Pugs::Emitter::Grammar::Perl5;++    my $ast = Pugs::Grammar::Rule->grammar(q{++        grammar MyLang;++        token def {+            <type> <?ws> <var_list> <?ws>? ';'+        }++        token type { int | float | double | char }++        token var_list { <ident> <?ws>? [ ',' <?ws>? <ident> ]* }++    })->();+    my $perl5 = Pugs::Emitter::Grammar::Perl5::emit($ast);+    print $perl5;++=head1 FUNCTIONS++=over++=item C<< $perl5 = Pugs::Emitter::Grammar::Perl5::emit($ast) >>++Generate Perl 5 source code from the grammar AST returned+by L<Pugs::Grammar::Rule>'s grammar parser.++=back++=head1 AUTHOR++The Pugs contributors E<lt>perl6-compiler@perl.orgE<gt>.++=head1 COPYRIGHT++Copyright (c) 2007 by Agent Zhang (E<lt>agentzh@agentzh.orgE<gt>) and others.++This program is free software; you can redistribute it+and/or modify it under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=head1 SEE ALSO++L<Pugs::Compiler::Grammar>, L<compile_p6grammar.pl>.+
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Parsec.pm view
@@ -0,0 +1,405 @@+package Pugs::Emitter::Rule::Parsec;++# p6-rule parsec emitter++use strict;+use warnings;+use Pugs::Grammar::MiniPerl6;+use Data::Dumper;+$Data::Dumper::Indent = 1;++our $sigspace = 0;+our $capture_counter = 0;+sub get_capture_var { return 'capture_' . $capture_counter++; }++sub rule_rename($){+    my $orig_name = shift;+    return 'rule' . (uc substr $orig_name, 0, 1) . substr $orig_name, 1;+}++sub to_genparser_string($) {+    my $char_parser = shift;+    return "($char_parser >>= \\c -> return [c])";+}++sub call_constant {+    my $str = shift;+    $str =~ s/\\/\\\\/g;+    $str =~ s/"/\\"/g;+    return 'string "' . $str . '"';+}++sub emit {+    my ($grammar, $ast, $param) = @_;+    local $sigspace = $param->{sigspace};   # XXX - $sigspace should be lexical+    local $capture_counter = 0;+    emit_rule( $ast, '' ) . "\n";+}++sub emit_rule {+    my $n = $_[0];+    my $tab = $_[1];+    die "unknown node: ", Dumper( $n )+        unless ref( $n ) eq 'HASH';+    #print "NODE ", Dumper($n);+    my ( $k, $v ) = each %$n;+    # XXX - use real references+    no strict 'refs';+    my $code = &$k( $v, $tab );+    return $code;+}++#rule nodes++sub non_capturing_group {+    return emit_rule( $_[0], $_[1] );+}++sub quant {+    my $term = $_[0]->{'term'};+    my $quantifier = $_[0]->{quant};+    my $spacing =+	( $sigspace &&+	  ($_[0]->{ws1} ne '' && $_[0]->{ws2} ne '')+	);+    my $tab = $spacing ? $_[1] . '  ' : $_[1];+    my $rul = emit_rule( $term, $tab );++    my $ws = metasyntax('?ws', $tab);+    $rul = "$ws\n$tab$rul" if $sigspace && $_[0]->{ws1} ne '';+    $rul = "$rul\n$tab$ws" if $sigspace && $_[0]->{ws2} ne '';+    $rul = "do\n$tab$rul" if $spacing;+    return $rul +        if $quantifier eq '';++    # *  +  ?+    my $qual = '';+    return "option \"\" \$ $rul" if $quantifier eq '?';++    $qual = 'many'     if $quantifier eq '*';+    $qual = 'many1'    if $quantifier eq '+';++    die "quantifier not implemented: $quantifier" if $qual eq '';++    my $final_rul =+	"(($qual \$ $rul) >>= \\arr -> return \$ foldr (++) \"\" arr)";++    return "$final_rul >>\n$tab$ws" if $sigspace and $_[0]->{ws3} ne '';+    return $final_rul;+}++sub alt {+    my @s;+    my @alt = @{$_[0]};++    # clean up alternative body+    # XXX maybe can be done earlier (e.g. in parser)+    foreach(@alt){+	if(ref eq 'HASH'){+	    my($k) = keys %$_;++	    if($k eq 'alt'){+		my @sub_alt = @{$_->{alt}};+		$_ = $sub_alt[0];+		push @alt, @sub_alt[1 .. $#sub_alt];+	    }+	}+    }++    my $indent = $_[1] . '  ';+    foreach(@alt){ +        my $tmp = emit_rule( $_, $indent );+        push @s, $tmp if $tmp;   +    }+    return "do\n$indent" . join "\n$indent<|>\n$indent", @s;+}++sub concat {+    my @inner = @{$_[0]};++    # clean up concatenation body+    # XXX maybe can be done earlier (e.g. in parser)+    foreach(@inner){+	if(ref eq 'HASH'){+	    my($k) = keys %$_;++	    if($k eq 'concat'){+		my @sub_inner = @{$_->{concat}};+		$_ = $sub_inner[0];+		push @inner, @sub_inner[1 .. $#sub_inner];+	    }+	}+    }++    my $indent = $_[1] . '  ';+    my $result = 'do';+    foreach(@inner){ +        my $tmp = emit_rule( $_, $indent );+	$result .= "\n$indent" . $tmp if $tmp;+    }+    return $result;+}++sub dot {+    return to_genparser_string("anyChar");+}++sub variable {}++use vars qw( %special_chars );+BEGIN {+    %special_chars = ( +r => "char '\\r'",+n => "char '\\n'",+t => "char '\\t'",+e => "char '\\033'",+f => "char '\\f'",+w => "(alphaNum <|> char '_')",+d => 'digit',+s => 'space',+W => "satisfy (\\x -> x /= '_' && not \$ isAlphaNum x)",+D => 'noneOf "0123456789"',+S => 'noneOf " \\v\\f\\t\\r\\n"',+);++    while(my ($k, $v) = each %special_chars){+	next if+	    $k eq uc $k or+	    exists $special_chars{uc $k} or+	    $v !~ /^char/;+	my $chars = substr $v, 6;+	chop $chars;+	$special_chars{uc $k} = "noneOf \"$chars\"";+    }+}+sub special_char {+    my $char = substr($_[0],1);+    return to_genparser_string($special_chars{$char})+	if exists $special_chars{$char};+    $char = '\\\\' if $char eq '\\';+    return "string \"$char\"";+}++sub match_variable {}++sub closure {+    my $miniperl6 = substr $_[0], 1, length($_[0]) - 2;+    my $haskell   = Pugs::Grammar::MiniPerl6->ProductionRule($miniperl6);+    $haskell =~ s/\n/\n$_[1]/sg;+    # print ">>> MiniPerl6\n$miniperl6\n===\n$haskell\n<<< Haskell\n";+    return "$haskell";+}++sub capturing_group {+    my $program = $_[0];++    $program = emit_rule( $program, $_[1] . '  ' )+        if ref( $program );++    return &get_capture_var . ' <- ' . $program;+}++sub named_capture {+    my $name    = $_[0]{ident};+    my $program = $_[0]{rule};++    return "$name <- " . metasyntax($program->{metasyntax}, $_[1] . '  ', 1)+	if exists $program->{metasyntax};++    return "$name <- " . emit_rule($program, $_[1] . '  ');+}++sub negate {+    my $body = $_[0];+    return not_after($body->{after}, $_[1]) if exists $body->{after};+    return not_before($body->{before}, $_[1]) if exists $body->{before};+    return '';+}++sub before {+    my $program = $_[0]{rule};+    return 'lookAhead (' . emit_rule($program, $_[1] . '    ') . ')';+}++sub not_before {+    my $program = $_[0]{rule};+    return 'notFollowedBy $ (' .+	emit_rule($program, $_[1] . '    ') .+	") >> return ' '";+    # notFollowedBy :: Show tok => GenParser tok st tok -> GenParser tok st ()+    #   tok = Char in the context so that we have to cast it+}++sub after {}+sub not_after {}+sub colon {}++sub constant {+    return "string \"$_[0]\"";+}++use vars qw( %char_class );+BEGIN {+    %char_class = ( +alpha => 'letter',+alnum => 'alphaNum',+ascii => 'satisfy isAscii',+blank => 'oneOf " \\t"',+cntrl => 'satisfy isCotrol',+digit => 'digit',+graph => "satisfy (\\x -> isPrint x && x /= ' ')",+lower => 'lower',+print => 'satisfy isPrint',+punct => "satisfy (\\x -> isPrint x && x /= ' ' && not (isAlphaNum x))",+space => 'space',+upper => 'upper',+word  => "(alphaNum <|> char '_')",+xdigit => 'hexDigit',+);+}++sub metasyntax {+    # <cmd>+    my $cmd = $_[0];   +    my $prefix = substr( $cmd, 0, 1 );++    my $named_capturing = !$_[2];+    my $negative_lookahead = 0;++    if ( $prefix eq '@' ) {+        # XXX - wrap @array items - see end of Pugs::Grammar::Rule+        # TODO - param list+        return +            "$_[1] do {\n" . +            "$_[1]    my \$match;\n" . +            "$_[1]    for my \$subrule ( $cmd ) {\n" . +            "$_[1]        \$match = " . +                call_subrule( '$subrule', '', () ) . ";\n" .+            "$_[1]        last if \$match;\n" . +            "$_[1]    }\n" .+            "$_[1]    my \$bool = (!\$match != 1);\n" . +            "$_[1]    \$pos = \$match->to if \$bool;\n" . +            "$_[1]    \$bool;\n" . +            "$_[1] }";+    }+    if ( $prefix eq '$' ) {+        if ( $cmd =~ /::/ ) {+            # call method in fully qualified $package::var+            # ...->match( $rule, $str, $grammar, $flags, $state )  +            # TODO - send $pos to subrule+            return +                "$_[1]         do {\n" .+                "$_[1]           push \@match,\n" . +                "$_[1]             $cmd->match( \$s, \$grammar, {p => \$pos}, undef );\n" .+                "$_[1]           \$pos = \$match[-1]->to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }"+        }+        # call method in lexical $var+        # TODO - send $pos to subrule+        return +                "$_[1]         do {\n" .+                "$_[1]           my \$r = Pugs::Runtime::Rule::get_variable( '$cmd' );\n" . +                "$_[1]           push \@match,\n" . +                "$_[1]             \$r->match( \$s, \$grammar, {p => \$pos}, undef );\n" .+                "$_[1]           \$pos = \$match[-1]->to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }"+    }+    if ( $prefix eq q(') ) {   # single quoted literal ' +        $cmd = substr( $cmd, 1, -1 );+        return call_constant( $cmd );+    }+    if ( $prefix eq q(") ) {   # interpolated literal "+        $cmd = substr( $cmd, 1, -1 );+        warn "<\"...\"> not implemented";+        return;+    }+    if ( $prefix =~ /[-+[]/ ) {   # character class +	   if ( $prefix eq '-' ) {+	       my $str = substr $cmd, 2, length($cmd) - 3;+	       $str =~ s/\\>/>/g; # XXX+	       $str =~ s/\\/\\\\/g;+	       $str =~ s/"/\\"/g;++	       return to_genparser_string("noneOf \"$str\"");+	   } +	   elsif ( $prefix eq '+' ) {+	       $cmd = substr($cmd, 2);+	   }++	   my $str = substr $cmd, 1, length($cmd) - 2;+	   $str =~ s/\\>/>/g; # XXX+	   $str =~ s/\\/\\\\/g;+	   $str =~ s/"/\\"/g;++	   return to_genparser_string("oneOf \"$str\"");+    }+    if ( $prefix eq '?' ) {   # non_capturing_subrule / code assertion+        $cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+	$prefix = substr( $cmd, 0, 1 );+	$named_capturing = 0;+    }+    if ( $prefix eq '!' ) {   # negated_subrule / code assertion +        $cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+	$prefix = substr( $cmd, 0, 1 );+	$negative_lookahead = 1;+	warn "<$cmd> not implemented";+	return;+    }+    if ( $cmd eq '.' ) {+            warn "<$cmd> not implemented";+            return;+    }+    if ( $prefix =~ /[_[:alnum:]]/ ) {  +        # "before" and "after" are handled in a separate rule+	if ( $cmd eq 'ws' ){+	    return 'perl6WhiteSpace';+	    # assuming function:+	    # perl6WhiteSpace = do cls <- getPrevCharClass+	    #                      let mod = if cls == WordClass then many1 else many+	    #                      do mod whiteSpace+	    #                         <|>+	    #                         (satisfy (\c -> charClassOf c /= WordClass) >> return "")++	}+        if ( $cmd eq 'cut' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'commit' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'prior' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'null' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $char_class{$cmd} ) {+            # XXX - inlined char classes are not inheritable, but this should be ok+	    return to_genparser_string($char_class{$cmd});+        }+        # capturing subrule+        # <subrule ( param, param ) >+        my ( $subrule, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+	return ($named_capturing ? "$subrule <- " : '') .+	    rule_rename($subrule) . join '', map { " ($_)" } @param;+    }+    die "<$cmd> not implemented";+}++1;
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5.pm view
@@ -0,0 +1,610 @@+package Pugs::Emitter::Rule::Perl5;++use Pugs::Emitter::Rule::Perl5::Ratchet;++# p6-rule perl5 emitter++use strict;+use warnings;+use Data::Dumper;+$Data::Dumper::Indent = 1;++our $capture_count;+our $capture_to_array;+our %capture_seen;++sub call_subrule {+    my ( $subrule, $tab, $positionals, @param ) = @_;+    $subrule = "\$_[4]->" . $subrule unless $subrule =~ / :: | \. | -> /x;+    $subrule =~ s/\./->/;   # XXX - source filter++    $positionals = shift @param if $positionals eq '' && @param == 1;  # odd number of elements in hash+    #print "PARAM: ",Dumper(@param);++    return+"$tab sub{+$tab     my \$prior = \$::_V6_PRIOR_;+$tab     my \$param = { \%{ \$_[7] || {} }, positionals => [ $positionals ], args => {" .+            join(", ",@param) . "} };+$tab     \$_[3] = $subrule( \$_[0], \$param, \$_[3],  );+$tab     \$::_V6_PRIOR_ = \$prior;+$tab }+";+}++sub call_subrule_no_capture {+    my ( $subrule, $tab, $positionals, @param ) = @_;+    $subrule = "\$_[4]->" . $subrule unless $subrule =~ / :: | \. | -> /x;+    $subrule =~ s/\./->/;   # XXX - source filter++    $positionals = shift @param if $positionals eq '' && @param == 1;  # odd number of elements in hash+    #print "PARAM: ",Dumper(@param);++    return+"$tab sub{+$tab     my \$prior = \$::_V6_PRIOR_;+$tab     my \$param = { \%{ \$_[7] || {} }, positionals => [ $positionals ], args => {" .+            join(", ",@param) . "} };+$tab     \$_[3] = $subrule( \$_[0], \$param, \$_[3],  );+$tab     \$_[3]->data->{match} = [];+$tab     \$_[3]->data->{named} = {};+$tab     \$::_V6_PRIOR_ = \$prior;+$tab }+";+}++sub emit {+    my ($grammar, $ast) = @_;+    # runtime parameters: $grammar, $string, $state, $arg_list+    # rule parameters: see Runtime::Rule.pm+    local $capture_count = -1;+    local $capture_to_array = 0;+    local %capture_seen = ();+    #print "emit capture_to_array $capture_to_array\n";+    # print "emit: ", Dumper($ast);+    #die emit_rule( $ast, '    ' );++    return+"do {+  package Pugs::Runtime::Regex;+  my \$matcher = \n" . emit_rule( $ast, '    ' ) . ";+  my \$rule;+  \$rule = sub {" .+        # grammar, string, state, args+        #"    print \"match args: \",Dumper(\@_);\n" .+        "+    my \$tree;+    if (  defined \$_[3]{p}+       && ! \$_[3]{continue}+       ) {+      \$matcher->( \$_[1], \$_[2], \$tree, \$tree, \$_[0], \$_[3]{p}, \$_[1], \$_[3] );+    }+    else {+      \$_[3]{p} ||= 0;+      for my \$pos ( \$_[3]{p} .. length( \$_[1] ) ) {+        my \$param = { \%{\$_[3]}, p => \$pos };+        \$matcher->( \$_[1], \$_[2], \$tree, \$tree, \$_[0], \$pos, \$_[1], \$param );+        last if \$tree;+      }+      \$tree = Pugs::Grammar::Base->no_match(\@_)+        unless defined \$tree;+    }+    my \$cap = \$tree->data->{capture};+    if ( ref \$cap eq 'CODE' ) {+      \$::_V6_MATCH_ = \$tree;+      \$tree->data->{capture} = \\(\$cap->( \$tree ));+    };+    if ( \$tree ) {+      # \$::_V6_PRIOR_ = \$rule++      my \$prior = \$::_V6_PRIOR_;+      \$::_V6_PRIOR_ = sub {+        local \$main::_V6_PRIOR_ = \$prior;+        \$rule->(\@_);+      };++    }+    return \$tree;+  }+}+";+}++sub emit_rule {+    my $n = $_[0];+    my $tab = $_[1] . '  ';+    die "unknown node: ", Dumper( $n )+        unless ref( $n ) eq 'HASH';+    #print "NODE ", Dumper($n);+    my @keys = grep { substr($_, 0, 1) ne '_' } keys %$n;+    my ($k) = @keys;+    my $v = $$n{$k};+    # XXX - use real references+    no strict 'refs';+    my $code = &$k( $v, $tab );+    return $code;+}++#rule nodes++sub capturing_group {+    my $program = $_[0];++    $capture_count++;+    {+        $capture_seen{$capture_count}++;+        local $capture_count = -1;+        local $capture_to_array = 0;+        local %capture_seen = ();+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }++    return+        "$_[1] positional( $capture_count, " .+        ( $capture_to_array || ( $capture_seen{$capture_count} > 1 ? 1 : 0 ) ) .+        ", \n" .+        $program .+        "$_[1] )\n";+}+sub capture_as_result {+    my $program = $_[0];++    $capture_count++;+    {+        $capture_seen{$capture_count}++;+        local $capture_count = -1;+        local $capture_to_array = 0;+        local %capture_seen = ();+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }++    return+        "$_[1] capture_as_result( \n" .+        $program .+        "$_[1] )\n";+}+sub non_capturing_group {+    return emit_rule( $_[0], $_[1] );+}+sub quant {+    my $term = $_[0]->{'term'};+    my $quantifier = $_[0]->{quant}  || '';+    my $greedy     = $_[0]->{greedy} || '';   # + ?++    if ( ref( $quantifier ) eq 'HASH' )+    {+        die "quantifier not implemented: " . Dumper( $quantifier );++        #return+        #    "$_[1] concat(\n" .+        #    join( ',', ($rul) x $count ) .+        #    "$_[1] )\n";+    }++    my $quant = $quantifier . $greedy;+    my $sub = {+            '*' =>'greedy_star',+            '+' =>'greedy_plus',+            '*?'=>'non_greedy_star',+            '+?'=>'non_greedy_plus',+            '?' =>'optional',+            '??'=>'null_or_optional',+            ''  => '',+        }->{$quant};+    die "quantifier not implemented: $quant"+        unless defined $sub;++    my $rul;+    {+        my $cap = $capture_to_array;+        local $capture_to_array = $cap || ( $quant ne '' ? 1 : 0 );+        $rul = emit_rule( $term, $_[1] . '  ' );+    }++    return $rul+        if $sub eq '';+    return+        "$_[1] $sub(\n" .+        $rul .+        "$_[1] )\n";+}+sub alt {+    my @s;+    # print "Alt: ", Dumper($_[0]);+    my $count = $capture_count;+    my $max = -1;+    for ( @{$_[0]} ) {+        $capture_count = $count;++        my $_capture_count      = $capture_count;+        my $_capture_to_array   = $capture_to_array;+        my %_capture_seen       = ( %capture_seen );+        local $capture_count    = $_capture_count;+        local $capture_to_array = $_capture_to_array;+        local %capture_seen     = ( %_capture_seen );++        my $tmp = emit_rule( $_, $_[1].'  ' );+        # print ' ',$capture_count;+        $max = $capture_count+            if $capture_count > $max;+        push @s, $tmp if $tmp;+    }+    $capture_count = $max;++    return "$_[1] alternation( [\n" .+           join( ',', @s ) .+           "$_[1] ] )\n";+}+sub alt1 { &alt }+sub concat {+    my @s;+    for ( @{$_[0]} ) {+        my $tmp = emit_rule( $_, $_[1] );+        push @s, $tmp if $tmp;+    }+    return+        "$_[1] concat( \n" .+        join( ',', @s ) .+        "$_[1] )\n";+}+sub code {+    return "$_[1] $_[0]\n";+}+sub dot {+    return call_subrule( 'any', $_[1], '' );+}+sub variable {+    my $name = "$_[0]";+    my $value = undef;+    # XXX - eval $name doesn't look up in user lexical pad+    # XXX - what &xxx interpolate to?++    if ( $name =~ /^\$/ ) {+        # $^a, $^b+        if ( $name =~ /^ \$ \^ ([^\s]*) /x ) {+            my $index = ord($1)-ord('a');+            #print "Variable #$index\n";+            #return "$_[1] constant( \$_[7][$index] )\n";++            my $code =+            "    sub {+                #print \"Runtime Variable args[\", join(\",\",\@_) ,\"] \$_[7][$index]\\n\";+                return constant( \$_[7][$index] )->(\@_);+            }";+            $code =~ s/^/$_[1]/mg;+            return "$code\n";+        }+        else {+            $value = eval $name;+        }+    }++    # ??? $value = join('', eval $name) if $name =~ /^\@/;++    if ( $name =~ /^%/ ) {+        # XXX - runtime or compile-time interpolation?+        return "$_[1] hash( \\$name )\n" if $name =~ /::/;+        return "$_[1] hash( get_variable( '$name' ) )\n";+    }+    die "interpolation of $name not implemented"+        unless defined $value;++    return "$_[1] constant( '" . $value . "' )\n";+}+sub special_char {+    my ($char, $data) = $_[0] =~ /^.(.)(.*)/;++    return  "$_[1] perl5( '\\N{" . join( "}\\N{", split( /\s*;\s*/, $data ) ) . "}' )\n"+        if $char eq 'c';+    return  "$_[1] perl5( '(?!\\N{" . join( "}\\N{", split( /\s*;\s*/, $data ) ) . "})\\X' )\n"+        if $char eq 'C';++    return  "$_[1] perl5( '\\x{$data}' )\n"+        if $char eq 'x';+    return  "$_[1] perl5( '(?!\\x{$data})\\X' )\n"+        if $char eq 'X';++    return special_char( sprintf("\\x%X", oct($data) ) )+        if $char eq 'o';+    return special_char( sprintf("\\X%X", oct($data) ) )+        if $char eq 'O';++    return  "$_[1] perl5( '(?:\\n\\r?|\\r\\n?|\\x85|\\x{2028})' )\n"+        if $char eq 'n';+    return  "$_[1] perl5( '(?!\\n\\r?|\\r\\n?|\\x85|\\x{2028})\\X' )\n"+        if $char eq 'N';++    # XXX - Infinite loop in pugs stdrules.t+    #return metasyntax( '?_horizontal_ws', $_[1] )+    return "$_[1] perl5( '[\\x20\\x09]' )\n"+        if $char eq 'h';+    return "$_[1] perl5( '[^\\x20\\x09]' )\n"+        if $char eq 'H';+    #return metasyntax( '?_vertical_ws', $_[1] )+    return "$_[1] perl5( '[\\x0A\\x0D]' )\n"+        if $char eq 'v';+    return "$_[1] perl5( '[^\\x0A\\x0D]' )\n"+        if $char eq 'V';++    for ( qw( r n t e f w d s ) ) {+        return "$_[1] perl5( '\\$_' )\n" if $char eq $_;+        return "$_[1] perl5( '[^\\$_]' )\n" if $char eq uc($_);+    }+    $char = '\\\\' if $char eq '\\';+    return "$_[1] constant( q!$char! )\n" unless $char eq '!';+    return "$_[1] constant( q($char) )\n";+}+sub match_variable {+    my $name = $_[0];+    my $num = substr($name,1);+    #print "var name: ", $num, "\n";+    my $code =+    "    sub {+        my \$m = \$_[2];+        #print 'var: ',\$m->perl;+        #print 'var: ',\$m->[$num];+        return constant( \"\$m->[$num]\" )->(\@_);+    }";+    $code =~ s/^/$_[1]/mg;+    return "$code\n";+}+sub closure {+    my $code     = $_[0]{closure};+    my $modifier = $_[0]{modifier};  # 'plain', '', '?', '!'++    #die "closure modifier not implemented '$modifier'"+    #    unless $modifier eq 'plain';++    #warn "CODE $code";+    $code = '' if $code eq '{*}';  # "whatever"++    if (  ref( $code )+       && defined $Pugs::Compiler::Perl6::VERSION+    ) {+        # perl6 compiler is loaded+        $code = Pugs::Emitter::Perl6::Perl5::emit( 'grammar', $code, 'self' );+        $code = '{ my $_V6_SELF = shift; ' . $code . '}';  # make it a "method"+    }+    else {+        # XXX XXX XXX - source-filter - temporary hacks to translate p6 to p5+        # $()<name>+        $code =~ s/ ([^']) \$ \( \) < (.*?) > /$1 \$_[0]->[$2]/sgx;+        # $<name>+        $code =~ s/ ([^']) \$ < (.*?) > /$1 \$_[0]->{$2}/sgx;+        # $()+        $code =~ s/ ([^']) \$ \( \) /$1 \$_[0]->()/sgx;+        # $/+        $code =~ s/ ([^']) \$ \/ /$1 \$_[0]/sgx;+    }+    #print "Code: $code\n";++            return "+                sub {+                    \$_[3] = Pugs::Runtime::Match->new( {+                        bool  => \\1,+                        str   => \\(\$_[0]),+                        from  => \\(\$_[7]{p} || 0),+                        to    => \\(\$_[7]{p} || 0),+                        match => [],+                        named => {},+                        capture => sub { $code },+                        abort => 1,+                    } )+                }\n"+                if $code =~ /return/;++    my $bool = "\\\$::_V6_SUCCEED";+    $bool    = "\\( \$capture ? 1 : 0 )"  if $modifier eq '?';+    $bool    = "\\( \$capture ? 0 : 1 )"  if $modifier eq '!';++    my $cap  = "\\\$capture";+    $cap     = "undef"  if $modifier eq '?' || $modifier eq '!';++            return "+                sub {+                    \$::_V6_MATCH_ = \$_[0];+                    local \$::_V6_SUCCEED = 1;+                    my \$capture = sub { $code }->( \$_[3] );+                    \$_[3] = Pugs::Runtime::Match->new( {+                        bool  => $bool,+                        str   => \\(\$_[0]),+                        from  => \\(\$_[7]{p} || 0),+                        to    => \\(\$_[7]{p} || 0),+                        match => [],+                        named => {},+                        capture => undef,+                    } )+                }\n";++}+sub named_capture {+    my $name    = $_[0]{ident};+    $name = $name->{match_variable} if ref($name) eq 'HASH';+    $name =~ s/^[\$\@\%]//;  # TODO - change semantics as needed+    my $program = $_[0]{rule};+    $capture_seen{$name}++;+    return+        "$_[1] named( '$name', " .+        ( $capture_to_array || ( $capture_seen{$name} > 1 ? 1 : 0 ) ) .+        ", \n" .+        emit_rule($program, $_[1]) .+        "$_[1] )\n";+}+sub negate {+    my $program = $_[0];+    #print "Negate: ", Dumper($_[0]);+    return+        "$_[1] negate( \n" .+        emit_rule($program, $_[1]) .+        "$_[1] )\n";+}+sub before {+    my $program = $_[0]{rule};+    return+        "$_[1] before( \n" .+        emit_rule($program, $_[1]) .+        "$_[1] )\n";+}+sub colon {+    my $str = $_[0];+    return "$_[1] at_start() \n"+        if $str eq '^';+    return "$_[1] alternation( [ null(), failed_abort() ] ) \n"+        if $str eq ':';+    return "$_[1] at_end_of_string() \n"+        if $str eq '$';+    return "$_[1] at_line_start() \n"+        if $str eq '^^';+    return "$_[1] at_line_end() \n"+        if $str eq '$$';+    return metasyntax( '?_wb_left', $_[1] )+        if $str eq '<<';+    return metasyntax( '?_wb_right', $_[1] )+        if $str eq '>>';+    die "'$str' not implemented";+}+sub modifier {+    my $str = $_[0]{modifier};+    my $rule = $_[0]{rule};++    return "$_[1] ignorecase( \n"+        . emit_rule( $rule, $_[1] . '  ' )+        . " )\n"+        if $str eq 'ignorecase';++    die "modifier '$str' not implemented";+}+sub constant {+    my $char = $_[0] eq '\\' ? '\\\\' : $_[0];+    return "$_[1] constant( q!$char! )\n" unless $char =~ /!/;+    return "$_[1] constant( q($char) )\n";+}+sub char_class {+    my $cmd = Pugs::Emitter::Rule::Perl5::CharClass::emit( $_[0] );+    return "$_[1] perl5( q!$cmd! )\n" unless $cmd =~ /!/;+    return "$_[1] perl5( q($cmd) )\n"; # XXX if $cmd eq '!)'+}+sub call {+    #die "not implemented: ", Dumper(\@_);+    my $param = $_[0]{params};+    my $name = $_[0]{method};+        # capturing subrule+        # <subrule ( param, param ) >+        my ($param_list) = $param =~ /\{(.*)\}/;+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+        $capture_seen{$name}++;+        #print "subrule ", $capture_seen{$name}, "\n";+        #print "param: ", Dumper(\@param);+        return+            "$_[1] named( '$name', " .+            ( $capture_to_array || ( $capture_seen{$name} > 1 ? 1 : 0 ) ) .+            ", \n" .+            call_subrule( $name, $_[1]."  ", "", @param ) .+            "$_[1] )\n";+}+sub metasyntax {+    my $cmd = $_[0]{metasyntax};+    my $modifier = delete $_[0]{modifier} || '';   # ? !+    return negate( { metasyntax => $_[0] }, $_[1] ) if $modifier eq '!';++    my $prefix = substr( $cmd, 0, 1 );+    if ( $prefix eq '@' ) {+        # XXX - wrap @array items - see end of Pugs::Grammar::Rule+        return+            "$_[1] alternation( \\$cmd )\n";+    }++    if ( $prefix eq '%' ) {+        # XXX - runtime or compile-time interpolation?+        my $name = substr( $cmd, 1 );+        $capture_seen{$name}++;+        return "$_[1] named( '$name', " .+            ( $capture_to_array || ( $capture_seen{$name} > 1 ? 1 : 0 ) ) .+            ", hash( \\$cmd ) )\n"+            if $cmd =~ /::/;+        return "$_[1] named( '$name', " .+            ( $capture_to_array || ( $capture_seen{$name} > 1 ? 1 : 0 ) ) .+            ", hash( get_variable( '$cmd' ) ) )\n";+    }++    if ( $prefix eq '$' ) {+        if ( $cmd =~ /::/ ) {+            # call method in fully qualified $package::var+            return+            "$_[1] sub { \n" .+            # "$_[1]     print 'params: ',Dumper(\@_);\n" .+            "$_[1]     \$_[3] = $cmd->match( \$_[0], \$_[4], \$_[7], \$_[1] );\n" .+            "$_[1] }\n";+        }+        # call method in lexical $var+        return+            "$_[1] sub { \n" .+            #"$_[1]     print 'params: ',Dumper(\@_);\n" .+            "$_[1]     my \$r = get_variable( '$cmd' );\n" .+            "$_[1]     \$_[3] = \$r->match( \$_[0], \$_[4], \$_[7], \$_[1] );\n" .+            "$_[1] }\n";+    }+    if ( $prefix eq q(') ) {   # single quoted literal '+        $cmd = substr( $cmd, 1, -1 );+        return "$_[1] constant( q!$cmd! )\n" unless $cmd =~ /!/;+        return "$_[1] constant( q($cmd) )\n";+    }+    if ( $prefix eq q(") ) {   # interpolated literal "+        $cmd = substr( $cmd, 1, -1 );+        warn "<\"...\"> not implemented";+        return;+    }+    if ( $prefix eq '.' ) {   # non_capturing_subrule / code assertion+        $cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+        return call_subrule_no_capture( $cmd, $_[1], '' );+    }+    if ( $prefix eq '?' ) {   # non_capturing_subrule / code assertion+        # XXX FIXME+        $cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+        return call_subrule_no_capture( $cmd, $_[1], '' );+    }+    if ( $prefix =~ /[_[:alnum:]]/ ) {+        if ( $cmd eq 'cut' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'commit' ) {+            warn "<$cmd> not implemented";+            return;+        }+        # capturing subrule+        # <subrule ( param, param ) >+        my ( $name, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+        $capture_seen{$name}++;+        #print "subrule ", $capture_seen{$name}, "\n";+        #print "param: ", Dumper(\@param);+        return+            "$_[1] named( '$name', " .+            ( $capture_to_array || ( $capture_seen{$name} > 1 ? 1 : 0 ) ) .+            ", \n" .+            call_subrule( $name, $_[1]."  ", "", @param ) .+            "$_[1] )\n";+    }+    #if ( $prefix eq '.' ) {+    #    my ( $method, $param_list ) = split( /[\(\)]/, $cmd );+    #    $method =~ s/^\.//;+    #    $param_list ||= '';+    #    return "$_[1] try_method( '$method', '$param_list' ) ";+    #}+    die "<$cmd> not implemented";+}++1;
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/CharClass.pm view
@@ -0,0 +1,100 @@+package Pugs::Emitter::Rule::Perl5::CharClass;++use strict;+use Data::Dumper;++use vars qw( %char_class );+BEGIN {+    %char_class = map { $_ => 1 } qw(+        alpha alnum ascii blank+        cntrl digit graph lower+        print punct space upper+        word  xdigit+    );+}++# input format:+# [+#    '+alpha'+#    '-[z]'+# ]++# TODO - set composition logic+# ( ( ( before +alpha ) | before +digit ) before not-alpha ) before not-digit )++sub emit {+    #print Dumper( $_[0] );+    #print Dumper( @{$_[0]} );+    my @c = map { "$_" } @{$_[0]};+    #print Dumper( @c );+    my $out = '';+    #my $last_cmd = '';+    for ( @c ) {+        my ( $op, $cmd ) = /(.)(.*)/;++        $cmd =~ s/\s//g;++        #if ( $last_cmd eq '-'+        #    && substr($cmd,0,1) eq '+'+        #    )+        #{+        #    $out .= '|';+        #}+        #$last_cmd = substr($cmd,0,1);++        $cmd =~ s/\.\./-/g;  # ranges++        # TODO - \o \O++        if    ( $cmd =~ /^ \[ \\ c \[ (.*) \] \] /x ) {+            #$cmd = "(?:\\N{" . join( "}|\\N{", split( /\s*;\s*/, $1 ) ) . "})";+            $cmd = "[\\N{" . join( "}\\N{", split( /\s*;\s*/, $1 ) ) . "}]";+        }+        elsif ( $cmd =~ /^ \[ \\ C \[ (.*) \] \] /x ) {+            #$cmd = "(?!\\N{" . join( "}|\\N{", split( /\s*;\s*/, $1 ) ) . "})\\X";+            $cmd = "[^\\N{" . join( "}\\N{", split( /\s*;\s*/, $1 ) ) . "}]";+        }+++        elsif ( $cmd =~ /^ \[ \\ x \[ (.*) \] \] /x ) {+            $cmd = "(?:\\x{$1})";+        }+        elsif ( $cmd =~ /^ \[ \\ X \[ (.*) \] \] /x ) {+            $cmd = "(?!\\x{$1})\\X";+            #$cmd = "[^\\x{$1}]";+        }+++        elsif ( $cmd =~ /^ \s* \[ (.*) /x ) {+           $cmd = '[' . $1;+	    }+        elsif ( $cmd =~ /^ \s* (.*) /x ) {+           my $name = $1;+           $cmd = ( exists $char_class{$name} )+                ? "[[:$name:]]"+                : "\\p{$name}";+        }++        if ( $op eq '+' ) {+            $out .=+                ( $out eq '' )+                ? '(?=' . $cmd . ')'+                : '|(?=' . $cmd . ')';+        }+        elsif ( $op eq '-' ) {+            $out .= '(?!' . $cmd . ')';+        }+        else {+            #print Dumper( @c ), ' == ', $out, "\n";+            die "invalid character set op: $op";+        }+    }+    $out = "(?:$out)\\X";++    #print Dumper( @c ), ' == ', $out, "\n";++    return $out;+}++1;+
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/Ratchet.pm view
@@ -0,0 +1,1152 @@+package Pugs::Emitter::Rule::Perl5::Ratchet;++# p6-rule perl5 emitter for ":ratchet" (non-backtracking)+# see: RuleInline.pl, RuleInline-more.pl for a program prototype++#use Smart::Comments '####';+use strict;+use warnings;+use Pugs::Emitter::Rule::Perl5::CharClass;+use Data::Dumper;+$Data::Dumper::Indent = 1;++our $direction = "+";  # XXX make lexical+our $sigspace = 0;+our $capture_count;+our $capture_to_array;+our $RegexPos;++our $count;+sub id {+    if (!defined $count) {+        if (defined $::PCR_SEED) {+            #warn "SET SEED!!!";+            srand($::PCR_SEED);+        }+        $count = 1000 + int(rand(1000));+    }+    'I' . ($count++)+}++sub call_subrule {+    my ( $subrule, $tab, $positionals, @param ) = @_;+    $subrule = "\$grammar->" . $subrule+        unless $subrule =~ / :: | \. | -> /x;+    $subrule =~ s/\./->/;   # XXX - source filter++    $positionals = shift @param if $positionals eq '' && @param == 1;++    return+"$tab     $subrule( \$s, { "+        . "p => \$pos, "+        . "positionals => [ $positionals ], "+        . "args => {" .+                 join(", ",@param) .+             "}, "+        . "}, undef )";+}++sub quote_constant {+    my $const;+    if ( $_[0] eq "\\" ) {+        $const = "chr(".ord("\\").")";+    }+    elsif ( $_[0] eq "'" ) {+        $const = "chr(".ord("'").")"+    }+    else {+        $const = "'$_[0]'"+    }+    return $const;+}++sub call_constant {+    return " 1 # null constant\n"+        unless length($_[0]);+    my $const = quote_constant( $_[0] );+    my $len = length( eval $const );+    #print "Const: [$_[0]] $const $len \n";+    return+"+$_[1] ## <constant>+$_[1] ## pos: @$RegexPos+$_[1] ( ( substr( \$s, \$pos, $len ) eq $const )+$_[1]     ? ( \$pos $direction= $len or 1 )+$_[1]     : 0+$_[1] )+$_[1] ## </constant>\n";+}++sub call_perl5 {+    my $const = $_[0];+    $_[1] = '  ' unless defined $_[1];+    #print "CONST: $const - $direction \n";+    return+"$_[1] ## <perl5>+$_[1] ( ( substr( \$s, \$pos ) =~ m/^($const)/ )+$_[1]     ? ( \$pos $direction= length( \$1 ) or 1 )+$_[1]     : 0+$_[1] )+$_[1] ## </perl5>\n";+}++sub emit {+    my ($grammar, $ast, $param) = @_;+    # runtime parameters: $grammar, $string, $state, $arg_list+    # rule parameters: see Runtime::Rule.pm+    local $sigspace = $param->{sigspace} ? 1 : 0;   # XXX - $sigspace should be lexical+    ### ratchet emit sigspace: $sigspace+    local $capture_count = -1;+    local $capture_to_array = 0;+    #print "rule: ", Dumper( $ast );+    return+        "## <global>+## sigspace: $sigspace+## ratchet: 1+do { my \$rule; \$rule = sub {+  my \$grammar = \$_[0];+  my \$s = \$_[1];+  \$_[3] = \$_[2] unless defined \$_[3]; # backwards compat+  no warnings 'substr', 'uninitialized', 'syntax';+  my \%pad;\n" .+        #"  my \$pos;\n" .+        #"  print \"match arg_list = \$_[1]\n\";\n" .+        #"  print 'match ', Dumper(\\\@_);\n" .+        #"  print \"match arg_list = \@{[\%{\$_[1]} ]}\n\" if defined \$_[1];\n" .+        #"  warn \"match pos = \", pos(\$_[1]), \"\\n\";\n" .+"  my \$m;+  my \$bool;+  my \@pos;+  # XXX :pos(X) takes the precedence over :continue ?+  if (defined \$_[3]{p}) {+    push \@pos, \$_[3]{p} || 0;+  } elsif (\$_[3]{continue}) {+    push \@pos, (pos(\$_[1]) || 0) .. length(\$s);+  } else {+    push \@pos, 0..length(\$s);+  }+  for my \$pos ( \@pos ) {+    my \%index;+    my \@match;+    my \%named;+    \$bool = 1;+    \$named{KEY} = \$_[3]{KEY} if exists \$_[3]{KEY};+    \$m = Pugs::Runtime::Match->new( {+      str => \\\$s, from => \\(0+\$pos), to => \\(\$pos),+      bool => \\\$bool, match => \\\@match, named => \\\%named, capture => undef,+    } );+    {+      my \$prior = \$::_V6_PRIOR_;+      local \$::_V6_PRIOR_ = \$prior;+      \$bool = 0 unless+" .+        #"      do { TAILCALL: ;\n" .+        emit_rule( $ast, '    ' ) . ";+    }+    if ( \$bool ) {+      my \$prior = \$::_V6_PRIOR_;+      \$::_V6_PRIOR_ = sub {+        local \$main::_V6_PRIOR_ = \$prior;+        \$rule->(\@_);+      };+      #warn \"pos2 = \", \$pos, \"\\n\";+      pos(\$_[1]) = \$pos if \$_[3]{continue};+      last;+    }+  } # /for+  \$::_V6_MATCH_ = \$m;+  return \$m;+} }+## </global>\n";+}++sub emit_rule {+    my $n = $_[0];+    my $tab = $_[1] . '  ';+    die "unknown node: ", Dumper( $n )+        unless ref( $n ) eq 'HASH';+    #print "NODE ", Dumper($n);+    my @keys = grep { substr($_, 0, 1) ne '_' } keys %$n;+    ### Node keys: @keys+    my ($k) = @keys;+    my $v = $n->{$k};+    local $RegexPos = $n->{_pos};+    ### $RegexPos+    if (!defined $RegexPos) {+    #    warn "WARNING: No _pos slot found for AST node '$k'.\n";+    #    warn Dumper($n);+        $RegexPos = [];+    }+    # XXX - use real references+    no strict 'refs';+    #print "NODE ", Dumper($k), ", ", Dumper($v);+    my $code = $k->( $v, $tab );+    return $code;+}++#rule nodes++sub non_capturing_group {+    return emit_rule( $_[0], $_[1] );+}+sub quant {+    my $term = $_[0]->{'term'};+    my $quantifier = $_[0]->{quant}  || '';+    my $greedy     = $_[0]->{greedy} || '';   # + ?+    die "greediness control not implemented: $greedy"+        if $greedy;+    #print "QUANT: ",Dumper($_[0]);+    my $id = id();+    my $tab = ( $quantifier eq '' ) ? $_[1] : $_[1] . "  ";+    my $ws = metasyntax( { metasyntax => 'ws', modifier => '.' }, $tab );+    my $ws3 = ( $sigspace && $_[0]->{ws3} ne '' ) ? " &&\n$ws" : '';++    my $rul;+    {+        #print "Term: ", Dumper($term), "\n";+        my $cap = $capture_to_array;+        local $capture_to_array = $cap || ( $quantifier ne '' );+        $rul = emit_rule( $term, $tab );++        # rollback on fail+        $rul = "$_[1]  ( "+            .  "  ( \$pad{$id} = \$pos or 1 ) &&\n"+            .     $rul+            .  " ||"+            .  "    ( ( \$pos = \$pad{$id} ) && 0 )"+            .  " )";+    }++    $rul = "$ws &&\n$rul" if $sigspace && $_[0]->{ws1} ne '';+    $rul = "$rul &&\n$ws" if $sigspace && $_[0]->{ws2} ne '';+    #print $rul;+    return "  +$_[1] ## <group>+$_[1] ## pos: @$RegexPos+" . $rul . "+$_[1] ## </group>\n"+        if $quantifier eq '';+    # *  +  ?+    # TODO: *? +? ??+    # TODO: *+ ++ ?++    # TODO: quantifier + capture creates Array+    #warn Dumper( $quantifier );+    if ( ref( $quantifier ) eq 'HASH' )+    {+        my $code = $quantifier->{closure};+        if ( ref( $code ) ) {+            if ( defined $Pugs::Compiler::Perl6::VERSION ) {+                #print " perl6 compiler is loaded \n";+                $code = Pugs::Emitter::Perl6::Perl5::emit( 'grammar', $code, 'self' );+            }+        };+        my @count = eval $code;+        #warn "code: $code = [ @count ]";++        die "quantifier not implemented: " . Dumper( $quantifier )+            if @count ne 1+            || $count[0] == 0;++        return+            "$_[1] ## <quant>\n" .+            "$_[1] ## pos: @$RegexPos\n" .+            "$_[1] (\n" .+            join( ' && ', ($rul) x $count[0] ) .+            "\n" .+            "$_[1] )$ws3\n" .+            "$_[1] ## </quant>\n";+    }+    return+        "$_[1] ## <quant>\n" .+	"$_[1] ## pos: @$RegexPos\n" .+        "$_[1] (\n$rul\n" .+        "$_[1] || ( \$bool = 1 )\n" .+        "$_[1] )$ws3\n" .+        "$_[1] ## </quant>\n"+        if $quantifier eq '?';+    return+        "$_[1] ## <quant>\n" .+        "$_[1] ## pos: @$RegexPos\n" .+        "$_[1] do { while (\n$rul) {}; \$bool = 1 }$ws3\n" .+        "$_[1] ## </quant>\n"+        if $quantifier eq '*';+    return+        "$_[1] ## <quant>\n" .+        "$_[1] ## pos: @$RegexPos\n" .+        "$_[1] (\n$rul\n" .+        "$_[1] && do { while (\n$rul) {}; \$bool = 1 }\n" .+        "$_[1] )$ws3\n" .+        "$_[1] ## </quant>\n"+        if $quantifier eq '+';+    die "quantifier not implemented: $quantifier";+}++sub alt {+    my @s;+    # print 'Alt: ';+    my $count = $capture_count;+    my $max = -1;+    my $id = id();+    for ( @{$_[0]} ) {+        $capture_count = $count;+        my $tmp = emit_rule( $_, $_[1].'  ' );+        # print ' ',$capture_count;+        $max = $capture_count+            if $capture_count > $max;+        push @s, $tmp if $tmp;+    }+    $capture_count = $max;+    # print " max = $capture_count\n";+    return+        "$_[1] ## <alt>+$_[1] ## pos: @$RegexPos+$_[1] (+$_[1]     ( \$pad{$id} = \$pos or 1 )+$_[1]     && (+" . join( "+$_[1]     )+$_[1]   || (+$_[1]     ( ( \$bool = 1 ) && ( \$pos = \$pad{$id} ) or 1 )+$_[1]     && ",+          @s+    ) . "+$_[1]   )+$_[1] )+$_[1] ## </alt>\n";+}+sub alt1 { &alt }+sub conjunctive {+    my @s;+    # print 'conjunctive: ';+    my $count = $capture_count;+    my $max = -1;+    my $id = id();+    for ( @{$_[0]} ) {+        $capture_count = $count;+        my $tmp = emit_rule( $_, $_[1].'  ' );+        # print ' ',$capture_count;+        $max = $capture_count+            if $capture_count > $max;+        push @s, $tmp if $tmp;+    }+    $capture_count = $max;+    # print " max = $capture_count\n";+    return+        "$_[1] ## <conjunctive>+$_[1] ## pos: @$RegexPos+$_[1] (+$_[1]     ( \$pad{$id} = \$pos or 1 )+$_[1]     && (+" . join( "+$_[1]     )+$_[1]   && (+$_[1]     ( ( \$bool = 1 ) && ( \$pos = \$pad{$id} ) or 1 )+$_[1]     && ",+          @s+    ) . "+$_[1]   )+$_[1] )+$_[1] ## </conjunctive>\n";+}+sub conjunctive1 { &conjunctive }+sub concat {+    my @s;++=for optimizing+    # optimize for the common case of "words"+    # Note: this optimization has almost no practical effect+    my $is_constant = 0;+    for ( @{$_[0]} ) {+        if ( ! $sigspace && exists $_->{quant} ) {+            my $was_constant = $is_constant;+            $is_constant =+                   $_->{quant}->{quant} eq ''+                && exists $_->{quant}->{term}->{constant};+            #print "concat: ", Dumper( $_ );+            if ( $is_constant && $was_constant && $direction ne '-' ) {+                $s[-1]->{quant}->{term}->{constant} .=+                    $_->{quant}->{term}->{constant};+                #print "constant: ",$s[-1]->{quant}->{term}->{constant},"\n";+                next;+            }+        }+        push @s, $_;+    }++    for ( @s ) {+        $_ = emit_rule( $_, $_[1] );+    }+=cut++    # Try to remove non-greedy quantifiers, by inserting a lookahead;+    # cheat: / .*? b /+    # into:  / [ <!before b> . ]* b /+    # TODO - make it work for '+' quantifier too+    for my $i ( 0 .. @{$_[0]} - 1 ) {+        if (   exists $_[0][$i]{quant}+            && $_[0][$i]{quant}{quant}  eq '*'+            && $_[0][$i]{quant}{greedy} eq '?'+        ) {+            my $tmp = { quant => {+                    %{ $_[0][$i]{quant} },+                    greedy => '', quant => ''+                },+                _pos => $_[0][$i]{_pos}+            };+            $_[0][$i] = {+                _pos => $_[0][$i]{_pos},+                quant => {+                    greedy => '',+                    quant  => $_[0][$i]{quant}{quant},+                    ws1    => '',+                    ws2    => '',+                    ws3    => '',+                    term   => {+                        _pos => $_[0][$i]{_pos},+                        concat => [+                            {+                                _pos => $_[0][$i]{_pos},+                                before => {+                                    rule     => {+                                        _pos => $_[0][$i]{_pos},+                                        concat => [+                                            @{ $_[0] }[$i+1 .. $#{ $_[0] } ]+                                        ],+                                    },+                                    modifier => '!',+                                }+                            },+                            $tmp,+                        ],+                    },+                },+            };+            #warn "Quant: ",Dumper($_[0]);+        }+    }++    for ( @{$_[0]} ) {+        my $tmp = emit_rule( $_, $_[1] );+        push @s, $tmp if $tmp;+    }+    @s = reverse @s if $direction eq '-';+    return+"$_[1] ## <concat>+$_[1] ## pos: @$RegexPos+$_[1] (\n" . join( "\n$_[1] &&\n", @s ) . "+$_[1] )+$_[1] ## </concat>\n";+}++sub code {+    return "$_[1] $_[0]\n";+}++sub dot {+    "+$_[1] ## <dot>+$_[1] ## pos: @$RegexPos+$_[1] ( substr( \$s, \$pos$direction$direction, 1 ) ne '' )+$_[1] ## </dot>\n"+}++sub variable {+    my $name = "$_[0]";+    my $value = undef;+    # XXX - eval $name doesn't look up in user lexical pad+    # XXX - what &xxx interpolate to?++    #print "VAR: $name \n";+    # expand embedded $scalar+    if ( $name =~ /^\$/ ) {+        # $^a, $^b+        if ( $name =~ /^ \$ \^ ([^\s]*) /x ) {+            my $index = ord($1)-ord('a');+            #print "Variable #$index\n";+            #return "$_[1] constant( \$_[7][$index] )\n";++            my $code =+            "    ... sub {+                #print \"Runtime Variable args[\", join(\",\",\@_) ,\"] \$_[7][$index]\\n\";+                return constant( \$_[7][$index] )->(\@_);+            }";+            $code =~ s/^/$_[1]/mg;+            return "$code\n";+        }++            $value = eval $name;+    }++    # expand embedded @arrays+    if ( $name =~ /^\@/ ) {+      my $code = q!+          join(+            '|',+            ! . $name . q!+          )+      !;+    return+"$_[1] ## <variable>+$_[1] ## pos: @$RegexPos+$_[1] ( eval( '( substr( \$s, \$pos ) =~ m/^(' . $code . ')/ )+$_[1]     ? ( \$pos $direction= length( \$1 ) or 1 )+$_[1]     : 0+$_[1]    ') )+$_[1] ## </variable>\n";+    }++    # expand embedded %hash+    if ( $name =~ /^%/ ) {+        my $id = '$' . id();+        my $preprocess_hash = 'Pugs::Runtime::Regex::preprocess_hash';+        my $code =+"+          ## <variable>+          ## pos: @$RegexPos+          do {+            our $id;+            our ${id}_sizes;+            unless ( $id ) {+                my \$hash = \\$name;+                my \%sizes = map { length(\$_) => 1 } keys \%\$hash;+                ${id}_sizes = [ sort { \$b <=> \$a } keys \%sizes ];+                " . #print \"sizes: \@${id}_sizes\\n\";+                "$id = \$hash;+            }+            " . #print 'keys: ',Dumper( $id );+            "my \$match = 0;+            my \$key;+            for ( \@". $id ."_sizes ) {+                \$key = ( \$pos <= length( \$s )+                            ? substr( \$s, \$pos, \$_ )+                            : '' );+                " . #print \"try ".$name." \$_ = \$key; \$s\\\n\";+                "if ( exists ". $id ."->{\$key} ) {+                    #\$named{KEY} = \$key;+                    #\$::_V6_MATCH_ = \$m;+                    #print \"m: \", Dumper( \$::_V6_MATCH_->data )+                    #    if ( \$key eq 'until' );+                    " . #print \"* ".$name."\{'\$key\'} at \$pos \\\n\";+                    "\$match = $preprocess_hash( $id, \$key )->( \$s, \$grammar, { p => ( \$pos + \$_ ), positionals => [ ], args => { KEY => \$key } }, undef );+                    " . #print \"match: \", Dumper( \$match->data );+                    "last if \$match;+                }+            }+            if ( \$match ) {+                \$pos = \$match->to;+                #print \"match: \$key at \$pos = \", Dumper( \$match->data );+                \$bool = 1;+            }; # else { \$bool = 0 }+            \$match;+          }+          ## </variable>+";+        #print $code;+        return $code;+    }+    die "interpolation of $name not implemented"+        unless defined $value;++    return call_constant( $value, $_[1] );+}+sub special_char {+    my ($char, $data) = $_[0] =~ /^.(.)(.*)/;++    return call_perl5( '\\N{$data}', $_[1] )+        if $char eq 'c';+    return call_perl5( '(?!\\N{$data}).', $_[1] )+        if $char eq 'C';++    return call_perl5( '\\x{'.$data.'}', $_[1] )+        if $char eq 'x';+    return call_perl5( '(?!\\x{'.$data.'}).', $_[1] )+        if $char eq 'X';++    return special_char( sprintf("\\x%X", oct($data) ) )+        if $char eq 'o';+    return special_char( sprintf("\\X%X", oct($data) ) )+        if $char eq 'O';++    return  call_perl5( '(?:\n\r?|\r\n?)', $_[1] )+        if $char eq 'n';+    return  call_perl5( '(?!\n\r?|\r\n?).', $_[1] )+        if $char eq 'N';++    # XXX - Infinite loop in pugs stdrules.t+    #return metasyntax( '?_horizontal_ws', $_[1] )+    return call_perl5( '[\x20\x09]' )+        if $char eq 'h';+    return call_perl5( '[^\x20\x09]' )+        if $char eq 'H';+    #return metasyntax( '?_vertical_ws', $_[1] )+    return call_perl5( '[\x0A\x0D]' )+        if $char eq 'v';+    return call_perl5( '[^\x0A\x0D]' )+        if $char eq 'V';++    for ( qw( r n t e f w d s ) ) {+        return call_perl5(   "\\$_",  $_[1] ) if $char eq $_;+        return call_perl5( "[^\\$_]", $_[1] ) if $char eq uc($_);+    }+    $char = '\\\\' if $char eq '\\';+    ### special char: $char+    return call_constant( $char, $_[1] );+}++sub match_variable {+    my $name = $_[0];+    my $num = substr($name,1);+    #print "var name: ", $num, "\n";++    return+"+$_[1] ## <match_variable>+$_[1] ## pos: @$RegexPos+$_[1] ( eval( '( substr( \$s, \$pos ) =~ m/^(' . \$m->{$num} . ')/ )+$_[1]     ? ( \$pos $direction= length( \$1 ) or 1 )+$_[1]     : 0+$_[1]    ') )+$_[1] ## </match_varaible>+";+}++sub closure {+    #print "closure: ",Dumper($_[0]);+    my $code     = $_[0]{closure};+    my $modifier = $_[0]{modifier};  # 'plain', '', '?', '!'++    die "invalid closure modifier: . "+        if $modifier eq '.';++    #die "closure modifier not implemented '$modifier'"+    #    unless $modifier eq 'plain';++    if (   ref( $code )+        && defined $Pugs::Compiler::Perl6::VERSION+    ) {+        #print " perl6 compiler is loaded \n";+        $code = Pugs::Emitter::Perl6::Perl5::emit( 'grammar', $code, 'self' );+        $code = '{ my $_V6_SELF = shift; ' . $code . '}';  # make it a "method"+    }+    else {+        #print " perl6 compiler is NOT loaded \n";+        # XXX XXX XXX - source-filter - temporary hacks to translate p6 to p5+        # $()<name>+        $code =~ s/ ([^']) \$ \$ (\d+) /$1\${ \$_[0]->[$2] }/sgx;+        $code =~ s/ ([^']) \$ (\d+) /$1\$_[0]->[$2]/sgx;+        $code =~ s/ ([^']) \$ \( \) < (.*?) > /$1\$_[0]->{$2}/sgx;+        # $<name>+        $code =~ s/ ([^']) \$ \$ < (.*?) > /$1\${ \$_[0]->{qw($2)} }/sgx;+        $code =~ s/ ([^']) \$ < (.*?) > /$1\$_[0]->{qw($2)}/sgx;+        # $()+        $code =~ s/ ([^']) \$ \( \) /$1\$_[0]->()/sgx;+        # $/+        $code =~ s/ ([^']) \$ \/ ([\{\[]) /$1\$_[0]->$2/sgx;+        $code =~ s/ ([^']) \$ \/ /$1\$_[0]/sgx;+        #$code =~ s/ use \s+ v6 \s* ; / # use v6\n/sgx;+    }+    #print "Code: $code\n";+    # "plain" {...return ...}+    return+          "$_[1] ## <closure>\n"+        . "$_[1] ## pos: @$RegexPos\n"+        . "$_[1] do {\n"+        . "$_[1]   local \$::_V6_SUCCEED = 1;\n"+        . "$_[1]   \$::_V6_MATCH_ = \$m;\n"+        . "$_[1]   \$m->data->{capture} = \\( sub $code->( \$m ) ); \n"+        . "$_[1]   \$bool = \$::_V6_SUCCEED;\n"+        . "$_[1]   \$::_V6_MATCH_ = \$m if \$bool; \n"+        . "$_[1]   return \$m if \$bool; \n"+        . "$_[1] }\n"+        . "$_[1] ## </closure>\n"+        if $code =~ /return/;++    # "plain" {...} without return+    return+          "$_[1] ## <closure>\n"+        . "$_[1] ## pos: @$RegexPos\n"+        . "$_[1] do { \n"+        . "$_[1]   local \$::_V6_SUCCEED = 1;\n"+        . "$_[1]   \$::_V6_MATCH_ = \$m;\n"+        . "$_[1]   sub $code->( \$m );\n"+        . "$_[1]   1;\n"+        . "$_[1] }\n"+        . "$_[1] ## </closure>\n"+        if $modifier eq 'plain';+    # "?" <?{...}>+    return+        "$_[1] ## <closure>\n" .+        "$_[1] ## pos: @$RegexPos\n" .+        "$_[1] do { \n" .+        "$_[1]   local \$::_V6_SUCCEED = 1;\n" .+        "$_[1]   \$::_V6_MATCH_ = \$m;\n" .+        "$_[1]   \$bool = ( sub $code->( \$m ) ) ? 1 : 0; \n" .+        "$_[1] }" .+        "$_[1] ## </closure>\n"+        if $modifier eq '?';+    # "!" <!{...}>+    return+        "$_[1] ## <closure>\n" .+        "$_[1] ## pos: @$RegexPos\n" .+        "$_[1] do { \n" .+        "$_[1]   local \$::_V6_SUCCEED = 1;\n" .+        "$_[1]   \$::_V6_MATCH_ = \$m;\n" .+        "$_[1]   \$bool = ( sub $code->( \$m ) ) ? 0 : 1; \n" .+        "$_[1] }" .+        "$_[1] ## </closure>\n"+        if $modifier eq '!';++}+sub capturing_group {+    my $program = $_[0];++    $capture_count++;+    {+        local $capture_count = -1;+        local $capture_to_array = 0;+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }++    return "+$_[1] ## <capture>+$_[1] do{+$_[1]     my \$hash = do {+$_[1]       my \$bool = 1;+$_[1]       my \$from = \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool = 0 unless+" .             $program . ";+$_[1]       { str => \\\$s, from => \\\$from, match => \\\@match, named => \\\%named, bool => \\\$bool, to => \\(0+\$pos), capture => undef }+$_[1]     };+$_[1]     my \$bool = \${\$hash->{'bool'}};" .+        ( $capture_to_array+        ? "+$_[1]     if ( \$bool ) {+$_[1]         push \@{ \$match[ $capture_count ] }, Pugs::Runtime::Match->new( \$hash );+$_[1]     }"+        : "+$_[1]     \$match[ $capture_count ] = Pugs::Runtime::Match->new( \$hash );"+        ) . "+$_[1]     \$bool;+$_[1] }+$_[1] ## </capture>\n";+}++sub capture_as_result {+    my $program = $_[0];++    $capture_count++;+    {+        local $capture_count = -1;+        local $capture_to_array = 0;+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }+    return "$_[1] ## <capture>+$_[1] ## pos: @$RegexPos+$_[1] do{+$_[1]     my \$hash = do {+$_[1]       my \$bool = 1;+$_[1]       my \$from = \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool = 0 unless+" .             $program . ";+$_[1]       { str => \\\$s, from => \\\$from, match => \\\@match, named => \\\%named, bool => \\\$bool, to => \\(0+\$pos), capture => undef }+$_[1]     };+$_[1]     my \$bool = \${\$hash->{'bool'}};+$_[1]     \$m->data->{capture} = \\( \"\" . Pugs::Runtime::Match->new( \$hash ) );+$_[1]     \$bool;+$_[1] }+$_[1] ## </capture>\n";+}+sub named_capture {+    my $name    = $_[0]{ident};+    ### $name+    if (ref($name) eq 'HASH') {+        $name = $name->{match_variable} || $name->{variable};+    }+    $name =~ s/^[\$\@\%]//;  # TODO - change semantics as needed+    my $program = $_[0]{rule};+    #warn "name [$name]\n";++    if ( exists $program->{metasyntax} ) {+        #print "aliased subrule\n";+        # $/<name> = $/<subrule>++        my $cmd = $program->{metasyntax}{metasyntax};+        die "invalid aliased subrule"+            unless $cmd =~ /^[_[:alnum:]]/;++        # <subrule ( param, param ) >+        my ( $subrule, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+        return "$_[1] ## <named_capture>+$_[1] ## pos: @$RegexPos+$_[1] do {+                my \$prior = \$::_V6_PRIOR_;+                my \$match =\n" .+                    call_subrule( $subrule, $_[1]."        ", "", @param ) . ";+                \$::_V6_PRIOR_ = \$prior;+                if ( \$match ) {" .+                    ( $capture_to_array+                    ? " push \@{\$named{'$name'}}, \$match;"+                    : " \$named{'$name'} = \$match;"+                    ) . "+                    \$pos = \$match->to;+                    1+                }+                else { 0 }+            }+$_[1] ## </named_capture>\n";+    }+    elsif ( exists $program->{capturing_group} ) {+        #print "aliased capturing_group\n";+        # $/<name> = $/[0]+        {+            local $capture_count = -1;+            local $capture_to_array = 0;+            $program = emit_rule( $program, $_[1].'      ' )+                if ref( $program );+        }+        return "$_[1] ## <named_capture>+$_[1] ## pos: @$RegexPos+$_[1] do{+                my \$match = Pugs::Runtime::Match->new( do {+                    my \$bool = 1;+                    my \$from = \$pos;+                    my \@match;+                    my \%named;+                    \$bool = 0 unless " .+                    $program . ";+                    { str => \\\$s, from => \\\$from, match => \\\@match, named => \\\%named, bool => \\\$bool, to => \\(0+\$pos), capture => undef }+                } );+                if ( \$match ) {" .+                    ( $capture_to_array+                    ? " push \@{\$named{'$name'}}, \$match;"+                    : " \$named{'$name'} = \$match;"+                    ) . "+                    \$pos = \$match->to;+                    1+                }+                else { 0 }+            }+$_[1] ## </named_capture>\n";+    }+    else {+        #print "aliased non_capturing_group\n";+        # $/<name> = "$/"+        #print Dumper( $_[0] );+        $program = emit_rule( $program, $_[1].'      ' );+        return "$_[1] ## <named_capture>+$_[1] ## pos: @$RegexPos+$_[1] do{+                my \$from = \$pos;+                my \$bool = $program;+                my \$match = Pugs::Runtime::Match->new(+                    { str => \\\$s, from => \\\$from, match => [], named => {}, bool => \\1, to => \\(0+\$pos), capture => undef }+                );" .+                ( $capture_to_array+                ? " push \@{\$named{'$name'}}, \$match;"+                : " \$named{'$name'} = \$match;"+                ) . "+                \$bool+            }+$_[1] ## </named_capture>\n";+    }+}+sub negate {+    my $program = $_[0];+    #print "Negate: ", Dumper($_[0]);+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] ## <negate>+$_[1] ## pos: @$RegexPos+$_[1] do{+$_[1]     my \$pos1 = \$pos;+$_[1]     do {+$_[1]       my \$pos = \$pos1;+$_[1]       my \$from = \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool = " . $program . " ? 0 : 1;+$_[1]       \$bool;+$_[1]     };+$_[1] }+$_[1] ## </negate>\n";+}++sub before {+    my $mod = delete $_[0]{modifier} || '';+    #### before atom: $_[0]+    return negate( { before => $_[0], _pos => $_[0]{rule}{_pos}, }, $_[1] ) if $mod eq '!';+    my $program = $_[0]{rule};+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "+$_[1] ## <before>+$_[1] ## pos: @$RegexPos+$_[1] do{+$_[1]     my \$pos1 = \$pos;+$_[1]     do {+$_[1]       my \$pos = \$pos1;+$_[1]       my \$from = \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool = 0 unless+" .             $program . ";+$_[1]       \$bool;+$_[1]     };+$_[1] }+$_[1] ## </before>\n";+}++sub after {+    my $mod = delete $_[0]{modifier};+    return negate( { after => $_[0] }, $_[1] ) if $mod eq '!';+    local $direction = "-";+    my $program = $_[0]{rule};+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] ## <after>+$_[1] ## pos: @$RegexPos+$_[1] do{+$_[1]     my \$pos1 = \$pos;+$_[1]     do {+$_[1]       my \$pos = \$pos1 - 1;+$_[1]       my \$from = \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool = 0 unless+" .             $program . ";+$_[1]       \$bool;+$_[1]     };+$_[1] }+$_[1] ## </after>\n";+}++sub colon {+    my $str = $_[0];+    return "$_[1] 1 # : no-op\n"+        if $str eq ':';+    return "$_[1] ( \$pos >= length( \$s ) )\n"+        if $str eq '$';+    return "$_[1] ( \$pos == 0 )\n"+        if $str eq '^';++    return "$_[1] ( \$pos >= length( \$s ) || substr( \$s, \$pos ) =~ ".'/^(?:\n\r?|\r\n?)/m'." )\n"+        if $str eq '$$';+    return "$_[1] ( \$pos == 0 || substr( \$s, 0, \$pos ) =~ ".'/(?:\n\r?|\r\n?)$/m'." )\n"+        if $str eq '^^';++    return metasyntax( { metasyntax => '_wb_left', modifier => '?' }, $_[1] )+        if $str eq '<<';+    return metasyntax( { metasyntax => '_wb_right', modifier => '?' }, $_[1] )+        if $str eq '>>';++    die "'$str' not implemented";+}+sub modifier {+    my $str = $_[0];+    die "modifier '$str' not implemented";+}+sub constant {+    call_constant( @_ );+}++sub char_class {+    my $cmd = Pugs::Emitter::Rule::Perl5::CharClass::emit( $_[0] );+    return call_perl5($cmd, $_[1]);+}++sub call {+    #die "not implemented: ", Dumper(\@_);+    my $param = $_[0]{params};+    my $name = $_[0]{method};+        # capturing subrule+        # <subrule ( param, param ) >+        my ($param_list) = $param =~ /\{(.*)\}/;+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+        #print "param: ", Dumper(\@param);++        # TODO++        if ( $name eq 'at' ) {+            $param_list ||= 0;   # XXX compile-time only+            return "$_[1] ( \$pos == $param_list )\n"+        }++        return named_capture(+            {+                ident => $name,+                rule => { metasyntax => { metasyntax => $name }, _pos => $_[0]{_pos}, },+            },+            $_[1],+        );+}++sub metasyntax {+    # <cmd>+    #print Dumper(\@_);+    my $cmd = $_[0]{metasyntax};+    my $modifier = delete $_[0]{modifier} || '';   # . ? !+    return negate( { metasyntax => $_[0], _pos => $_[0]{_pos} }, $_[1] ) if $modifier eq '!';++    my $prefix = substr( $cmd, 0, 1 );+    if ( $prefix eq '@' ) {+        # XXX - wrap @array items - see end of Pugs::Grammar::Rule+        # TODO - param list+        my $name = substr( $cmd, 1 );+        return+            "$_[1] ## <metasyntax>+$_[1] ## pos: @$RegexPos+$_[1] do {+                my \$match;+                for my \$subrule ( $cmd ) {+                    \$match = \$subrule->match( \$s, \$grammar, { p => ( \$pos ), positionals => [ ], args => {} }, undef );+                    last if \$match;+                }+                if ( \$match ) {" .+                    ( $capture_to_array+                    ? " push \@{\$named{'$name'}}, \$match;"+                    : " \$named{'$name'} = \$match;"+                    ) . "+                    \$pos = \$match->to;+                    1+                }+                else { 0 }+            }+$_[1] ## </metasyntax>\n";+    }++    if ( $prefix eq '%' ) {+        # XXX - runtime or compile-time interpolation?+        my $name = substr( $cmd, 1 );+        # print "<$cmd>\n";+        # return variable( $cmd );+        return "$_[1]## <metasyntax>+$_[1] ## pos: @$RegexPos+$_[1] do{+                my \$match = " . variable( $cmd, $_[1] ) . ";+                if ( \$match ) {" .+                    ( $capture_to_array+                    ? " push \@{\$named{'$name'}}, \$match;"+                    : " \$named{'$name'} = \$match;"+                    ) . "+                    \$pos = \$match->to;+                    1+                }+                else { 0 }+            }\n$_[1]## </metasyntax>\n";+    }++    if ( $prefix eq '$' ) {+        if ( $cmd =~ /::/ ) {+            # call method in fully qualified $package::var+            # ...->match( $rule, $str, $grammar, $flags, $state )+            # TODO - send $pos to subrule+            return+                "$_[1]         ## <metasyntax>\n" .+                "$_[1]         ## pos: @$RegexPos\n" .+                "$_[1]         do {\n" .+                "$_[1]           push \@match,\n" .+                "$_[1]             $cmd->match( \$s, \$grammar, {p => \$pos}, undef );\n" .+                "$_[1]           \$pos = \$match[-1]->to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }\n" .+                "$_[1]         ## </metasyntax>\n";+        }+        # call method in lexical $var+        # TODO - send $pos to subrule+        return+                "$_[1]         ## <metasyntax>\n" .+                "$_[1]         ## pos: @$RegexPos\n" .+                "$_[1]         do {\n" .+                "$_[1]           my \$r = Pugs::Runtime::Regex::get_variable( '$cmd' );\n" .+                "$_[1]           push \@match,\n" .+                "$_[1]             \$r->match( \$s, \$grammar, {p => \$pos}, undef );\n" .+                "$_[1]           \$pos = \$match[-1]->to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }\n" .+                "$_[1]         ## </metasyntax>\n";+    }+    if ( $prefix eq q(') ) {   # single quoted literal '+        $cmd = substr( $cmd, 1, -1 );+        return call_constant( $cmd, $_[1] );+    }+    if ( $prefix eq q(") ) {   # interpolated literal "+        $cmd = substr( $cmd, 1, -1 );+        warn "<\"...\"> not implemented";+        return;+    }+    if  ( +           $modifier eq '.' +        || $modifier eq '?'   # XXX FIXME+        )+    {   # non_capturing_subrule / code assertion+        #$cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+        my @param; # TODO+        my $subrule = $cmd;+        return+"$_[1] ## <metasyntax>+$_[1] ## pos: @$RegexPos+$_[1] do {+$_[1]      my \$prior = \$::_V6_PRIOR_;+$_[1]      my \$match =\n" .+               call_subrule( $subrule, $_[1]."        ", "", @param ) . ";+$_[1]      \$::_V6_PRIOR_ = \$prior;+$_[1]      my \$bool = (!\$match != 1);+$_[1]      \$pos = \$match->to if \$bool;+$_[1]      \$match;+$_[1] }+$_[1] ## </metasyntax>\n";+    }+    if ( $prefix =~ /[_[:alnum:]]/ ) {+        if ( $cmd eq 'cut' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'commit' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'null' ) {+            return "$_[1] 1 # null\n"+        }+        # <subrule ( param, param ) >+        my ( $subrule, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list ||= '';++        if ( $subrule eq 'at' ) {+            $param_list ||= 0;   # XXX compile-time only+            return "$_[1] ( \$pos == $param_list )\n"+        }++        return named_capture(+            {+                ident => $subrule,+                rule => { metasyntax => { metasyntax => $cmd }, _pos => $_[0]->{_pos} },+            },+            $_[1],+        );+    }+    #### $prefix+    #### $modifier+    #if ( $prefix eq '.' ) {+    #    my ( $method, $param_list ) = split( /[\(\)]/, $cmd );+    #    $method =~ s/^\.//;+    #    $param_list ||= '';+    #    return " ( \$s->$method( $param_list ) ? 1 : 0 ) ";+    #}+    die "<$cmd> not implemented";+}++1;
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl5/Regex.pm view
@@ -0,0 +1,250 @@+package Pugs::Emitter::Rule::Perl5::Regex;++# p6-rule perl5 emitter for emitting perl5 regexes++=for TODO++    plug into the :ratchet emitter++    @ (non-)interpolation (test)+    aliased, named captures+    nested captures+    quantified captures+    ranges++    die() on captures that would have wrong numbering+    +BUGS:+    - nested captures are not detected+    - set operations on character classes are not detected+    +=cut++use strict;+use warnings;+use Data::Dumper;+$Data::Dumper::Indent = 1;++our $capture_count;+our $capture_to_array;++sub emit {+    my ($grammar, $ast, $param) = @_;+    my $sigspace = $param->{sigspace};   +    local $capture_count = -1;+    local $capture_to_array = 0;+    #print "rule: ", Dumper( $ast );+    die "sigspace not supported in P5 mode (can't call <ws> subrule)"+        if $sigspace;+    my $p5regex = '(?m)' . emit_rule( $ast );+    # print ":P5/$p5regex/ \n";+    return $p5regex;+}++sub emit_rule {+    my $n = $_[0];+    die "unknown node: ", Dumper( $n )+        unless ref( $n ) eq 'HASH';+    #print "NODE ", Dumper($n);+    my ($k) = keys %$n;+    my $v = $$n{$k};+    # XXX - use real references+    no strict 'refs';+    #print "NODE ", Dumper($k), ", ", Dumper($v);+    my $code = &$k( $v, '' );+    return $code;+}++#rule nodes++sub non_capturing_group {+    return "(?:" . emit_rule( $_[0] ) . ")";+}        +sub quant {+    my $term = $_[0]->{'term'};+    my $quantifier = $_[0]->{quant}  || '';+    my $greedy     = $_[0]->{greedy} || '';   # + ?+    $greedy = '' if $greedy eq '+';+    #print "QUANT: ",Dumper($_[0]);+    # TODO: fix grammar to not emit empty quantifier+    die "ranges not implemented"+        if ref( $quantifier );+    my $rul;+    {+        #print "Term: ", Dumper($term), "\n";+        my $cap = $capture_to_array;+        local $capture_to_array = $cap || ( $quantifier ne '' );+        $rul = emit_rule( $term );+    }+    my $quant = $quantifier . $greedy;+    return "(?:$rul)$quant" if $quant;+    return $rul;    +}        +sub alt {+    my @s;+    my $count = $capture_count;+    my $max = -1;+    for ( @{$_[0]} ) { +        $capture_count = $count;+        my $tmp = emit_rule( $_ );+        # print ' ',$capture_count;+        $max = $capture_count +            if $capture_count > $max;+        push @s, $tmp;    # if $tmp;   +    }+    $capture_count = $max;+    # print " max = $capture_count\n";+    return +        "(?:" . join( "|", @s ) . ")";+}        +sub alt1 { &alt }+sub concat {+    return join( "",+        map { emit_rule( $_ ) } @{$_[0]}+    );+}        +sub code {+    die "code not implemented";+}        +sub dot { +    '(?:\n\r?|\r\n?|.)'+}++sub variable {+    die "variable interpolation not implemented";+}+sub special_char {+    my $char = substr($_[0],1);+    return     '(?:\n\r?|\r\n?)'+        if $char eq 'n';+    return     '(?!\n\r?|\r\n?).'+        if $char eq 'N';+    for ( qw( r t e f w d s ) ) {+        return "\\$_"    if $char eq $_;+        return "[^\\$_]" if $char eq uc($_);+    }+    return '\\' . $char;+}+sub match_variable {+    die "no match variables yet";+}+sub closure {+    die "no closures";+}+sub capturing_group {+    my $program = $_[0];+    die "capture to array not implemented"+        if $capture_to_array;+    $capture_count++;+    {+        local $capture_count = -1;+        local $capture_to_array = 0;+        $program = emit_rule( $program )+            if ref( $program );+    }+    return "(" . $program . ")"+}        +sub capture_as_result {+    die "return objects not implemented";+}        +sub named_capture {+    die "no named captures";+}+sub negate {+    die "no negate";+}+sub before {+    my $program = $_[0]{rule};+    $program = emit_rule( $program )+        if ref( $program );+    return "(?=" . $program . ")";+}+sub not_before {+    my $program = $_[0]{rule};+    $program = emit_rule( $program )+        if ref( $program );+    return "(?!" . $program . ")";+}+sub after {+    my $program = $_[0]{rule};+    $program = emit_rule( $program )+        if ref( $program );+    return "(?<=" . $program . ")";+}+sub not_after {+    my $program = $_[0]{rule};+    $program = emit_rule( $program )+        if ref( $program );+    return "(?<!" . $program . ")";+}+sub colon {+    my $str = $_[0];+    return '\z' +        if $str eq '$';+    return '\A' +        if $str eq '^';+    return '$' +        if $str eq '$$';+    return '^' +        if $str eq '^^';+    die "'$str' not implemented";+}+sub modifier {+    my $str = $_[0];+    die "modifier '$str' not implemented";+}+sub constant {+    return ""+        unless length($_[0]);+    return '\\/' if $_[0] eq '/';  +    return $_[0];  +}++use vars qw( %char_class );+BEGIN {+    %char_class = map { $_ => 1 } qw( +        alpha alnum ascii blank+        cntrl digit graph lower+        print punct space upper+        word  xdigit+    );+}++sub char_class {+    my $cmd = Pugs::Emitter::Rule::Perl5::CharClass::emit( $_[0] );+    return $cmd;+}++sub metasyntax {+    # <cmd>+    my $cmd = $_[0];   +    my $prefix = substr( $cmd, 0, 1 );+    if ( $prefix eq q(') ) {   # single quoted literal ' +        $cmd = substr( $cmd, 1, -1 );+        $cmd =~ s/([\$\@\%\[\]\+\*\(\)\?\/])/\\$1/g;+        return $cmd;+    }+    if ( $prefix eq '.' ) {   # non_capturing_subrule / code assertion+        $cmd = substr( $cmd, 1 );+        if ( exists $char_class{$cmd} ) {+            # XXX - inlined char classes are not inheritable, but this should be ok+            return "[[:$cmd:]]";+        }+    }+    if ( $prefix eq '?' ) {   # non_capturing_subrule / code assertion+        # XXX FIXME +        $cmd = substr( $cmd, 1 );+        if ( exists $char_class{$cmd} ) {+            # XXX - inlined char classes are not inheritable, but this should be ok+            return "[[:$cmd:]]";+        }+    }+    if ( $prefix =~ /[_[:alnum:]]/ ) {  +        if ( $cmd eq 'null' ) {+            return ""+        }+    }+    die "<$cmd> not implemented";+}++1;
+ blib6/pugs/perl5/lib/Pugs/Emitter/Rule/Perl6/Ratchet.pm view
@@ -0,0 +1,854 @@+package Pugs::Emitter::Rule::Perl6::Ratchet;++# p6-rule perl5 emitter for ":ratchet" (non-backtracking)+# see: RuleInline.pl, RuleInline-more.pl for a program prototype++use strict;+use warnings;+use Data::Dumper;+$Data::Dumper::Indent = 1;++our $direction = "+";  # XXX make lexical+our $sigspace = 0;+our $capture_count;+our $capture_to_array;++our $count = 1000 + int(rand(1000));+sub id { 'I' . ($count++) }++# Calling convention:  +# $grammar.$rule({ str => '...', pos => $pos, other_arg => $x })++=for global vars++    class Grammar::Base {+        my $.PRIOR;+    }++    Grammar::Base.PRIOR := $rule;++=cut++sub call_subrule {+    my ( $subrule, $tab, @param ) = @_;+    $subrule = "\$grammar." . $subrule +        unless $subrule =~ / :: | \. | -> /x;+    return +"$tab     $subrule( { str => \$str, pos => \$m.to, " .+             join(", ",@param) . +         " }, undef )";+}++sub quote_constant {+    my $const;+    if ( $_[0] eq "\\" ) {+        $const = "chr(".ord("\\").")";+    }+    elsif ( $_[0] eq "'" ) {+        $const = "chr(".ord("'").")"+    }+    else {+        $const = "'$_[0]'"+    }+    return $const;+}++sub call_constant {+    return " 1 # null constant\n"+        unless length($_[0]);+    my $const = quote_constant( $_[0] );+    my $len = length( eval $const );+    #print "Const: [$_[0]] $const $len \n";    +    return+"$_[1] ( ( substr( \$str, \$m.to, $len ) eq $const ) +$_[1]     ? ( (\$m.to := ( \$m.to $direction $len ) or 1 )+$_[1]     : 0+$_[1] )";+}++sub call_perl5 {+    my $const = $_[0];+    #print "CONST: $const - $direction \n";+    return+"$_[1] ( ( substr( \$str, \$m.to ) =~ m:P5/^($const)/ )  +$_[1]     ? ( \$m.to := \$m.to $direction length( \$1 ) or 1 )+$_[1]     : 0+$_[1] )";+}++sub emit {+    my ($grammar, $ast, $param) = @_;+    # runtime parameters: $grammar, $string, $state, $arg_list+    # rule parameters: see Runtime::Rule.pm+    local $sigspace = $param->{sigspace};   # XXX - $sigspace should be lexical+    local $capture_count = -1;+    local $capture_to_array = 0;+    #print "rule: ", Dumper( $ast );+    return +        'do { my $rule; $rule = method ($grammar: {:$str, :$pos, :$continue, :$KEY}) {' . +"+  my \$m;+  for ( defined \$pos && ! \$continue+        ? \$pos +        : ( ( \$pos || 0 ) .. length( \$str ) ) +      ) -> \$pos1 {+    my \%pad;+    my \%named;+    \%named{KEY} := \$KEY +        if defined \$KEY;+    \$m := Pugs::Runtime::Match( { +      str => \$str, from => (0+\$pos1), to => \$pos1, +      bool => 1, match => [], named => \%named, capture => undef, +    } );+    {+      my \$prior := Grammar::Base.PRIOR;+      temp Grammar::Base.PRIOR := \$prior; +      \$m.bool := 0 unless+" .+        #"      do { TAILCALL: ;\n" .+        emit_rule( $ast, '    ' ) . ";+    }+    if ( \$m.bool ) {+      my \$prior := Grammar::Base.PRIOR;+      Grammar::Base.PRIOR := sub { +        temp Grammar::Base.PRIOR := \$prior; +        \$rule.(\@_);+      };+      last;+    }+  } # /for+  # Grammar::Base.MATCH := \$m;   # this must be set in the caller side+  return \$m;+} }+";+}++sub emit_rule {+    my $n = $_[0];+    my $tab = $_[1] . '  ';+    die "unknown node: ", Dumper( $n )+        unless ref( $n ) eq 'HASH';+    #print "NODE ", Dumper($n);+    my ($k) = keys %$n;+    my $v = $$n{$k};+    # XXX - use real references+    no strict 'refs';+    #print "NODE ", Dumper($k), ", ", Dumper($v);+    my $code = &$k( $v, $tab );+    return $code;+}++#rule nodes++sub non_capturing_group {+    return emit_rule( $_[0], $_[1] );+}        +sub quant {+    my $term = $_[0]->{'term'};+    my $quantifier = $_[0]->{quant}  || '';+    my $greedy     = $_[0]->{greedy} || '';   # + ?+    die "greediness control not implemented: $greedy"+        if $greedy;+    #print "QUANT: ",Dumper($_[0]);+    # TODO: fix grammar to not emit empty quantifier+    my $tab = ( $quantifier eq '' ) ? $_[1] : $_[1] . "  ";+    my $ws = metasyntax( '?ws', $tab );+    my $ws3 = ( $sigspace && $_[0]->{ws3} ne '' ) ? " &&\n$ws" : '';++    my $rul;+    {+        #print "Term: ", Dumper($term), "\n";+        my $cap = $capture_to_array;+        local $capture_to_array = $cap || ( $quantifier ne '' );+        $rul = emit_rule( $term, $tab );+    }++    $rul = "$ws &&\n$rul" if $sigspace && $_[0]->{ws1} ne '';+    $rul = "$rul &&\n$ws" if $sigspace && $_[0]->{ws2} ne '';+    #print $rul;+    return $rul +        if $quantifier eq '';+    # *  +  ?+    # TODO: *? +? ??+    # TODO: *+ ++ ?++    # TODO: quantifier + capture creates Array+    return +        "$_[1] (\n$rul\n" .+        "$_[1] || ( \$m.bool = 1 )\n" .+        "$_[1] ) $ws3"+        if $quantifier eq '?';+    return +        "$_[1] do { while (\n$rul) {}; \$m.bool := 1 }$ws3"+        if $quantifier eq '*';+    return+        "$_[1] (\n$rul\n" .+        "$_[1] && do { while (\n$rul) {}; \$m.bool := 1 }\n" .+        "$_[1] ) $ws3"+        if $quantifier eq '+';+    die "quantifier not implemented: $quantifier";+}        +sub alt {+    my @s;+    # print 'Alt: ';+    my $count = $capture_count;+    my $max = -1;+    my $id = id();+    for ( @{$_[0]} ) { +        $capture_count = $count;+        my $tmp = emit_rule( $_, $_[1].'  ' );+        # print ' ',$capture_count;+        $max = $capture_count +            if $capture_count > $max;+        push @s, $tmp if $tmp;   +    }+    $capture_count = $max;+    # print " max = $capture_count\n";+    return +        "$_[1] (+$_[1]     ( \%pad{$id} := \$m.to or 1 ) +$_[1]     && (+" . join( "+$_[1]     ) +$_[1]   || ( +$_[1]     ( ( \$m.bool := 1 ) && ( \$m.to := \%pad{$id} ) or 1 ) +$_[1]     && ", +          @s +    ) . "+$_[1]   )+$_[1] )";+}        +sub alt1 { &alt }+sub conjunctive {+    my @s;+    # print 'conjunctive: ';+    my $count = $capture_count;+    my $max = -1;+    my $id = id();+    for ( @{$_[0]} ) { +        $capture_count = $count;+        my $tmp = emit_rule( $_, $_[1].'  ' );+        # print ' ',$capture_count;+        $max = $capture_count +            if $capture_count > $max;+        push @s, $tmp if $tmp;   +    }+    $capture_count = $max;+    # print " max = $capture_count\n";+    return +        "$_[1] (+$_[1]     ( \%pad{$id} := \$m.to or 1 ) +$_[1]     && (+" . join( "+$_[1]     ) +$_[1]   && ( +$_[1]     ( ( \$m.bool := 1 ) && ( \$m.to := \%pad{$id} ) or 1 ) +$_[1]     && ", +          @s +    ) . "+$_[1]   )+$_[1] )";+}        +sub concat {+    my @s;++=for optimizing+    # optimize for the common case of "words"+    # Note: this optimization has almost no practical effect+    my $is_constant = 0;+    for ( @{$_[0]} ) {+        if ( ! $sigspace && exists $_->{quant} ) {+            my $was_constant = $is_constant;+            $is_constant = +                   $_->{quant}->{quant} eq ''+                && exists $_->{quant}->{term}->{constant};+            #print "concat: ", Dumper( $_ );+            if ( $is_constant && $was_constant && $direction ne '-' ) {+                $s[-1]->{quant}->{term}->{constant} .=+                    $_->{quant}->{term}->{constant};+                #print "constant: ",$s[-1]->{quant}->{term}->{constant},"\n";+                next;+            }+        }+        push @s, $_;+    }++    for ( @s ) { +        $_ = emit_rule( $_, $_[1] );+    }+=cut++    for ( @{$_[0]} ) {+        my $tmp = emit_rule( $_, $_[1] );+        push @s, $tmp if $tmp;   +    }+    @s = reverse @s if $direction eq '-';+    return "$_[1] (\n" . join( "\n$_[1] &&\n", @s ) . "\n$_[1] )";+}        +sub code {+    return "$_[1] $_[0]\n";  +}        +sub dot {+    "$_[1] ( substr( \$s, \$m.to$direction$direction, 1 ) ne '' )"+}++sub variable {+    my $name = "$_[0]";+    my $value = undef;+    # XXX - eval $name doesn't look up in user lexical pad+    # XXX - what &xxx interpolate to?+    +    if ( $name =~ /^\$/ ) {+        # $^a, $^b+        if ( $name =~ /^ \$ \^ ([^\s]*) /x ) {+            my $index = ord($1)-ord('a');+            #print "Variable #$index\n";+            #return "$_[1] constant( \$_[7][$index] )\n";+            +            my $code = +            "    ... sub { +                #print \"Runtime Variable args[\", join(\",\",\@_) ,\"] \$_[7][$index]\\n\";+                return constant( \$_[7][$index] ).(\@_);+            }";+            $code =~ s/^/$_[1]/mg;+            return "$code\n";+        }+        else {+            $value = eval $name;+        }+    }+    +    $value = join('', eval $name) if $name =~ /^\@/;+    if ( $name =~ /^%/ ) {+        my $id = '$' . id();+        my $preprocess_hash = 'Pugs::Runtime::Regex::preprocess_hash';+        my $code = "+          do {+            state $id;+            state ${id}_sizes;+            unless ( $id ) {+                my \$hash := $name;+                my \%sizes := \%\$hash.keys.map:{ .length => 1 };+                ${id}_sizes := [ \%sizes.keys.sort:{ \$^b <=> \$^a } ];+                " . #print \"sizes: \@${id}_sizes\\n\";+                "$id = \$hash;+            }+            " . #print 'keys: ',Dumper( $id );+            "my \$match := 0;+            my \$key;+            for \@". $id ."_sizes {+                \$key := ( \$m.to <= length( \$s ) +                            ? substr( \$s, \$m.to, \$_ )+                            : '' );+                " . #print \"try ".$name." \$_ = \$key; \$s\\\n\";+                "if ( %". $id .".exists( \$key ) ) {+                    " . #\$named{KEY} = \$key;+                    #Grammar::Base.MATCH := \$m; +                    #print \"m: \", Dumper( Grammar::Base.MATCH )+                    #    if ( \$key eq 'until' );+                    #print \"* ".$name."\{'\$key\'} at \$m.to \\\n\";+                    "\$match = $preprocess_hash( $id, \$key ).({ str => \$str, grammar => \$grammar, pos => ( \$m.to + \$_ ), KEY => \$key });+                    " . #print \"match: \", Dumper( \$match.data );+                    "last if \$match;+                }+            }+            if ( \$match ) {+                \$m.to = \$match.to;+                " . #print \"match: \$key at \$m.to = \", Dumper( \$match.data );+                "\$match.bool = 1;+            }; +            \$match;+          }";+        #print $code;+        return $code;+    }+    die "interpolation of $name not implemented"+        unless defined $value;++    return call_constant( $value, $_[1] );+}+sub special_char {+    my $char = substr($_[0],1);+    return  call_perl5( '(?:\n\r?|\r\n?)', $_[1] )+        if $char eq 'n';+    return  call_perl5( '(?!\n\r?|\r\n?).', $_[1] )+        if $char eq 'N';+    for ( qw( r n t e f w d s ) ) {+        return call_perl5(   "\\$_",  $_[1] ) if $char eq $_;+        return call_perl5( "[^\\$_]", $_[1] ) if $char eq uc($_);+    }+    $char = '\\\\' if $char eq '\\';+    return call_constant( $char, $_[1] );+}+sub match_variable {+    my $name = $_[0];+    my $num = substr($name,1);+    #print "var name: ", $num, "\n";+    my $code = +    "    ... sub { +        my \$m = Pugs::Runtime::Match( \$_[2] );+        return constant( \"\$m.[$num]\" ).(\@_);+    }";+    $code =~ s/^/$_[1]/mg;+    return "$code\n";+}+sub closure {+    my $code = $_[0]; +    +    if ( ref( $code ) ) {+        if ( defined $Pugs::Compiler::Perl6::VERSION ) {+            #print " perl6 compiler is loaded \n";+            my $perl5 = Pugs::Emitter::Perl6::Perl5::emit( 'grammar', $code, 'self' );+            return +                "do { +                    temp Grammar::Base.MATCH   := \$m; +                    temp Grammar::Base.SUCCEED := 1;+                    \$m.capture := sub $perl5.();+                    \$m.bool := Grammar::Base.SUCCEED;+                    Grammar::Base.MATCH := \$m if \$m.bool; +                    return \$m if \$m.bool;+                }" if $perl5 =~ /return/;+            return +                "do { +                    Grammar::Base.MATCH := \$m; +                    temp Grammar::Base.SUCCEED := 1;+                    sub $perl5.();+                    Grammar::Base.SUCCEED;+                }";+        }        +    }++    #print " perl6 compiler is NOT loaded \n";+    #print "Code: $code\n";+    +    return +        "$_[1] do {\n" .+        "$_[1]   local Grammar::Base.SUCCEED := 1;\n" .+        "$_[1]   Grammar::Base.MATCH := \$m;\n" .+        "$_[1]   sub $code.( \$m );\n" .+        "$_[1]   Grammar::Base.SUCCEED;\n" .+        "$_[1] }" +        unless $code =~ /return/;+        +    return+        "$_[1] do { \n" .+        "$_[1]   local Grammar::Base.SUCCEED := 1;\n" .+        "$_[1]   Grammar::Base.MATCH := \$m;\n" .+        "$_[1]   \$m.capture := \\( sub $code.( \$m ) ); \n" .+        "$_[1]   \$m.bool := Grammar::Base.SUCCEED;\n" .+        "$_[1]   Grammar::Base.MATCH := \$m if \$m.bool; \n" .+        "$_[1]   return \$m if \$m.bool; \n" .+        "$_[1] }";++}+sub capturing_group {+    my $program = $_[0];++    $capture_count++;+    {+        local $capture_count = -1;+        local $capture_to_array = 0;+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }++    return "$_[1] do{ +$_[1]     my \$hash := do {+$_[1]       my \$bool := 1;+$_[1]       my \$from := \$m.to;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool := 0 unless+" .             $program . ";+$_[1]       { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => (0+\$m.to), capture => undef }+$_[1]     };+$_[1]     my \$bool = \$hash.{'bool'};" .+        ( $capture_to_array +        ? "+$_[1]     if ( \$bool ) {+$_[1]         push \@( \$match[ $capture_count ] ), Pugs::Runtime::Match( \$hash );+$_[1]     }"+        : "+$_[1]     \$match[ $capture_count ] = Pugs::Runtime::Match( \$hash );"+        ) . "+$_[1]     \$bool;+$_[1] }";+}        ++sub capture_as_result {+    my $program = $_[0];++    $capture_count++;+    {+        local $capture_count = -1;+        local $capture_to_array = 0;+        $program = emit_rule( $program, $_[1].'      ' )+            if ref( $program );+    }+    return "$_[1] do{ +$_[1]     my \$hash := do {+$_[1]       my \$bool := 1;+$_[1]       my \$from := \$m.to;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool := 0 unless+" .             $program . ";+$_[1]       { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => (0+\$m.to), capture => undef }+$_[1]     };+$_[1]     my \$bool := \$hash.{'bool'};+$_[1]     \$m.capture := ~Pugs::Runtime::Match( \$hash );+$_[1]     \$bool;+$_[1] }";+}        +sub named_capture {+    my $name    = $_[0]{ident};+    $name = $name->{match_variable} if ref($name) eq 'HASH';+    $name =~ s/^[\$\@\%]//;  # TODO - change semantics as needed+    my $program = $_[0]{rule};+    #print "name [$name]\n";+    +    if ( exists $program->{metasyntax} ) {+        #print "aliased subrule\n";+        # $/<name> = $/<subrule>+        +        my $cmd = $program->{metasyntax};+        die "invalid aliased subrule" +            unless $cmd =~ /^[_[:alnum:]]/;+        +        # <subrule ( param, param ) >+        my ( $subrule, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list = '' unless defined $param_list;+        my @param = split( ',', $param_list );+        return "$_[1] do { +                my \$prior := \$::_V6_PRIOR_; +                my \$match := \n" . +                    call_subrule( $subrule, $_[1]."        ", @param ) . ";+                \$::_V6_PRIOR_ := \$prior; +                if ( \$match ) {" .+                    ( $capture_to_array +                    ? " push \@(\$named{'$name'}), \$match;" +                    : " \$named{'$name'} := \$match;"+                    ) . "+                    \$m.to := \$match.to; +                    1 +                } +                else { 0 }+            }";+    }+    elsif ( exists $program->{capturing_group} ) {+        #print "aliased capturing_group\n";+        # $/<name> = $/[0]+        {+            local $capture_count = -1;+            local $capture_to_array = 0;+            $program = emit_rule( $program, $_[1].'      ' )+                if ref( $program );+        }+        return "$_[1] do{ +                my \$match := Pugs::Runtime::Match( do {+                    my \$bool := 1;+                    my \$from := \$m.to;+                    my \@match;+                    my \%named;+                    \$bool := 0 unless " .+                    $program . ";+                    { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => (0+\$m.to), capture => undef }+                } );+                if ( \$match ) {" .+                    ( $capture_to_array +                    ? " push \@(\$named{'$name'}), \$match;" +                    : " \$named{'$name'} := \$match;"+                    ) . "+                    \$m.to := \$match.to; +                    1 +                } +                else { 0 }+            }";+    }+    else {+        #print "aliased non_capturing_group\n";+        # $/<name> = "$/"+        #print Dumper( $_[0] );+        $program = emit_rule( $program, $_[1].'      ' );+        return "$_[1] do{ +                my \$from := \$m.to;+                my \$bool := $program;+                my \$match := Pugs::Runtime::Match( +                    { str => \$s, from => \$from, match => [], named => {}, bool => 1, to => (0+\$m.to), capture => undef }+                );" .+                ( $capture_to_array +                ? " push \@(\$named{'$name'}), \$match;" +                : " \$named{'$name'} = \$match;"+                ) . "+                \$bool+            }";+    }+}+sub negate {+    my $program = $_[0];+    #print "Negate: ", Dumper($_[0]);+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] do{ +$_[1]     my \$pos1 := \$m.to;+$_[1]     do {+$_[1]       my \$pos := \$pos1;+$_[1]       my \$from := \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool := " . $program . " ? 0 : 1;+$_[1]       \$bool;+$_[1]     };+$_[1] }";+}+sub before {+    my $program = $_[0]{rule};+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] do{ +$_[1]     my \$pos1 := \$m.to;+$_[1]     do {+$_[1]       my \$pos := \$pos1;+$_[1]       my \$from := \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool := 0 unless+" .             $program . ";+$_[1]       \$bool;+$_[1]     };+$_[1] }";+}+sub not_before {+    my $program = $_[0]{rule};+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] do{ +$_[1]     my \$pos1 := \$m.to;+$_[1]     do {+$_[1]       my \$pos := \$pos1;+$_[1]       my \$from := \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       my \$bool := 1;+$_[1]       \$bool := 0 unless+" .             $program . ";+$_[1]       ! \$bool;+$_[1]     };+$_[1] }";+}+sub after {+    local $direction = "-";+    my $program = $_[0]{rule};+    $program = emit_rule( $program, $_[1].'        ' )+        if ref( $program );+    return "$_[1] do{ +$_[1]     my \$pos1 := \$m.to;+$_[1]     do {+$_[1]       my \$pos := \$pos1 - 1;+$_[1]       my \$from := \$pos;+$_[1]       my \@match;+$_[1]       my \%named;+$_[1]       \$bool := 0 unless+" .             $program . ";+$_[1]       \$bool;+$_[1]     };+$_[1] }";+}+sub not_after {+    warn '<!after ...> not implemented';+    return;+}+sub colon {+    my $str = $_[0];+    return "$_[1] 1 # : no-op\n"+        if $str eq ':';+    return "$_[1] ( \$m.to >= length( \$s ) ) \n" +        if $str eq '$';+    return "$_[1] ( \$m.to == 0 ) \n" +        if $str eq '^';+        +    return "$_[1] ( \$m.to >= length( \$s ) || substr( \$s, \$m.to ) =~ /^(?:\n\r?|\r\n?)/m ) \n" +        if $str eq '$$';+    return "$_[1] ( \$m.to == 0 || substr( \$s, 0, \$m.to ) =~ /(?:\n\r?|\r\n?)\$/m ) \n" +        if $str eq '^^';++    return metasyntax( '?_wb_left', $_[1] )+        if $str eq '<<';+    return metasyntax( '?_wb_right', $_[1] )+        if $str eq '>>';+        +    die "'$str' not implemented";+}+sub modifier {+    my $str = $_[0];+    die "modifier '$str' not implemented";+}+sub constant {+    call_constant( @_ );+}++use vars qw( %char_class );+BEGIN {+    %char_class = map { $_ => 1 } qw( +        alpha alnum ascii blank+        cntrl digit graph lower+        print punct space upper+        word  xdigit+    );+}++sub metasyntax {+    # <cmd>+    my $cmd = $_[0];   +    my $prefix = substr( $cmd, 0, 1 );+    if ( $prefix eq '@' ) {+        # XXX - wrap @array items - see end of Pugs::Grammar::Rule+        # TODO - param list+        my $name = substr( $cmd, 1 );+        return +            "$_[1] do {+                my \$match; +                for my \$subrule ( $cmd ) { +                    \$match := \$subrule.match( \$str, \$grammar, { pos => ( \$m.to ), args => {} }, undef );+                    last if \$match; +                }+                if ( \$match ) {" .+                    ( $capture_to_array +                    ? " push \@(\$named{'$name'}), \$match;" +                    : " \$named{'$name'} := \$match;"+                    ) . "+                    \$m.to := \$match.to; +                    1 +                } +                else { 0 }+            }";+    }++    if ( $prefix eq '%' ) {+        # XXX - runtime or compile-time interpolation?+        my $name = substr( $cmd, 1 );+        # print "<$cmd>\n";+        # return variable( $cmd );+        return "$_[1] do{ +                my \$match := " . variable( $cmd, $_[1] ) . ";+                if ( \$match ) {" .+                    ( $capture_to_array +                    ? " push \@{\$named{'$name'}}, \$match;" +                    : " \$named{'$name'} := \$match;"+                    ) . "+                    \$m.to := \$match.to; +                    1 +                } +                else { 0 }+            }";+    }++    if ( $prefix eq '$' ) {+        if ( $cmd =~ /::/ ) {+            # call method in fully qualified $package::var+            # ...->match( $rule, $str, $grammar, $flags, $state )  +            # TODO - send $pos to subrule+            return +                "$_[1]         do {\n" .+                "$_[1]           push \@match,\n" . +                "$_[1]             $cmd.match( \$str, \$grammar, {pod => \$m.to}, undef );\n" .+                "$_[1]           \$m.to := \$match[-1].to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }"+        }+        # call method in lexical $var+        return +                "$_[1]         do {\n" .+                "$_[1]           my \$r := $cmd;\n" . +                "$_[1]           push \@match,\n" . +                "$_[1]             \$r.match( \$str, \$grammar, {pos => \$m.to}, undef );\n" .+                "$_[1]           \$m.to := \$match[-1].to;\n" .+                "$_[1]           !\$match[-1] != 1;\n" .+                "$_[1]         }"+    }+    if ( $prefix eq q(') ) {   # single quoted literal ' +        $cmd = substr( $cmd, 1, -1 );+        return call_constant( $cmd, $_[1] );+    }+    if ( $prefix eq q(") ) {   # interpolated literal "+        $cmd = substr( $cmd, 1, -1 );+        warn "<\"...\"> not implemented";+        return;+    }+    if ( $prefix =~ /[-+[]/ ) {   # character class +        $cmd =~ s/\.\./-/g;+        if ( $prefix eq '-' ) {+           $cmd = '[^' . substr($cmd, 2);+        } +        elsif ( $prefix eq '+' ) {+           $cmd = substr($cmd, 2);+        }+        $cmd =~ s/\s+|\n//g;+        # XXX <[^a]> means [\^a] instead of [^a] in perl5re+        return call_perl5($cmd, $_[1]);+    }+    if  ( +           $prefix eq '.' +        || $prefix eq '?'   # XXX FIXME+        )+    {   # non_capturing_subrule / code assertion+        $cmd = substr( $cmd, 1 );+        if ( $cmd =~ /^{/ ) {+            warn "code assertion not implemented";+            return;+        }+        if ( exists $char_class{$cmd} ) {+            # XXX - inlined char classes are not inheritable, but this should be ok+            return call_perl5( "[[:$cmd:]]", $_[1] );+        }+        my @param; # TODO+        my $subrule = $cmd;+        return+"$_[1] do { +$_[1]      my \$prior := Grammar::Base.PRIOR; +$_[1]      my \$match := \n" . +               call_subrule( $subrule, $_[1]."        ", @param ) . ";+$_[1]      Grammar::Base.PRIOR := \$prior; +$_[1]      my \$bool := (!\$match != 1);+$_[1]      \$m.to := \$match.to if \$bool;+$_[1]      \$match;+$_[1] }";+    }+    if ( $prefix =~ /[_[:alnum:]]/ ) {  +        if ( $cmd eq 'cut' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'commit' ) {+            warn "<$cmd> not implemented";+            return;+        }+        if ( $cmd eq 'null' ) {+            return "$_[1] 1 # null\n"+        }+        # <subrule ( param, param ) >+        my ( $subrule, $param_list ) = split( /[\(\)]/, $cmd );+        $param_list ||= '';++        if ( $subrule eq 'at' ) {+            $param_list ||= 0;   # XXX compile-time only+            return "$_[1] ( \$m.to == $param_list )\n"+        }++        return named_capture(+            { +                ident => $subrule, +                rule => { metasyntax => $cmd },+            }, +            $_[1],    +        );+    }+    #if ( $prefix eq '.' ) {  +    #    my ( $method, $param_list ) = split( /[\(\)]/, $cmd );+    #    $method =~ s/^\.//;+    #    $param_list ||= '';+    #    return " ( \$str.$method( $param_list ) ? 1 : 0 ) ";+    #}+    die "<$cmd> not implemented";+}++1;
+ blib6/pugs/perl5/lib/Pugs/Grammar/Base.pm view
@@ -0,0 +1,196 @@+package Pugs::Grammar::Base;+use Pugs::Runtime::Match;+use Pugs::Compiler::RegexPerl5;+use Pugs::Compiler::Regex;+use Data::Dumper;+use Carp;++use charnames ":full";   # support \c[DIGIT SIX]++# This class defines <ws>, unicode character classes, etc++# internal methods - not in spec++sub no_match {+    my $grammar = shift;+    my $pos = $_[1]{p} || 0;+    return Pugs::Runtime::Match->new( { +        bool    => \0,+        str     => \$_[0],+        match   => [],+        from    => \$pos,+        to      => \$pos,+        capture => undef,+    } );+}++*fail = \&no_match;++*any = Pugs::Compiler::RegexPerl5->compile( +    '\X' +)->code;++# <<word+*_wb_left = Pugs::Compiler::RegexPerl5->compile( +    '\b(?=\w)' +)->code;++# word>>+*_wb_right = Pugs::Compiler::RegexPerl5->compile( +    '(?<=\w)\b' +)->code;++=for later - unused+# \h+*_horizontal_ws = Pugs::Compiler::RegexPerl5->compile( +    #'XXX - Infinite loop in pugs stdrules.t' .+    '\x20|\t'+    +    #'\x0a|\x0b|\x0c|\x0d|\x85'   +    # from regex_tests, plus \t and ' '+)->code;++# \v+*_vertical_ws = Pugs::Compiler::RegexPerl5->compile( +    #'XXX - Infinite loop in pugs stdrules.t' .+    '[\n\r]'+    +    #'\x{1680}|\x{180e}|\x{2000}|\x{2001}|\x{2002}|\x{2003}|\x{2004}|\x{2005}|\x{2006}|\x{2007}|\x{2008}|\x{2008}|\x{2009}|\x{200a}|\x{202f}|\x{205f}|\x{3000}'   +    # from regex_tests+)->code;+=cut++# specced methods++sub before {+    #print "Base->before: ", Dumper(\@_);+    my $grammar = shift;+    my $pos = $_[1]{p} || 0;+    my $arg = $_[1]{positionals}[0];  ++    # XXX - token or regex?+    my $rule = Pugs::Compiler::Regex->compile( $arg );+    my $match = $rule->match( $_[0], { pos => $pos } );+    +    return Pugs::Runtime::Match->new( { +        bool    => \( $match ? 1 : 0 ),+        str     => \$_[0],+        match   => [],+        from    => \$pos,+        to      => \$pos,+        capture => undef,+    } );+}   ++sub at {+    #print "Base->at: ", Dumper(\@_);+    my $grammar = shift;+    my $pos = $_[1]{p} || 0;+    my $arg = $_[1]{positionals}[0];  +    # print "at: ",Dumper( @_ );+    return Pugs::Runtime::Match->new( { +        bool    => \( $pos == $arg ),+        str     => \$_[0],+        match   => [],+        from    => \$pos,+        to      => \$pos,+        capture => undef,+    } );+}++sub prior {+    die "Error: <prior> is undefined" +        unless defined $main::_V6_PRIOR_;++    my $prior = $main::_V6_PRIOR_;+    ## local $main::_V6_PRIOR_;+    $prior->(@_[0, 1, 2, 2]);  # XXX fix parameter list+}++*null = Pugs::Compiler::RegexPerl5->compile( +    '' +)->code;++*ws = Pugs::Compiler::RegexPerl5->compile( +    '(?:(?<!\w)|(?!\w)|\s)\s*' +)->code;++# <wb> = word boundary - from regex_tests+*wb = Pugs::Compiler::RegexPerl5->compile( +    '\b' +)->code;++*ident = Pugs::Compiler::RegexPerl5->compile( +    '[[:alpha:]_][[:alnum:]_]*' +)->code;++*name = Pugs::Compiler::RegexPerl5->compile( +    # from pugs tests+    '(?:[[:alpha:]_][[:alnum:]_]*::)*[[:alpha:]_][[:alnum:]_]*' +)->code;++*sp = Pugs::Compiler::RegexPerl5->compile( +    '\x20' +)->code;++*dot = Pugs::Compiler::RegexPerl5->compile( +    '\.' +)->code;++*gt = Pugs::Compiler::RegexPerl5->compile( +    '>' +)->code;++*lt = Pugs::Compiler::RegexPerl5->compile( +    '<' +)->code;++#BEGIN {+#    # this list was extracted from 'perlre'+#    for ( qw( +#        alpha alnum ascii blank+#        cntrl digit graph lower+#        print punct space upper+#        word  xdigit+#    ) ) {+#        *{$_} = Pugs::Compiler::RegexPerl5->compile( +#            "[[:$_:]]"+#        )->code;+#    }+#}++sub DESTROY { }  # avoid autoloading this++    sub AUTOLOAD {+        #my $self = shift;+        my $meth = $AUTOLOAD;+        $meth =~ s/.*:://;   # strip fully-qualified portion+        +        # is it a Unicode property? "isL"+        {+          local $@;+          eval ' my $s="a"; $s =~ /\p{' . $meth . '}/ ';+          unless ( $@ ) {+            *{$meth} = Pugs::Compiler::RegexPerl5->compile( +              '\p{' . $meth . '}'+            )->code;+            return $meth->( @_ );+          }+        }+        +        # is it a char class? "digit"+        {+          local $@;+          eval ' my $s="a"; $s =~ /[[:' . $meth . ':]]/ ';+          unless ( $@ ) {+            *{$meth} = Pugs::Compiler::RegexPerl5->compile( +              '[[:' . $meth . ':]]'+            )->code;+            return $meth->( @_ );+          }+        }+        +        carp "unknown rule: <$meth>";+    }    ++1;
+ blib6/pugs/perl5/lib/Pugs/Grammar/Precedence.pm view
@@ -0,0 +1,349 @@+package Pugs::Grammar::Precedence;++# Documentation in the __END__+use 5.006;+use strict;+use warnings;++use Parse::Yapp;+use Digest::MD5 'md5_hex';++my $cache;+eval {+    require Cache::FileCache;+    $cache = new Cache::FileCache( { 'namespace' => 'v6-precedence' } );+};++my %relative_precedences = (+    tighter => sub {+        splice( @{$_[0]->{levels}}, $_[1], 0, [ $_[2] ] );+    },+    looser  => sub {+        splice( @{$_[0]->{levels}}, $_[1]+1, 0, [ $_[2] ] );+    },+    equal   => sub {+        push @{$_[0]->{levels}[$_[1]]}, $_[2];+    },+);++# note: S06 - 'chain' can't be mixed with other types in the same level+my %rule_templates = (+    prefix_non =>+        "'name' exp         \n" .+        "\t{ \$_[0]->{out}= {fixity => 'prefix', op1 => \$_[1], exp1 => \$_[2],} }",+    circumfix_non =>+        "'name' exp 'name2' \n" .+        "\t{ \$_[0]->{out}= {fixity => 'circumfix', op1 => \$_[1], op2 => \$_[3], exp1 => \$_[2],} }\n" .+        "\t | 'name' 'name2' \n" .+        "\t{ \$_[0]->{out}= {fixity => 'circumfix', op1 => \$_[1], op2 => \$_[2] } }",+    infix_right =>+        "exp 'name' exp     \n" .+        "\t{ \$_[0]->{out}= {fixity => 'infix', op1 => \$_[2], exp1 => \$_[1], exp2 => \$_[3],} }",+    postfix_non =>+        "exp 'name'         \n" .+        "\t{ \$_[0]->{out}= {fixity => 'postfix', op1 => \$_[2], exp1 => \$_[1],} }",+    postcircumfix_non =>+        "exp 'name' exp 'name2' \n" .+        "\t{ \$_[0]->{out}= {fixity => 'postcircumfix', op1 => \$_[2], op2 => \$_[4], exp1 => \$_[1], exp2 => \$_[3],} } \n" .+        "\t | exp 'name' 'name2' \n" .+        "\t{ \$_[0]->{out}= {fixity => 'postcircumfix', op1 => \$_[2], op2 => \$_[3], exp1 => \$_[1], } }",+    infix_left =>+        "exp 'name' exp     \n" .+        "\t{ \$_[0]->{out}= {fixity => 'infix', op1 => \$_[2], exp1 => \$_[1], exp2 => \$_[3],} }",+    infix_non =>+        "exp 'name' exp     \n" .+        "\t{ \$_[0]->{out}= {fixity => 'infix', op1 => \$_[2], exp1 => \$_[1], exp2 => \$_[3],} }",+    ternary_non =>+        "exp 'name' exp 'name2' exp \n" .+        "\t{ \$_[0]->{out}= {fixity => 'ternary', op1 => \$_[2], op2 => \$_[4], exp1 => \$_[1], exp2 => \$_[3], exp3 => \$_[5],} }",++    # XXX+    #infix_chain =>+    #    "exp 'name' chain_right  \n" .+    #    "\t{ \$_[0]->{out}= {op1 => 'name', exp1 => \$_[1], exp2 => \$_[3],} }",+    #infix_list =>+    #    "exp 'name' list_right \n" .+    #    "\t{ \$_[0]->{out}= {op1 => 'name', exp1 => \$_[1], exp2 => \$_[3],} }",+);++sub new {+    my $class = shift;+    my $self = { levels => [], @_ };+    bless $self, $class;+}++our $op_count = '000';+sub add_op {+    my ($self, $opt) = @_;+    #print "adding $opt->{name}\n";+    $opt->{assoc}  = 'non'    unless defined $opt->{assoc};+    $opt->{fixity} = 'prefix' unless defined $opt->{fixity};+    $opt->{index}  = 'OP' . $op_count++;+    #my $fixity = $opt->{fixity};+    #$fixity .= '_' . $opt->{assoc} if $opt->{fixity} eq 'infix';+    for my $level ( 0 .. $#{$self->{levels}} ) {+        if ( grep {+                defined $opt->{other}+                ? ($_->{name} eq $opt->{other})+                : 0+             } @{$self->{levels}[$level]} ) {+            #print "pos $level at $opt->{precedence} $opt->{other}\n";+            $relative_precedences{$opt->{precedence}}->($self, $level, $opt);+            #print "Precedence table: ", Dump( $self );+            return;+        }+    }+    if ( ! defined $opt->{precedence} ) {+        push @{$self->{levels}}, [ $opt ];+        return;+    }+    die "there is no precedence like ", $opt->{other};+}+++sub add_to_list {+    my ( $op, $x, $y ) = @_;+    my @x = ($x);+    @x = @{$x->{list}} if exists $x->{list} && $x->{op1} eq $op;+    return { op1 => $op, list => [ @x, $y ], assoc => 'list' };+}++sub add_to_chain {+    my ( $op, $x, $y ) = @_;+    my @x = exists $x->{chain} ? @{$x->{chain}} : ($x);+    my @y = exists $y->{chain} ? @{$y->{chain}} : ($y);+    return { chain => [ @x, $op, @y ], assoc => 'chain' };+}++sub emit_yapp {+    my ($self) = @_;+    my $s;  # = "%{ my \$_[0]->{out}; %}\n";+    my $prec = "P000";+    my %seen;+    for my $level ( reverse 0 .. $#{$self->{levels}} ) {+        my %assoc;+        for my $operator ( @{$self->{levels}[$level]} ) {+            push @{$assoc{ $operator->{assoc} }}, $operator;+        }+        for my $aaa ( keys %assoc ) {+            if ( @{$assoc{$aaa}} ) {+                my $a = $aaa;+                $a = 'nonassoc' if $a eq 'non';+                $a = 'left'     if $a eq 'list';+                $a = 'left'     if $a eq 'chain';+                $s .= "%$a ";+                for my $operator ( @{ $assoc{$aaa} } ) {+                    next if $seen{$operator->{name}};+                    $seen{$operator->{name}} = 1;+                    $s .= ' ' .+                             "'$operator->{name}'" ;+                        # (( $aaa eq 'list' || $aaa eq 'chain' )+                        #     ? $operator->{index}+                        #     : "'$operator->{name}'"+                        # );+                }+                $s .=+                    " $prec" .+                    "\n";+                # $seen{$_->{name}} = 1 for @{$assoc{$_}};+                $prec++;+            }+        }+    }+    $s .= "%%\n" .+        "statement:  exp { return(\$_[0]->{out}) } ;\n";++    if ( defined $self->{header} ) {+        $s .= $self->{header};+    }+    else {+        $s .=+            "exp:   NUM  { \$_[0]->{out}= \$_[1] }\n";+    }+    $prec = "P000";+    for my $level ( reverse 0 .. $#{$self->{levels}} ) {+        my %assoc;+        for ( @{$self->{levels}[$level]} ) {+            push @{$assoc{ $_->{assoc} }}, $_;+        }+        for ( keys %assoc ) {+            if ( @{$assoc{$_}} ) {+++                for my $op ( @{$assoc{$_}} ) {+                    if ( $op->{assoc} eq 'list' ) {+                        $s .=+                            "    |  exp '$op->{name}' exp   %prec $prec\n" .+                            "        { \$_[0]->{out}= Pugs::Grammar::Precedence::add_to_list( '$op->{name}', \$_[1], \$_[3] ) } \n" ;+                        $s .=+                            "    |  exp '$op->{name}'    %prec $prec\n" .+                            "        { \$_[0]->{out}= Pugs::Grammar::Precedence::add_to_list( '$op->{name}', \$_[1], { null => 1 } ) } \n" ;+                            # "        { \$_[0]->{out}= \$_[1] } \n" ;+                        next;+                    }+                    if ( $op->{assoc} eq 'chain' ) {+                        $s .=+                            "    |  exp '$op->{name}' exp   %prec $prec\n" .+                            "        { \$_[0]->{out}= Pugs::Grammar::Precedence::add_to_chain( '$op->{name}', \$_[1], \$_[3] ) } \n" ;+                        $s .=+                            "    |  exp '$op->{name}'    %prec $prec\n" .+                            "        { \$_[0]->{out}= Pugs::Grammar::Precedence::add_to_chain( '$op->{name}', \$_[1], { null => 1 } ) } \n" ;+                            # "        { \$_[0]->{out}= \$_[1] } \n" ;+                        next;+                    }+                    my $t = $rule_templates{"$op->{fixity}_$op->{assoc}"};+                    unless ( defined $t ) {+                        warn "can't find template for '$op->{fixity}_$op->{assoc}'";+                        next;+                    }+                    $t =~ s/$_/$op->{$_}/g for qw( name2 name );+                    $t =~ s/\{ /%prec $prec { /;+                    $s .= "    |  $t \n" .+                        # "\t%prec $prec\n" .+                        "\t/* $op->{name} $op->{fixity} $op->{assoc} */\n";+                }+                $prec++;+            }+        }+    }+    $s .= ";\n" .+        "%%\n";+    #print $s;+    return $s;+}++sub emit_grammar_perl5 {+    my $self = shift;+    my $g = $self->emit_yapp();+    #print $g;++    my $digest = md5_hex($self->{grammar} . $g);+    my $cached;++    if ($cache && ($cached = $cache->get($digest))) {+	return $cached;+    }++    my $p = Parse::Yapp->new( input => $g );+    $cached = $p->Output( classname => $self->{grammar} );+    $cache->set($digest, $cached) if $cache;+    return $cached;+}++sub exists_op { die "not implemented" };+sub delete_op { die "not implemented" };+sub get_op    { die "not implemented" };+sub inherit_category { die "not implemented" };+sub inherit_grammar  { die "not implemented" };+sub merge_category   { die "not implemented" };+sub code  { die "not implemented" }+sub match { die "not implemented" }+sub perl5 { die "not implemented" }++1;++__END__++=head1 NAME++Pugs::Grammar::Precedence - Engine for Perl 6 Rule operator precedence++=head1 SYNOPSIS++  use Pugs::Grammar::Precedence;++  # example definition for "sub rxinfix:<|> ..."++  my $rxinfix = Pugs::Grammar::Precedence->new(+    grammar => 'rxinfix',+  );+  $rxinfix->add_op(+    name => '|',+    assoc => 'left',+    fixity => 'infix',+  );++Pseudo-code for usage inside a grammar:++    sub new_proto( $match ) {+        return ${$match<category>}.add_op(+            name => $match<name>,+            fixity => ...,+            precedence => ...,+        );+    }++    rule prototype {+        proto <category>:<name> <options>+        {+            return new_proto($/);+        }+    }++    rule statement {+        <category.parse> ...+    }++=head1 DESCRIPTION++This module provides an implementation for Perl 6 operator precedence.++=head1 METHODS++=head2 new ()++Class method.  Returns a category object.++options:++=over++=item * C<< grammar => $category_name >> - the name of this category+(a namespace or a Grammar name).++=back++=head2 add_op ()++Instance method.  Adds a new operator to the category.++options:++=over++=item * name => $operator_name - the name of this operator, such as '+', '*'++=item * name2 => $operator_name - the name of the second operator in+an operator pair, such as circumfix [ '(', ')' ] or ternary [ '??', '!!' ].++ # precedence=>'tighter',+ #   tighter/looser/equiv+ # other=>'+',+ # fixity =>+ #  infix/prefix/circumfix/postcircumfix/ternary+ # assoc =>+ #  left/right/non/chain/list+ # rule=>$rule+ #  (is parsed)++=back++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 SEE ALSO++Summary of Perl 6 Operators: L<http://dev.perl.org/perl6/doc/design/syn/S03.html>++=head1 COPYRIGHT++Copyright 2006, 2007 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut+
+ blib6/pugs/perl5/lib/Pugs/Grammar/Rule.pm view
@@ -0,0 +1,3 @@+# placeholder file - see examples/Grammar.grammar for Rule.pmc's source ++1;
+ blib6/pugs/perl5/lib/Pugs/Grammar/Rule.pmc view
@@ -0,0 +1,15166 @@+# !!! DO NOT EDIT !!!+# This file was generated by Pugs::Compiler::Rule's compile_p6grammar.pl+# script from examples/Grammar.grammar at Tue Oct 30 11:29:45 2007++use strict;+use warnings;++package Pugs::Grammar::Rule;++#use base 'Pugs::Grammar::Base';++use Pugs::Runtime::Match;+use Pugs::Runtime::Regex;+use Pugs::Runtime::Tracer ();++# Code block from grammar spec+++use utf8;+no strict 'refs';+no warnings 'redefine';+no warnings 'once';++#use Pugs::Runtime::Match;++our %rule_terms;+our %variables;++++# token pod_begin+*pod_begin =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 632 675+           (+               ( $pad{I1170} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 633 652+               (+      +                 ## <group>+                 ## pos: 633 639+                  (   ( $pad{I1171} = $pos or 1 ) &&+                   ## <perl5>+                   ( ( substr( $s, $pos ) =~ m/^((?:\n\r?|\r\n?))/ )+                       ? ( $pos += length( $1 ) or 1 )+                       : 0+                   )+                   ## </perl5>+     ||    ( ( $pos = $pad{I1171} ) && 0 ) )+                 ## </group>+    +               &&+    +                 ## <constant>+                 ## pos: 639 640+                 ( ( substr( $s, $pos, 1 ) eq '=' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+    +                 ## <constant>+                 ## pos: 640 641+                 ( ( substr( $s, $pos, 1 ) eq 'e' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+    +                 ## <constant>+                 ## pos: 641 642+                 ( ( substr( $s, $pos, 1 ) eq 'n' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+      +                 ## <group>+                 ## pos: 642 644+                  (   ( $pad{I1172} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 642 643+                   ( ( substr( $s, $pos, 1 ) eq 'd' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1172} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 644 652+                 do { while (+                  (   ( $pad{I1173} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1173} ) && 0 ) )) {}; $bool = 1 }+                 ## </quant>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1170} ) or 1 )+               &&            ## <concat>+               ## pos: 653 675+               (+      +                 ## <group>+                 ## pos: 653 658+                  (   ( $pad{I1174} = $pos or 1 ) &&+    +                   ## <dot>+                   ## pos: 656 657+                   ( substr( $s, $pos++, 1 ) ne '' )+                   ## </dot>+     ||    ( ( $pos = $pad{I1174} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 658 662+                 do { while (+                  (   ( $pad{I1175} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1175} ) && 0 ) )) {}; $bool = 1 }+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 662 675+                  (   ( $pad{I1176} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 662 674+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->pod_begin( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1176} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token pod_other+*pod_other =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 700 743+           (+               ( $pad{I1177} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 701 720+               (+      +                 ## <group>+                 ## pos: 701 707+                  (   ( $pad{I1178} = $pos or 1 ) &&+                   ## <perl5>+                   ( ( substr( $s, $pos ) =~ m/^((?:\n\r?|\r\n?))/ )+                       ? ( $pos += length( $1 ) or 1 )+                       : 0+                   )+                   ## </perl5>+     ||    ( ( $pos = $pad{I1178} ) && 0 ) )+                 ## </group>+    +               &&+    +                 ## <constant>+                 ## pos: 707 708+                 ( ( substr( $s, $pos, 1 ) eq '=' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+    +                 ## <constant>+                 ## pos: 708 709+                 ( ( substr( $s, $pos, 1 ) eq 'c' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+    +                 ## <constant>+                 ## pos: 709 710+                 ( ( substr( $s, $pos, 1 ) eq 'u' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+    +               &&+      +                 ## <group>+                 ## pos: 710 712+                  (   ( $pad{I1179} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 710 711+                   ( ( substr( $s, $pos, 1 ) eq 't' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1179} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 712 720+                 do { while (+                  (   ( $pad{I1180} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1180} ) && 0 ) )) {}; $bool = 1 }+                 ## </quant>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1177} ) or 1 )+               &&            ## <concat>+               ## pos: 721 743+               (+      +                 ## <group>+                 ## pos: 721 726+                  (   ( $pad{I1181} = $pos or 1 ) &&+    +                   ## <dot>+                   ## pos: 724 725+                   ( substr( $s, $pos++, 1 ) ne '' )+                   ## </dot>+     ||    ( ( $pos = $pad{I1181} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 726 730+                 do { while (+                  (   ( $pad{I1182} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1182} ) && 0 ) )) {}; $bool = 1 }+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 730 743+                  (   ( $pad{I1183} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 730 742+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1183} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token ws+*ws =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 761 1059+           (+            (   ( $pad{I1184} = $pos or 1 ) &&+               ## <alt>+               ## pos: 762 1056+               (+                   ( $pad{I1185} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 768 783+                   (+      +                     ## <group>+                     ## pos: 768 775+                      (   ( $pad{I1186} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 772 774+                       ( ( substr( $s, $pos, 1 ) eq '#' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1186} ) && 0 ) )+                     ## </group>+    +                   &&+                     ## <quant>+                     ## pos: 775 783+                     do { while (+                      (   ( $pad{I1187} = $pos or 1 ) &&+                         ## <perl5>+                         ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                             ? ( $pos += length( $1 ) or 1 )+                             : 0+                         )+                         ## </perl5>+     ||    ( ( $pos = $pad{I1187} ) && 0 ) )) {}; $bool = 1 }+                     ## </quant>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1185} ) or 1 )+                   &&                ## <concat>+                   ## pos: 784 1044+                   (+      +                     ## <group>+                     ## pos: 784 791+                      (   ( $pad{I1188} = $pos or 1 ) &&+                       ## <perl5>+                       ( ( substr( $s, $pos ) =~ m/^((?:\n\r?|\r\n?))/ )+                           ? ( $pos += length( $1 ) or 1 )+                           : 0+                       )+                       ## </perl5>+     ||    ( ( $pos = $pad{I1188} ) && 0 ) )+                     ## </group>+    +                   &&+                     ## <quant>+                     ## pos: 791 1044+                     (+                      (   ( $pad{I1189} = $pos or 1 ) &&+                         ## <concat>+                         ## pos: 792 1037+                         (+      +                           ## <group>+                           ## pos: 792 795+                            (   ( $pad{I1190} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 793 794+                             ( ( substr( $s, $pos, 1 ) eq '=' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1190} ) && 0 ) )+                           ## </group>+    +                         &&+                           ## <quant>+                           ## pos: 795 1037+                           (+                            (   ( $pad{I1191} = $pos or 1 ) &&+                               ## <alt>+                               ## pos: 796 1022+                               (+                                   ( $pad{I1192} = $pos or 1 )+                                   && (+                                   ## <concat>+                                   ## pos: 810 847+                                   (+      +                                     ## <group>+                                     ## pos: 810 813+                                      (   ( $pad{I1193} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 812 813+                                       ( ( substr( $s, $pos, 1 ) eq 'b' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1193} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 813 814+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 814 815+                                     ( ( substr( $s, $pos, 1 ) eq 'g' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 815 816+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 816 818+                                      (   ( $pad{I1194} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 816 817+                                       ( ( substr( $s, $pos, 1 ) eq 'n' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1194} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 818 824+                                      (   ( $pad{I1195} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 818 823+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1195} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 824 825+                                     ( ( substr( $s, $pos, 1 ) eq 'E' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 825 826+                                     ( ( substr( $s, $pos, 1 ) eq 'N' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 826 828+                                      (   ( $pad{I1196} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 826 827+                                       ( ( substr( $s, $pos, 1 ) eq 'D' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1196} ) && 0 ) )+                                     ## </group>+    +                                   &&+                                     ## <quant>+                                     ## pos: 828 832+                                     do { while (+                                      (   ( $pad{I1197} = $pos or 1 ) &&+                                         ## <perl5>+                                         ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                                             ? ( $pos += length( $1 ) or 1 )+                                             : 0+                                         )+                                         ## </perl5>+     ||    ( ( $pos = $pad{I1197} ) && 0 ) )) {}; $bool = 1 }+                                     ## </quant>+    +                                   &&+                                     ## <quant>+                                     ## pos: 832 847+                                     do { while (+                                      (   ( $pad{I1198} = $pos or 1 ) &&+    +                                         ## <dot>+                                         ## pos: 832 833+                                         ( substr( $s, $pos++, 1 ) ne '' )+                                         ## </dot>+     ||    ( ( $pos = $pad{I1198} ) && 0 ) )) {}; $bool = 1 }+                                     ## </quant>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 848 882+                                   (+      +                                     ## <group>+                                     ## pos: 848 851+                                      (   ( $pad{I1199} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 850 851+                                       ( ( substr( $s, $pos, 1 ) eq 'b' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1199} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 851 852+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 852 853+                                     ( ( substr( $s, $pos, 1 ) eq 'g' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 853 854+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 854 857+                                      (   ( $pad{I1200} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 854 855+                                       ( ( substr( $s, $pos, 1 ) eq 'n' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1200} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 857 882+                                      (   ( $pad{I1201} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 857 869+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_begin( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1201} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 883 917+                                   (+      +                                     ## <group>+                                     ## pos: 883 886+                                      (   ( $pad{I1202} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 885 886+                                       ( ( substr( $s, $pos, 1 ) eq 'k' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1202} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 886 887+                                     ( ( substr( $s, $pos, 1 ) eq 'w' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 887 888+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 888 892+                                      (   ( $pad{I1203} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 888 889+                                       ( ( substr( $s, $pos, 1 ) eq 'd' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1203} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 892 917+                                      (   ( $pad{I1204} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 892 904+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1204} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 918 952+                                   (+      +                                     ## <group>+                                     ## pos: 918 921+                                      (   ( $pad{I1205} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 920 921+                                       ( ( substr( $s, $pos, 1 ) eq 'p' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1205} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 921 922+                                     ( ( substr( $s, $pos, 1 ) eq 'o' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 922 927+                                      (   ( $pad{I1206} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 922 923+                                       ( ( substr( $s, $pos, 1 ) eq 'd' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1206} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 927 952+                                      (   ( $pad{I1207} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 927 939+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1207} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 953 987+                                   (+      +                                     ## <group>+                                     ## pos: 953 956+                                      (   ( $pad{I1208} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 955 956+                                       ( ( substr( $s, $pos, 1 ) eq 'f' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1208} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 956 957+                                     ( ( substr( $s, $pos, 1 ) eq 'o' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 957 962+                                      (   ( $pad{I1209} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 957 958+                                       ( ( substr( $s, $pos, 1 ) eq 'r' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1209} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 962 987+                                      (   ( $pad{I1210} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 962 974+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1210} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 988 1022+                                   (+      +                                     ## <group>+                                     ## pos: 988 991+                                      (   ( $pad{I1211} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 990 991+                                       ( ( substr( $s, $pos, 1 ) eq 'h' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1211} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 991 992+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 992 993+                                     ( ( substr( $s, $pos, 1 ) eq 'a' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 993 994+                                     ( ( substr( $s, $pos, 1 ) eq 'd' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 994 997+                                      (   ( $pad{I1212} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 994 995+                                       ( ( substr( $s, $pos, 1 ) eq '1' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1212} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 997 1022+                                      (   ( $pad{I1213} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 997 1009+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1213} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                 )+                               )+                               ## </alt>+     ||    ( ( $pos = $pad{I1191} ) && 0 ) )+                           || ( $bool = 1 )+                           )+                           ## </quant>+    +                         )+                         ## </concat>+     ||    ( ( $pos = $pad{I1189} ) && 0 ) )+                     || ( $bool = 1 )+                     )+                     ## </quant>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1185} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1045 1056+                    (   ( $pad{I1214} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^(\s)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1214} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1184} ) && 0 ) )+           && do { while (+            (   ( $pad{I1184} = $pos or 1 ) &&+               ## <alt>+               ## pos: 762 1056+               (+                   ( $pad{I1185} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 768 783+                   (+      +                     ## <group>+                     ## pos: 768 775+                      (   ( $pad{I1186} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 772 774+                       ( ( substr( $s, $pos, 1 ) eq '#' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1186} ) && 0 ) )+                     ## </group>+    +                   &&+                     ## <quant>+                     ## pos: 775 783+                     do { while (+                      (   ( $pad{I1187} = $pos or 1 ) &&+                         ## <perl5>+                         ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                             ? ( $pos += length( $1 ) or 1 )+                             : 0+                         )+                         ## </perl5>+     ||    ( ( $pos = $pad{I1187} ) && 0 ) )) {}; $bool = 1 }+                     ## </quant>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1185} ) or 1 )+                   &&                ## <concat>+                   ## pos: 784 1044+                   (+      +                     ## <group>+                     ## pos: 784 791+                      (   ( $pad{I1188} = $pos or 1 ) &&+                       ## <perl5>+                       ( ( substr( $s, $pos ) =~ m/^((?:\n\r?|\r\n?))/ )+                           ? ( $pos += length( $1 ) or 1 )+                           : 0+                       )+                       ## </perl5>+     ||    ( ( $pos = $pad{I1188} ) && 0 ) )+                     ## </group>+    +                   &&+                     ## <quant>+                     ## pos: 791 1044+                     (+                      (   ( $pad{I1189} = $pos or 1 ) &&+                         ## <concat>+                         ## pos: 792 1037+                         (+      +                           ## <group>+                           ## pos: 792 795+                            (   ( $pad{I1190} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 793 794+                             ( ( substr( $s, $pos, 1 ) eq '=' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1190} ) && 0 ) )+                           ## </group>+    +                         &&+                           ## <quant>+                           ## pos: 795 1037+                           (+                            (   ( $pad{I1191} = $pos or 1 ) &&+                               ## <alt>+                               ## pos: 796 1022+                               (+                                   ( $pad{I1192} = $pos or 1 )+                                   && (+                                   ## <concat>+                                   ## pos: 810 847+                                   (+      +                                     ## <group>+                                     ## pos: 810 813+                                      (   ( $pad{I1193} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 812 813+                                       ( ( substr( $s, $pos, 1 ) eq 'b' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1193} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 813 814+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 814 815+                                     ( ( substr( $s, $pos, 1 ) eq 'g' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 815 816+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 816 818+                                      (   ( $pad{I1194} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 816 817+                                       ( ( substr( $s, $pos, 1 ) eq 'n' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1194} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 818 824+                                      (   ( $pad{I1195} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 818 823+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1195} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 824 825+                                     ( ( substr( $s, $pos, 1 ) eq 'E' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 825 826+                                     ( ( substr( $s, $pos, 1 ) eq 'N' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 826 828+                                      (   ( $pad{I1196} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 826 827+                                       ( ( substr( $s, $pos, 1 ) eq 'D' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1196} ) && 0 ) )+                                     ## </group>+    +                                   &&+                                     ## <quant>+                                     ## pos: 828 832+                                     do { while (+                                      (   ( $pad{I1197} = $pos or 1 ) &&+                                         ## <perl5>+                                         ( ( substr( $s, $pos ) =~ m/^((?!\n\r?|\r\n?).)/ )+                                             ? ( $pos += length( $1 ) or 1 )+                                             : 0+                                         )+                                         ## </perl5>+     ||    ( ( $pos = $pad{I1197} ) && 0 ) )) {}; $bool = 1 }+                                     ## </quant>+    +                                   &&+                                     ## <quant>+                                     ## pos: 832 847+                                     do { while (+                                      (   ( $pad{I1198} = $pos or 1 ) &&+    +                                         ## <dot>+                                         ## pos: 832 833+                                         ( substr( $s, $pos++, 1 ) ne '' )+                                         ## </dot>+     ||    ( ( $pos = $pad{I1198} ) && 0 ) )) {}; $bool = 1 }+                                     ## </quant>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 848 882+                                   (+      +                                     ## <group>+                                     ## pos: 848 851+                                      (   ( $pad{I1199} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 850 851+                                       ( ( substr( $s, $pos, 1 ) eq 'b' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1199} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 851 852+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 852 853+                                     ( ( substr( $s, $pos, 1 ) eq 'g' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 853 854+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 854 857+                                      (   ( $pad{I1200} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 854 855+                                       ( ( substr( $s, $pos, 1 ) eq 'n' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1200} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 857 882+                                      (   ( $pad{I1201} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 857 869+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_begin( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1201} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 883 917+                                   (+      +                                     ## <group>+                                     ## pos: 883 886+                                      (   ( $pad{I1202} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 885 886+                                       ( ( substr( $s, $pos, 1 ) eq 'k' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1202} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 886 887+                                     ( ( substr( $s, $pos, 1 ) eq 'w' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 887 888+                                     ( ( substr( $s, $pos, 1 ) eq 'i' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 888 892+                                      (   ( $pad{I1203} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 888 889+                                       ( ( substr( $s, $pos, 1 ) eq 'd' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1203} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 892 917+                                      (   ( $pad{I1204} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 892 904+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1204} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 918 952+                                   (+      +                                     ## <group>+                                     ## pos: 918 921+                                      (   ( $pad{I1205} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 920 921+                                       ( ( substr( $s, $pos, 1 ) eq 'p' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1205} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 921 922+                                     ( ( substr( $s, $pos, 1 ) eq 'o' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 922 927+                                      (   ( $pad{I1206} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 922 923+                                       ( ( substr( $s, $pos, 1 ) eq 'd' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1206} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 927 952+                                      (   ( $pad{I1207} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 927 939+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1207} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 953 987+                                   (+      +                                     ## <group>+                                     ## pos: 953 956+                                      (   ( $pad{I1208} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 955 956+                                       ( ( substr( $s, $pos, 1 ) eq 'f' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1208} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 956 957+                                     ( ( substr( $s, $pos, 1 ) eq 'o' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 957 962+                                      (   ( $pad{I1209} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 957 958+                                       ( ( substr( $s, $pos, 1 ) eq 'r' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1209} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 962 987+                                      (   ( $pad{I1210} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 962 974+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1210} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1192} ) or 1 )+                                   &&                                ## <concat>+                                   ## pos: 988 1022+                                   (+      +                                     ## <group>+                                     ## pos: 988 991+                                      (   ( $pad{I1211} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 990 991+                                       ( ( substr( $s, $pos, 1 ) eq 'h' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1211} ) && 0 ) )+                                     ## </group>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 991 992+                                     ( ( substr( $s, $pos, 1 ) eq 'e' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 992 993+                                     ( ( substr( $s, $pos, 1 ) eq 'a' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+    +                                     ## <constant>+                                     ## pos: 993 994+                                     ( ( substr( $s, $pos, 1 ) eq 'd' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 994 997+                                      (   ( $pad{I1212} = $pos or 1 ) &&+    +                                       ## <constant>+                                       ## pos: 994 995+                                       ( ( substr( $s, $pos, 1 ) eq '1' )+                                           ? ( $pos += 1 or 1 )+                                           : 0+                                       )+                                       ## </constant>+     ||    ( ( $pos = $pad{I1212} ) && 0 ) )+                                     ## </group>+    +                                   &&+      +                                     ## <group>+                                     ## pos: 997 1022+                                      (   ( $pad{I1213} = $pos or 1 ) &&+                                       ## <metasyntax>+                                       ## pos: 997 1009+                                       do {+                                            my $prior = $::_V6_PRIOR_;+                                            my $match =+                                                   $grammar->pod_other( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                            $::_V6_PRIOR_ = $prior;+                                            my $bool = (!$match != 1);+                                            $pos = $match->to if $bool;+                                            $match;+                                       }+                                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1213} ) && 0 ) )+                                     ## </group>+    +                                   )+                                   ## </concat>+    +                                 )+                               )+                               ## </alt>+     ||    ( ( $pos = $pad{I1191} ) && 0 ) )+                           || ( $bool = 1 )+                           )+                           ## </quant>+    +                         )+                         ## </concat>+     ||    ( ( $pos = $pad{I1189} ) && 0 ) )+                     || ( $bool = 1 )+                     )+                     ## </quant>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1185} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1045 1056+                    (   ( $pad{I1214} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^(\s)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1214} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1184} ) && 0 ) )) {}; $bool = 1 }+           )+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token ident+*ident =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 1118 1143+           (+            (   ( $pad{I1215} = $pos or 1 ) &&+               ## <alt>+               ## pos: 1119 1140+               (+                   ( $pad{I1216} = $pos or 1 )+                   && (+      +                   ## <group>+                   ## pos: 1119 1129+                    (   ( $pad{I1217} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 1120 1128+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1217} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1216} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1130 1133+                    (   ( $pad{I1218} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 1131 1132+                     ( ( substr( $s, $pos, 1 ) eq '_' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1218} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1216} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1134 1140+                    (   ( $pad{I1219} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 1135 1139+                     ( ( substr( $s, $pos, 2 ) eq '::' )+                         ? ( $pos += 2 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1219} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1215} ) && 0 ) )+           && do { while (+            (   ( $pad{I1215} = $pos or 1 ) &&+               ## <alt>+               ## pos: 1119 1140+               (+                   ( $pad{I1216} = $pos or 1 )+                   && (+      +                   ## <group>+                   ## pos: 1119 1129+                    (   ( $pad{I1217} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 1120 1128+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1217} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1216} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1130 1133+                    (   ( $pad{I1218} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 1131 1132+                     ( ( substr( $s, $pos, 1 ) eq '_' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1218} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1216} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 1134 1140+                    (   ( $pad{I1219} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 1135 1139+                     ( ( substr( $s, $pos, 2 ) eq '::' )+                         ? ( $pos += 2 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1219} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1215} ) && 0 ) )) {}; $bool = 1 }+           )+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token alnum+*alnum =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 1164 1178+            (   ( $pad{I1220} = $pos or 1 ) &&+             ## <perl5>+             ( ( substr( $s, $pos ) =~ m/^((?:(?=[0-9a-zA-Z]))\X)/ )+                 ? ( $pos += length( $1 ) or 1 )+                 : 0+             )+             ## </perl5>+     ||    ( ( $pos = $pad{I1220} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token alpha+*alpha =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 1199 1210+            (   ( $pad{I1221} = $pos or 1 ) &&+             ## <perl5>+             ( ( substr( $s, $pos ) =~ m/^((?:(?=[a-zA-Z]))\X)/ )+                 ? ( $pos += length( $1 ) or 1 )+                 : 0+             )+             ## </perl5>+     ||    ( ( $pos = $pad{I1221} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token digit+*digit =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 1231 1239+            (   ( $pad{I1222} = $pos or 1 ) &&+             ## <perl5>+             ( ( substr( $s, $pos ) =~ m/^((?:(?=[0-9]))\X)/ )+                 ? ( $pos += length( $1 ) or 1 )+                 : 0+             )+             ## </perl5>+     ||    ( ( $pos = $pad{I1222} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token special_char+*special_char =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 1284 2177+           (+               ( $pad{I1223} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 1285 1473+               (+      +                 ## <group>+                 ## pos: 1285 1296+                  (   ( $pad{I1224} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <alt>+                           ## pos: 1287 1294+                           (+                               ( $pad{I1225} = $pos or 1 )+                               && (+      +                               ## <group>+                               ## pos: 1287 1290+                                (   ( $pad{I1226} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1288 1289+                                 ( ( substr( $s, $pos, 1 ) eq 'c' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1226} ) && 0 ) )+                               ## </group>+    +                               )+                             || (+                               ( ( $bool = 1 ) && ( $pos = $pad{I1225} ) or 1 )+                               &&   +                               ## <group>+                               ## pos: 1291 1294+                                (   ( $pad{I1227} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1292 1293+                                 ( ( substr( $s, $pos, 1 ) eq 'C' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1227} ) && 0 ) )+                               ## </group>+    +                             )+                           )+                           ## </alt>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1224} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1296 1299+                  (   ( $pad{I1228} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1296 1298+                   ( ( substr( $s, $pos, 1 ) eq '[' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1228} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1299 1340+                  (   ( $pad{I1229} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <quant>+                           ## pos: 1300 1338+                           (+                            (   ( $pad{I1230} = $pos or 1 ) &&+                               ## <alt>+                               ## pos: 1302 1336+                               (+                                   ( $pad{I1231} = $pos or 1 )+                                   && (+                                   ## <named_capture>+                                   ## pos: 1302 1309+                                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                               $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'alnum'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                   ## </named_capture>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&                                ## <perl5>+                                   ( ( substr( $s, $pos ) =~ m/^(\s)/ )+                                       ? ( $pos += length( $1 ) or 1 )+                                       : 0+                                   )+                                   ## </perl5>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1313 1318+                                    (   ( $pad{I1232} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1314 1317+                                     ( ( substr( $s, $pos, 1 ) eq ';' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1232} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1319 1324+                                    (   ( $pad{I1233} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1320 1323+                                     ( ( substr( $s, $pos, 1 ) eq '(' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1233} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1325 1330+                                    (   ( $pad{I1234} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1326 1329+                                     ( ( substr( $s, $pos, 1 ) eq ')' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1234} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1331 1336+                                    (   ( $pad{I1235} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1332 1335+                                     ( ( substr( $s, $pos, 1 ) eq '-' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1235} ) && 0 ) )+                                   ## </group>+    +                                 )+                               )+                               ## </alt>+     ||    ( ( $pos = $pad{I1230} ) && 0 ) )+                           && do { while (+                            (   ( $pad{I1230} = $pos or 1 ) &&+                               ## <alt>+                               ## pos: 1302 1336+                               (+                                   ( $pad{I1231} = $pos or 1 )+                                   && (+                                   ## <named_capture>+                                   ## pos: 1302 1309+                                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                               $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'alnum'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                   ## </named_capture>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&                                ## <perl5>+                                   ( ( substr( $s, $pos ) =~ m/^(\s)/ )+                                       ? ( $pos += length( $1 ) or 1 )+                                       : 0+                                   )+                                   ## </perl5>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1313 1318+                                    (   ( $pad{I1232} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1314 1317+                                     ( ( substr( $s, $pos, 1 ) eq ';' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1232} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1319 1324+                                    (   ( $pad{I1233} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1320 1323+                                     ( ( substr( $s, $pos, 1 ) eq '(' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1233} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1325 1330+                                    (   ( $pad{I1234} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1326 1329+                                     ( ( substr( $s, $pos, 1 ) eq ')' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1234} ) && 0 ) )+                                   ## </group>+    +                                   )+                                 || (+                                   ( ( $bool = 1 ) && ( $pos = $pad{I1231} ) or 1 )+                                   &&   +                                   ## <group>+                                   ## pos: 1331 1336+                                    (   ( $pad{I1235} = $pos or 1 ) &&+    +                                     ## <constant>+                                     ## pos: 1332 1335+                                     ( ( substr( $s, $pos, 1 ) eq '-' )+                                         ? ( $pos += 1 or 1 )+                                         : 0+                                     )+                                     ## </constant>+     ||    ( ( $pos = $pad{I1235} ) && 0 ) )+                                   ## </group>+    +                                 )+                               )+                               ## </alt>+     ||    ( ( $pos = $pad{I1230} ) && 0 ) )) {}; $bool = 1 }+                           )+                           ## </quant>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 1 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1229} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1340 1385+                  (   ( $pad{I1236} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1340 1342+                   ( ( substr( $s, $pos, 1 ) eq ']' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1236} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1385 1473+                  (   ( $pad{I1237} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 1385 1463+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0]->[0] . $_[0]->[1], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1237} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1223} ) or 1 )+               &&            ## <concat>+               ## pos: 1474 1617+               (+      +                 ## <group>+                 ## pos: 1474 1485+                  (   ( $pad{I1238} = $pos or 1 ) &&+                   ## <alt>+                   ## pos: 1476 1483+                   (+                       ( $pad{I1239} = $pos or 1 )+                       && (+      +                       ## <group>+                       ## pos: 1476 1479+                        (   ( $pad{I1240} = $pos or 1 ) &&+    +                         ## <constant>+                         ## pos: 1477 1478+                         ( ( substr( $s, $pos, 1 ) eq 'x' )+                             ? ( $pos += 1 or 1 )+                             : 0+                         )+                         ## </constant>+     ||    ( ( $pos = $pad{I1240} ) && 0 ) )+                       ## </group>+    +                       )+                     || (+                       ( ( $bool = 1 ) && ( $pos = $pad{I1239} ) or 1 )+                       &&   +                       ## <group>+                       ## pos: 1480 1483+                        (   ( $pad{I1241} = $pos or 1 ) &&+    +                         ## <constant>+                         ## pos: 1481 1482+                         ( ( substr( $s, $pos, 1 ) eq 'X' )+                             ? ( $pos += 1 or 1 )+                             : 0+                         )+                         ## </constant>+     ||    ( ( $pos = $pad{I1241} ) && 0 ) )+                       ## </group>+    +                     )+                   )+                   ## </alt>+     ||    ( ( $pos = $pad{I1238} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 1485 1535+                 (+                  (   ( $pad{I1242} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 1485 1493+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->xdigit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'xdigit'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1242} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1242} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 1485 1493+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->xdigit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'xdigit'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1242} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 1535 1617+                  (   ( $pad{I1243} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 1535 1608+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1243} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1223} ) or 1 )+               &&            ## <concat>+               ## pos: 1618 1777+               (+      +                 ## <group>+                 ## pos: 1618 1629+                  (   ( $pad{I1244} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <alt>+                           ## pos: 1620 1627+                           (+                               ( $pad{I1245} = $pos or 1 )+                               && (+      +                               ## <group>+                               ## pos: 1620 1623+                                (   ( $pad{I1246} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1621 1622+                                 ( ( substr( $s, $pos, 1 ) eq 'x' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1246} ) && 0 ) )+                               ## </group>+    +                               )+                             || (+                               ( ( $bool = 1 ) && ( $pos = $pad{I1245} ) or 1 )+                               &&   +                               ## <group>+                               ## pos: 1624 1627+                                (   ( $pad{I1247} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1625 1626+                                 ( ( substr( $s, $pos, 1 ) eq 'X' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1247} ) && 0 ) )+                               ## </group>+    +                             )+                           )+                           ## </alt>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1244} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1629 1632+                  (   ( $pad{I1248} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1629 1631+                   ( ( substr( $s, $pos, 1 ) eq '[' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1248} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1632 1644+                  (   ( $pad{I1249} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <quant>+                           ## pos: 1633 1642+                           (+                            (   ( $pad{I1250} = $pos or 1 ) &&+                               ## <named_capture>+                               ## pos: 1633 1641+                               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                           $grammar->xdigit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'xdigit'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                               ## </named_capture>+     ||    ( ( $pos = $pad{I1250} ) && 0 ) )+                           && do { while (+                            (   ( $pad{I1250} = $pos or 1 ) &&+                               ## <named_capture>+                               ## pos: 1633 1641+                               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                           $grammar->xdigit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'xdigit'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                               ## </named_capture>+     ||    ( ( $pos = $pad{I1250} ) && 0 ) )) {}; $bool = 1 }+                           )+                           ## </quant>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 1 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1249} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1644 1689+                  (   ( $pad{I1251} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1644 1646+                   ( ( substr( $s, $pos, 1 ) eq ']' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1251} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1689 1777+                  (   ( $pad{I1252} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 1689 1767+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0]->[0] . $_[0]->[1], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1252} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1223} ) or 1 )+               &&            ## <concat>+               ## pos: 1778 1915+               (+      +                 ## <group>+                 ## pos: 1778 1789+                  (   ( $pad{I1253} = $pos or 1 ) &&+                   ## <alt>+                   ## pos: 1780 1787+                   (+                       ( $pad{I1254} = $pos or 1 )+                       && (+      +                       ## <group>+                       ## pos: 1780 1783+                        (   ( $pad{I1255} = $pos or 1 ) &&+    +                         ## <constant>+                         ## pos: 1781 1782+                         ( ( substr( $s, $pos, 1 ) eq 'o' )+                             ? ( $pos += 1 or 1 )+                             : 0+                         )+                         ## </constant>+     ||    ( ( $pos = $pad{I1255} ) && 0 ) )+                       ## </group>+    +                       )+                     || (+                       ( ( $bool = 1 ) && ( $pos = $pad{I1254} ) or 1 )+                       &&   +                       ## <group>+                       ## pos: 1784 1787+                        (   ( $pad{I1256} = $pos or 1 ) &&+    +                         ## <constant>+                         ## pos: 1785 1786+                         ( ( substr( $s, $pos, 1 ) eq 'O' )+                             ? ( $pos += 1 or 1 )+                             : 0+                         )+                         ## </constant>+     ||    ( ( $pos = $pad{I1256} ) && 0 ) )+                       ## </group>+    +                     )+                   )+                   ## </alt>+     ||    ( ( $pos = $pad{I1253} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 1789 1833+                 (+                  (   ( $pad{I1257} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^(\d)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1257} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1257} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^(\d)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1257} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 1833 1915+                  (   ( $pad{I1258} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 1833 1906+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1258} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1223} ) or 1 )+               &&            ## <concat>+               ## pos: 1916 2069+               (+      +                 ## <group>+                 ## pos: 1916 1927+                  (   ( $pad{I1259} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <alt>+                           ## pos: 1918 1925+                           (+                               ( $pad{I1260} = $pos or 1 )+                               && (+      +                               ## <group>+                               ## pos: 1918 1921+                                (   ( $pad{I1261} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1919 1920+                                 ( ( substr( $s, $pos, 1 ) eq 'o' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1261} ) && 0 ) )+                               ## </group>+    +                               )+                             || (+                               ( ( $bool = 1 ) && ( $pos = $pad{I1260} ) or 1 )+                               &&   +                               ## <group>+                               ## pos: 1922 1925+                                (   ( $pad{I1262} = $pos or 1 ) &&+    +                                 ## <constant>+                                 ## pos: 1923 1924+                                 ( ( substr( $s, $pos, 1 ) eq 'O' )+                                     ? ( $pos += 1 or 1 )+                                     : 0+                                 )+                                 ## </constant>+     ||    ( ( $pos = $pad{I1262} ) && 0 ) )+                               ## </group>+    +                             )+                           )+                           ## </alt>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1259} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1927 1930+                  (   ( $pad{I1263} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1927 1929+                   ( ( substr( $s, $pos, 1 ) eq '[' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1263} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1930 1936+                  (   ( $pad{I1264} = $pos or 1 ) &&+    +                   ## <capture>+                   do{+                       my $hash = do {+                         my $bool = 1;+                         my $from = $pos;+                         my @match;+                         my %named;+                         $bool = 0 unless+                           ## <quant>+                           ## pos: 1931 1934+                           (+                            (   ( $pad{I1265} = $pos or 1 ) &&+                               ## <perl5>+                               ( ( substr( $s, $pos ) =~ m/^(\d)/ )+                                   ? ( $pos += length( $1 ) or 1 )+                                   : 0+                               )+                               ## </perl5>+     ||    ( ( $pos = $pad{I1265} ) && 0 ) )+                           && do { while (+                            (   ( $pad{I1265} = $pos or 1 ) &&+                               ## <perl5>+                               ( ( substr( $s, $pos ) =~ m/^(\d)/ )+                                   ? ( $pos += length( $1 ) or 1 )+                                   : 0+                               )+                               ## </perl5>+     ||    ( ( $pos = $pad{I1265} ) && 0 ) )) {}; $bool = 1 }+                           )+                           ## </quant>+    ;+                         { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                       };+                       my $bool = ${$hash->{'bool'}};+                       $match[ 1 ] = Pugs::Runtime::Match->new( $hash );+                       $bool;+                   }+                   ## </capture>+     ||    ( ( $pos = $pad{I1264} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1936 1981+                  (   ( $pad{I1266} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 1936 1938+                   ( ( substr( $s, $pos, 1 ) eq ']' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1266} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 1981 2069+                  (   ( $pad{I1267} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 1981 2059+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0]->[0] . $_[0]->[1], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1267} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1223} ) or 1 )+               &&            ## <concat>+               ## pos: 2070 2177+               (+      +                 ## <group>+                 ## pos: 2070 2103+                  (   ( $pad{I1268} = $pos or 1 ) &&+    +                   ## <dot>+                   ## pos: 2071 2072+                   ( substr( $s, $pos++, 1 ) ne '' )+                   ## </dot>+     ||    ( ( $pos = $pad{I1268} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 2103 2177+                  (   ( $pad{I1269} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 2103 2176+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { special_char => '\\' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to] }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1269} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token literal+*literal =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 2200 2251+           do { while (+            (   ( $pad{I1270} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2201 2248+               (+                   ( $pad{I1271} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2207 2231+                   (+      +                     ## <group>+                     ## pos: 2207 2212+                      (   ( $pad{I1272} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2209 2211+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1272} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2212 2231+                      (   ( $pad{I1273} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2212 2226+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1273} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1271} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2232 2248+                    (   ( $pad{I1274} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\']))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1274} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1270} ) && 0 ) )) {}; $bool = 1 }+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token double_quoted+*double_quoted =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 2280 2372+           do { while (+            (   ( $pad{I1275} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2281 2369+               (+                   ( $pad{I1276} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2287 2311+                   (+      +                     ## <group>+                     ## pos: 2287 2292+                      (   ( $pad{I1277} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2289 2291+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1277} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2292 2311+                      (   ( $pad{I1278} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2292 2306+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1278} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1276} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2312 2352+                    (   ( $pad{I1279} = $pos or 1 ) &&+                    ## <metasyntax>+                     ## pos: 2314 2347+                     do{+                    my $match = +              ## <variable>+              ## pos: 2314 2347+              do {+                our $I1280;+                our $I1280_sizes;+                unless ( $I1280 ) {+                    my $hash = \%Pugs::Grammar::Rule::variables;+                    my %sizes = map { length($_) => 1 } keys %$hash;+                    $I1280_sizes = [ sort { $b <=> $a } keys %sizes ];+                    $I1280 = $hash;+                }+                my $match = 0;+                my $key;+                for ( @$I1280_sizes ) {+                    $key = ( $pos <= length( $s )+                                ? substr( $s, $pos, $_ )+                                : '' );+                    if ( exists $I1280->{$key} ) {+                        #$named{KEY} = $key;+                        #$::_V6_MATCH_ = $m;+                        #print "m: ", Dumper( $::_V6_MATCH_->data )+                        #    if ( $key eq 'until' );+                        $match = Pugs::Runtime::Regex::preprocess_hash( $I1280, $key )->( $s, $grammar, { p => ( $pos + $_ ), positionals => [ ], args => { KEY => $key } }, undef );+                        last if $match;+                    }+                }+                if ( $match ) {+                    $pos = $match->to;+                    #print "match: $key at $pos = ", Dumper( $match->data );+                    $bool = 1;+                }; # else { $bool = 0 }+                $match;+              }+              ## </variable>+    ;+                    if ( $match ) { push @{$named{'Pugs::Grammar::Rule::variables'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                    ## </metasyntax>+     ||    ( ( $pos = $pad{I1279} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1276} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2353 2369+                    (   ( $pad{I1281} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\"]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1281} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1275} ) && 0 ) )) {}; $bool = 1 }+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token metasyntax+*metasyntax =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 2398 2576+           (+            (   ( $pad{I1282} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2399 2573+               (+                   ( $pad{I1283} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2405 2429+                   (+      +                     ## <group>+                     ## pos: 2405 2410+                      (   ( $pad{I1284} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2407 2409+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1284} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2410 2429+                      (   ( $pad{I1285} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2410 2424+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1285} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2430 2458+                   (+      +                     ## <group>+                     ## pos: 2430 2436+                      (   ( $pad{I1286} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2432 2434+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1286} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2436 2451+                      (   ( $pad{I1287} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2436 2446+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1287} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2451 2458+                      (   ( $pad{I1288} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2451 2453+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1288} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2459 2491+                   (+      +                     ## <group>+                     ## pos: 2459 2465+                      (   ( $pad{I1289} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2461 2463+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1289} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2465 2484+                      (   ( $pad{I1290} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2465 2481+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->double_quoted( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1290} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2484 2491+                      (   ( $pad{I1291} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2484 2486+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1291} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2492 2527+                   (+      +                     ## <group>+                     ## pos: 2492 2498+                      (   ( $pad{I1292} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2494 2496+                       ( ( substr( $s, $pos, 1 ) eq '{' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1292} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2498 2520+                      (   ( $pad{I1293} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2498 2512+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1293} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2520 2527+                      (   ( $pad{I1294} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2520 2522+                       ( ( substr( $s, $pos, 1 ) eq '}' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1294} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2528 2556+                   (+      +                     ## <group>+                     ## pos: 2528 2534+                      (   ( $pad{I1295} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2530 2532+                       ( ( substr( $s, $pos, 1 ) eq '<' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1295} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2534 2549+                      (   ( $pad{I1296} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2534 2547+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->metasyntax( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1296} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2549 2556+                      (   ( $pad{I1297} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2549 2551+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1297} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2557 2573+                    (   ( $pad{I1298} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\>]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1298} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1282} ) && 0 ) )+           && do { while (+            (   ( $pad{I1282} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2399 2573+               (+                   ( $pad{I1283} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2405 2429+                   (+      +                     ## <group>+                     ## pos: 2405 2410+                      (   ( $pad{I1284} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2407 2409+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1284} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2410 2429+                      (   ( $pad{I1285} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2410 2424+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1285} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2430 2458+                   (+      +                     ## <group>+                     ## pos: 2430 2436+                      (   ( $pad{I1286} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2432 2434+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1286} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2436 2451+                      (   ( $pad{I1287} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2436 2446+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1287} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2451 2458+                      (   ( $pad{I1288} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2451 2453+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1288} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2459 2491+                   (+      +                     ## <group>+                     ## pos: 2459 2465+                      (   ( $pad{I1289} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2461 2463+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1289} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2465 2484+                      (   ( $pad{I1290} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2465 2481+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->double_quoted( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1290} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2484 2491+                      (   ( $pad{I1291} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2484 2486+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1291} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2492 2527+                   (+      +                     ## <group>+                     ## pos: 2492 2498+                      (   ( $pad{I1292} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2494 2496+                       ( ( substr( $s, $pos, 1 ) eq '{' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1292} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2498 2520+                      (   ( $pad{I1293} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2498 2512+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1293} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2520 2527+                      (   ( $pad{I1294} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2520 2522+                       ( ( substr( $s, $pos, 1 ) eq '}' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1294} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2528 2556+                   (+      +                     ## <group>+                     ## pos: 2528 2534+                      (   ( $pad{I1295} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2530 2532+                       ( ( substr( $s, $pos, 1 ) eq '<' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1295} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2534 2549+                      (   ( $pad{I1296} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2534 2547+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->metasyntax( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1296} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2549 2556+                      (   ( $pad{I1297} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2549 2551+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1297} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1283} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2557 2573+                    (   ( $pad{I1298} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\>]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1298} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1282} ) && 0 ) )) {}; $bool = 1 }+           )+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token char_range+*char_range =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 2602 2653+           (+            (   ( $pad{I1299} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2603 2650+               (+                   ( $pad{I1300} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2609 2633+                   (+      +                     ## <group>+                     ## pos: 2609 2614+                      (   ( $pad{I1301} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2611 2613+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1301} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2614 2633+                      (   ( $pad{I1302} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2614 2628+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1302} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1300} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2634 2650+                    (   ( $pad{I1303} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\]]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1303} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1299} ) && 0 ) )+           && do { while (+            (   ( $pad{I1299} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2603 2650+               (+                   ( $pad{I1300} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2609 2633+                   (+      +                     ## <group>+                     ## pos: 2609 2614+                      (   ( $pad{I1301} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2611 2613+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1301} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2614 2633+                      (   ( $pad{I1302} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2614 2628+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1302} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1300} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 2634 2650+                    (   ( $pad{I1303} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\]]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1303} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1299} ) && 0 ) )) {}; $bool = 1 }+           )+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token char_class+*char_class =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 2679 2721+           (+               ( $pad{I1304} = $pos or 1 )+               && (+               ## <quant>+               ## pos: 2680 2696+               (+                (   ( $pad{I1305} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 2682 2690+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->alpha( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1305} ) && 0 ) )+               && do { while (+                (   ( $pad{I1305} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 2682 2690+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->alpha( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1305} ) && 0 ) )) {}; $bool = 1 }+               )+               ## </quant>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1304} ) or 1 )+               &&            ## <concat>+               ## pos: 2697 2721+               (+      +                 ## <group>+                 ## pos: 2697 2703+                  (   ( $pad{I1306} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 2699 2701+                   ( ( substr( $s, $pos, 1 ) eq '[' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1306} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 2703 2718+                  (   ( $pad{I1307} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 2703 2716+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->char_range( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1307} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 2718 2721+                  (   ( $pad{I1308} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 2718 2720+                   ( ( substr( $s, $pos, 1 ) eq ']' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1308} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token string_code+*string_code =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <quant>+           ## pos: 2771 3055+           (+            (   ( $pad{I1309} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2772 3052+               (+                   ( $pad{I1310} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2778 2802+                   (+      +                     ## <group>+                     ## pos: 2778 2783+                      (   ( $pad{I1311} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2780 2782+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1311} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2783 2802+                      (   ( $pad{I1312} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2783 2797+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1312} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2803 2831+                   (+      +                     ## <group>+                     ## pos: 2803 2809+                      (   ( $pad{I1313} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2805 2807+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1313} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2809 2824+                      (   ( $pad{I1314} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2809 2819+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1314} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2824 2831+                      (   ( $pad{I1315} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2824 2826+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1315} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2832 2864+                   (+      +                     ## <group>+                     ## pos: 2832 2838+                      (   ( $pad{I1316} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2834 2836+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1316} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2838 2857+                      (   ( $pad{I1317} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2838 2854+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->double_quoted( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1317} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2857 2864+                      (   ( $pad{I1318} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2857 2859+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1318} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2865 2903+                   (+      +                     ## <group>+                     ## pos: 2865 2871+                      (   ( $pad{I1319} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2867 2869+                       ( ( substr( $s, $pos, 1 ) eq '{' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1319} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2871 2896+                      (   ( $pad{I1320} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2872 2893+                       (+                           ( $pad{I1321} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2872 2888+                            (   ( $pad{I1322} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2873 2887+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1322} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1321} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2889 2893+                            (   ( $pad{I1323} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1323} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1320} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2896 2903+                      (   ( $pad{I1324} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2896 2898+                       ( ( substr( $s, $pos, 1 ) eq '}' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1324} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2904 2942+                   (+      +                     ## <group>+                     ## pos: 2904 2910+                      (   ( $pad{I1325} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2906 2908+                       ( ( substr( $s, $pos, 1 ) eq '(' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1325} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2910 2935+                      (   ( $pad{I1326} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2911 2932+                       (+                           ( $pad{I1327} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2911 2927+                            (   ( $pad{I1328} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2912 2926+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1328} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1327} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2928 2932+                            (   ( $pad{I1329} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1329} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1326} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2935 2942+                      (   ( $pad{I1330} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2935 2937+                       ( ( substr( $s, $pos, 1 ) eq ')' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1330} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2943 2981+                   (+      +                     ## <group>+                     ## pos: 2943 2949+                      (   ( $pad{I1331} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2945 2947+                       ( ( substr( $s, $pos, 1 ) eq '<' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1331} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2949 2974+                      (   ( $pad{I1332} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2950 2971+                       (+                           ( $pad{I1333} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2950 2966+                            (   ( $pad{I1334} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2951 2965+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1334} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1333} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2967 2971+                            (   ( $pad{I1335} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1335} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1332} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2974 2981+                      (   ( $pad{I1336} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2974 2976+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1336} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2982 3016+                   (+      +                     ## <group>+                     ## pos: 2982 3009+                      (   ( $pad{I1337} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2985 3007+                       (+                           ( $pad{I1338} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2985 2992+                            (   ( $pad{I1339} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2986 2991+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1339} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2993 2997+                            (   ( $pad{I1340} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 2994 2996+                             ( ( substr( $s, $pos, 1 ) eq '>' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1340} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2998 3002+                            (   ( $pad{I1341} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 2999 3001+                             ( ( substr( $s, $pos, 1 ) eq '=' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1341} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 3003 3007+                            (   ( $pad{I1342} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 3004 3006+                             ( ( substr( $s, $pos, 1 ) eq '-' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1342} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1337} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 3009 3016+                      (   ( $pad{I1343} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 3009 3011+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1343} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 3017 3029+                    (   ( $pad{I1344} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 3019 3024+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1344} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 3030 3052+                    (   ( $pad{I1345} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\}\)\>]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1345} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1309} ) && 0 ) )+           && do { while (+            (   ( $pad{I1309} = $pos or 1 ) &&+               ## <alt>+               ## pos: 2772 3052+               (+                   ( $pad{I1310} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 2778 2802+                   (+      +                     ## <group>+                     ## pos: 2778 2783+                      (   ( $pad{I1311} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2780 2782+                       ( ( substr( $s, $pos, 1 ) eq '\\' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1311} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2783 2802+                      (   ( $pad{I1312} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 2783 2797+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1312} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2803 2831+                   (+      +                     ## <group>+                     ## pos: 2803 2809+                      (   ( $pad{I1313} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2805 2807+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1313} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2809 2824+                      (   ( $pad{I1314} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2809 2819+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1314} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2824 2831+                      (   ( $pad{I1315} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2824 2826+                       ( ( substr( $s, $pos, 1 ) eq chr(39) )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1315} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2832 2864+                   (+      +                     ## <group>+                     ## pos: 2832 2838+                      (   ( $pad{I1316} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2834 2836+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1316} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2838 2857+                      (   ( $pad{I1317} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 2838 2854+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->double_quoted( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1317} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2857 2864+                      (   ( $pad{I1318} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2857 2859+                       ( ( substr( $s, $pos, 1 ) eq '"' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1318} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2865 2903+                   (+      +                     ## <group>+                     ## pos: 2865 2871+                      (   ( $pad{I1319} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2867 2869+                       ( ( substr( $s, $pos, 1 ) eq '{' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1319} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2871 2896+                      (   ( $pad{I1320} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2872 2893+                       (+                           ( $pad{I1321} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2872 2888+                            (   ( $pad{I1322} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2873 2887+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1322} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1321} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2889 2893+                            (   ( $pad{I1323} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1323} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1320} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2896 2903+                      (   ( $pad{I1324} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2896 2898+                       ( ( substr( $s, $pos, 1 ) eq '}' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1324} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2904 2942+                   (+      +                     ## <group>+                     ## pos: 2904 2910+                      (   ( $pad{I1325} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2906 2908+                       ( ( substr( $s, $pos, 1 ) eq '(' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1325} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2910 2935+                      (   ( $pad{I1326} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2911 2932+                       (+                           ( $pad{I1327} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2911 2927+                            (   ( $pad{I1328} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2912 2926+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1328} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1327} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2928 2932+                            (   ( $pad{I1329} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1329} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1326} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2935 2942+                      (   ( $pad{I1330} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2935 2937+                       ( ( substr( $s, $pos, 1 ) eq ')' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1330} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2943 2981+                   (+      +                     ## <group>+                     ## pos: 2943 2949+                      (   ( $pad{I1331} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2945 2947+                       ( ( substr( $s, $pos, 1 ) eq '<' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1331} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2949 2974+                      (   ( $pad{I1332} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2950 2971+                       (+                           ( $pad{I1333} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2950 2966+                            (   ( $pad{I1334} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2951 2965+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1334} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1333} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2967 2971+                            (   ( $pad{I1335} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1335} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1332} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 2974 2981+                      (   ( $pad{I1336} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 2974 2976+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1336} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&                ## <concat>+                   ## pos: 2982 3016+                   (+      +                     ## <group>+                     ## pos: 2982 3009+                      (   ( $pad{I1337} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 2985 3007+                       (+                           ( $pad{I1338} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 2985 2992+                            (   ( $pad{I1339} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 2986 2991+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1339} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2993 2997+                            (   ( $pad{I1340} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 2994 2996+                             ( ( substr( $s, $pos, 1 ) eq '>' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1340} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 2998 3002+                            (   ( $pad{I1341} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 2999 3001+                             ( ( substr( $s, $pos, 1 ) eq '=' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1341} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1338} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 3003 3007+                            (   ( $pad{I1342} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 3004 3006+                             ( ( substr( $s, $pos, 1 ) eq '-' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1342} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1337} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 3009 3016+                      (   ( $pad{I1343} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 3009 3011+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1343} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 3017 3029+                    (   ( $pad{I1344} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 3019 3024+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1344} ) && 0 ) )+                   ## </group>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1310} ) or 1 )+                   &&   +                   ## <group>+                   ## pos: 3030 3052+                    (   ( $pad{I1345} = $pos or 1 ) &&+                     ## <perl5>+                     ( ( substr( $s, $pos ) =~ m/^((?:(?![\}\)\>]))\X)/ )+                         ? ( $pos += length( $1 ) or 1 )+                         : 0+                     )+                     ## </perl5>+     ||    ( ( $pos = $pad{I1345} ) && 0 ) )+                   ## </group>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1309} ) && 0 ) )) {}; $bool = 1 }+           )+           ## </quant>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token parsed_code+*parsed_code =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 3141 3187+           (+      +             ## <group>+             ## pos: 3141 3160+              (   ( $pad{I1346} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 3141 3155+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->string_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1346} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 3160 3187+              (   ( $pad{I1347} = $pos or 1 ) &&+               ## <closure>+               ## pos: 3160 3186+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return '{' . $_[0] . '}'; }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1347} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token named_capture_body+*named_capture_body =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 3221 3712+           (+               ( $pad{I1348} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 3222 3354+               (+      +                 ## <group>+                 ## pos: 3222 3227+                  (   ( $pad{I1349} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3223 3225+                   ( ( substr( $s, $pos, 1 ) eq '(' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1349} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3227 3241+                  (   ( $pad{I1350} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 3227 3233+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1350} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3241 3245+                  (   ( $pad{I1351} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3241 3243+                   ( ( substr( $s, $pos, 1 ) eq ')' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1351} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3245 3354+                  (   ( $pad{I1352} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 3245 3349+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { capturing_group => ${ $_[0]->{qw(rule)} },+                                  _pos => [ $_[0]->from, $_[0]->to ], }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1352} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1348} ) or 1 )+               &&            ## <concat>+               ## pos: 3355 3402+               (+      +                 ## <group>+                 ## pos: 3355 3360+                  (   ( $pad{I1353} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3356 3358+                   ( ( substr( $s, $pos, 1 ) eq '[' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1353} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3360 3374+                  (   ( $pad{I1354} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 3360 3366+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1354} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3374 3378+                  (   ( $pad{I1355} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3374 3376+                   ( ( substr( $s, $pos, 1 ) eq ']' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1355} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3378 3402+                  (   ( $pad{I1356} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 3378 3397+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return ${ $_[0]->{qw(rule)} } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1356} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1348} ) or 1 )+               &&            ## <concat>+               ## pos: 3403 3464+               (+      +                 ## <group>+                 ## pos: 3403 3408+                  (   ( $pad{I1357} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3404 3406+                   ( ( substr( $s, $pos, 1 ) eq '<' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1357} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3408 3428+                  (   ( $pad{I1358} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 3408 3426+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->parse_metasyntax( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parse_metasyntax'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1358} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3428 3464+                  (   ( $pad{I1359} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 3428 3459+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return ${ $_[0]->{qw(parse_metasyntax)} } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1359} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1348} ) or 1 )+               &&            ## <concat>+               ## pos: 3465 3678+               (+      +                 ## <group>+                 ## pos: 3465 3470+                  (   ( $pad{I1360} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3466 3468+                   ( ( substr( $s, $pos, 1 ) eq chr(39) )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1360} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3470 3484+                  (   ( $pad{I1361} = $pos or 1 ) &&+                   ## <metasyntax>+                   ## pos: 3470 3480+                   do {+                        my $prior = $::_V6_PRIOR_;+                        my $match =+                               $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                        $::_V6_PRIOR_ = $prior;+                        my $bool = (!$match != 1);+                        $pos = $match->to if $bool;+                        $match;+                   }+                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1361} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3484 3495+                  (   ( $pad{I1362} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 3484 3486+                   ( ( substr( $s, $pos, 1 ) eq chr(39) )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1362} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 3495 3678+                  (   ( $pad{I1363} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 3495 3673+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { metasyntax => {+                            metasyntax => "${$_[0]}",+                            },+                       _pos => [ $_[0]->from, $_[0]->to ],+                    };+            }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1363} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1348} ) or 1 )+               &&   +               ## <group>+               ## pos: 3679 3712+                (   ( $pad{I1364} = $pos or 1 ) &&+                 ## <closure>+                 ## pos: 3680 3711+                 do { +                   local $::_V6_SUCCEED = 1;+                   $::_V6_MATCH_ = $m;+                   sub { die "invalid alias syntax"; }->( $m );+                   1;+                 }+                 ## </closure>+     ||    ( ( $pos = $pad{I1364} ) && 0 ) )+               ## </group>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token parse_metasyntax+*parse_metasyntax =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 3748 6621+           (+      +             ## <group>+             ## pos: 3748 3792+              (   ( $pad{I1365} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 3748 3787+               do{+                    my $from = $pos;+                    my $bool =                    ## <alt>+                       ## pos: 3764 3786+                       (+                           ( $pad{I1366} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 3764 3769+                            (   ( $pad{I1367} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 3765 3768+                             ( ( substr( $s, $pos, 1 ) eq '!' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1367} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1366} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 3770 3775+                            (   ( $pad{I1368} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 3771 3774+                             ( ( substr( $s, $pos, 1 ) eq '?' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1368} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1366} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 3776 3781+                            (   ( $pad{I1369} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 3777 3780+                             ( ( substr( $s, $pos, 1 ) eq '.' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1369} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1366} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 3782 3786+                            (   ( $pad{I1370} = $pos or 1 ) &&+     1 # null constant+     ||    ( ( $pos = $pad{I1370} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+    ;+                    my $match = Pugs::Runtime::Match->new(+                        { str => \$s, from => \$from, match => [], named => {}, bool => \1, to => \(0+$pos), capture => undef }+                    ); $named{'modifier'} = $match;+                    $bool+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1365} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 3792 6621+              (   ( $pad{I1371} = $pos or 1 ) &&+               ## <alt>+               ## pos: 3793 6619+               (+                   ( $pad{I1372} = $pos or 1 )+                   && (+                   ## <concat>+                   ## pos: 3793 4011+                   (+      +                     ## <group>+                     ## pos: 3793 3807+                      (   ( $pad{I1373} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 3802 3805+                       ( ( substr( $s, $pos, 1 ) eq '{' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1373} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 3807 3822+                      (   ( $pad{I1374} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 3807 3820+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->parsed_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parsed_code'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1374} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 3822 3835+                      (   ( $pad{I1375} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 3822 3826+                       ( ( substr( $s, $pos, 2 ) eq '}>' )+                           ? ( $pos += 2 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1375} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 3835 4011+                      (   ( $pad{I1376} = $pos or 1 ) &&+                       ## <closure>+                       ## pos: 3835 4006+                       do {+                         local $::_V6_SUCCEED = 1;+                         $::_V6_MATCH_ = $m;+                         $m->data->{capture} = \( sub { return { closure => {+                closure  => ${ $_[0]->{qw(parsed_code)} },+                modifier => ${ $_[0]->{qw(modifier)} },+            },+                _pos => [ $_[0]->from - 1, $_[0]->to ],+            } }->( $m ) ); +                         $bool = $::_V6_SUCCEED;+                         $::_V6_MATCH_ = $m if $bool; +                         return $m if $bool; +                       }+                       ## </closure>+     ||    ( ( $pos = $pad{I1376} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1372} ) or 1 )+                   &&                ## <concat>+                   ## pos: 4012 4505+                   (+      +                     ## <group>+                     ## pos: 4012 4042+                      (   ( $pad{I1377} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 4021 4033+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1377} ) && 0 ) )+                     ## </group>+    +                   &&+                     ## <quant>+                     ## pos: 4042 4075+                     (+                      (   ( $pad{I1378} = $pos or 1 ) &&+    +                         ## <capture>+                         do{+                             my $hash = do {+                               my $bool = 1;+                               my $from = $pos;+                               my @match;+                               my %named;+                               $bool = 0 unless+                                 ## <concat>+                                 ## pos: 4043 4064+                                 (+      +                                   ## <group>+                                   ## pos: 4043 4051+                                    (   ( $pad{I1379} = $pos or 1 ) &&+                                     ## <perl5>+                                     ( ( substr( $s, $pos ) =~ m/^((?:(?=[+-]))\X)/ )+                                         ? ( $pos += length( $1 ) or 1 )+                                         : 0+                                     )+                                     ## </perl5>+     ||    ( ( $pos = $pad{I1379} ) && 0 ) )+                                   ## </group>+    +                                 &&+      +                                   ## <group>+                                   ## pos: 4051 4064+                                    (   ( $pad{I1380} = $pos or 1 ) &&+                                     ## <named_capture>+                                     ## pos: 4051 4063+                                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                                 $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                     ## </named_capture>+     ||    ( ( $pos = $pad{I1380} ) && 0 ) )+                                   ## </group>+    +                                 )+                                 ## </concat>+    ;+                               { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                             };+                             my $bool = ${$hash->{'bool'}};+                             if ( $bool ) {+                                 push @{ $match[ 0 ] }, Pugs::Runtime::Match->new( $hash );+                             }+                             $bool;+                         }+                         ## </capture>+     ||    ( ( $pos = $pad{I1378} ) && 0 ) )+                     && do { while (+                      (   ( $pad{I1378} = $pos or 1 ) &&+    +                         ## <capture>+                         do{+                             my $hash = do {+                               my $bool = 1;+                               my $from = $pos;+                               my @match;+                               my %named;+                               $bool = 0 unless+                                 ## <concat>+                                 ## pos: 4043 4064+                                 (+      +                                   ## <group>+                                   ## pos: 4043 4051+                                    (   ( $pad{I1379} = $pos or 1 ) &&+                                     ## <perl5>+                                     ( ( substr( $s, $pos ) =~ m/^((?:(?=[+-]))\X)/ )+                                         ? ( $pos += length( $1 ) or 1 )+                                         : 0+                                     )+                                     ## </perl5>+     ||    ( ( $pos = $pad{I1379} ) && 0 ) )+                                   ## </group>+    +                                 &&+      +                                   ## <group>+                                   ## pos: 4051 4064+                                    (   ( $pad{I1380} = $pos or 1 ) &&+                                     ## <named_capture>+                                     ## pos: 4051 4063+                                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                                 $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                     ## </named_capture>+     ||    ( ( $pos = $pad{I1380} ) && 0 ) )+                                   ## </group>+    +                                 )+                                 ## </concat>+    ;+                               { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                             };+                             my $bool = ${$hash->{'bool'}};+                             if ( $bool ) {+                                 push @{ $match[ 0 ] }, Pugs::Runtime::Match->new( $hash );+                             }+                             $bool;+                         }+                         ## </capture>+     ||    ( ( $pos = $pad{I1378} ) && 0 ) )) {}; $bool = 1 }+                     )+                     ## </quant>+    +                   &&+      +                     ## <group>+                     ## pos: 4075 4086+                      (   ( $pad{I1381} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 4075 4077+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1381} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 4086 4505+                      (   ( $pad{I1382} = $pos or 1 ) &&+                       ## <closure>+                       ## pos: 4086 4500+                       do {+                         local $::_V6_SUCCEED = 1;+                         $::_V6_MATCH_ = $m;+                         $m->data->{capture} = \( sub {+                if ( ${ $_[0]->{qw(modifier)} } eq '!' ) {+                  return {+                    negate => {+                      char_class => [+                        '+' . $_[0]->{qw(char_class)},+                        @{$_[0]->[0]},   # TODO - stringify+                  ] } }+                }+                return {+                  char_class => [+                    '+' . $_[0]->{qw(char_class)},+                    @{$_[0]->[0]},   # TODO - stringify+                ] }+            }->( $m ) ); +                         $bool = $::_V6_SUCCEED;+                         $::_V6_MATCH_ = $m if $bool; +                         return $m if $bool; +                       }+                       ## </closure>+     ||    ( ( $pos = $pad{I1382} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1372} ) or 1 )+                   &&                ## <concat>+                   ## pos: 4506 6394+                   (+      +                     ## <group>+                     ## pos: 4506 4531+                      (   ( $pad{I1383} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 4515 4522+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->ident( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'ident'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1383} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 4531 6394+                      (   ( $pad{I1384} = $pos or 1 ) &&+                       ## <alt>+                       ## pos: 4532 6388+                       (+                           ( $pad{I1385} = $pos or 1 )+                           && (+                           ## <concat>+                           ## pos: 4532 5149+                           (+      +                             ## <group>+                             ## pos: 4532 4549+                              (   ( $pad{I1386} = $pos or 1 ) &&+                               ## <metasyntax>+                               ## pos: 4543 4548+                               do {+                                    my $prior = $::_V6_PRIOR_;+                                    my $match =+                                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                    $::_V6_PRIOR_ = $prior;+                                    my $bool = (!$match != 1);+                                    $pos = $match->to if $bool;+                                    $match;+                               }+                               ## </metasyntax>+     ||    ( ( $pos = $pad{I1386} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 4549 4556+                              (   ( $pad{I1387} = $pos or 1 ) &&+                               ## <named_capture>+                               ## pos: 4549 4555+                               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                               ## </named_capture>+     ||    ( ( $pos = $pad{I1387} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 4556 4569+                              (   ( $pad{I1388} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 4556 4558+                               ( ( substr( $s, $pos, 1 ) eq '>' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1388} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 4569 5149+                              (   ( $pad{I1389} = $pos or 1 ) &&+                               ## <closure>+                               ## pos: 4569 5140+                               do {+                                 local $::_V6_SUCCEED = 1;+                                 $::_V6_MATCH_ = $m;+                                 $m->data->{capture} = \( sub {+                if  ( ${ $_[0]->{qw(ident)} } eq 'before'+                   || ${ $_[0]->{qw(ident)} } eq 'after'+                    ) {+                    return { ${ $_[0]->{qw(ident)} } => {+                        rule => ${ $_[0]->{qw(rule)} }, modifier => ${ $_[0]->{qw(modifier)} },+                         }, _pos => [ $_[0]->from - 1, $_[0]->to ], }+                }+                return { metasyntax => {+                            metasyntax => ${ $_[0]->{qw(ident)} },+                            rule       => ${ $_[0]->{qw(rule)} },+                            modifier   => ${ $_[0]->{qw(modifier)} },+                        },+                        _pos => [ $_[0]->from - 1, $_[0]->to ],+                    }+              }->( $m ) ); +                                 $bool = $::_V6_SUCCEED;+                                 $::_V6_MATCH_ = $m if $bool; +                                 return $m if $bool; +                               }+                               ## </closure>+     ||    ( ( $pos = $pad{I1389} ) && 0 ) )+                             ## </group>+    +                           )+                           ## </concat>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1385} ) or 1 )+                           &&                        ## <concat>+                           ## pos: 5150 6129+                           (+      +                             ## <group>+                             ## pos: 5150 5165+                              (   ( $pad{I1390} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 5161 5164+                               ( ( substr( $s, $pos, 1 ) eq ':' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1390} ) && 0 ) )+                             ## </group>+    +                           &&+                             ## <quant>+                             ## pos: 5165 5182+                             (+                              (   ( $pad{I1391} = $pos or 1 ) &&+                                 ## <metasyntax>+                                 ## pos: 5165 5170+                                 do {+                                      my $prior = $::_V6_PRIOR_;+                                      my $match =+                                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                      $::_V6_PRIOR_ = $prior;+                                      my $bool = (!$match != 1);+                                      $pos = $match->to if $bool;+                                      $match;+                                 }+                                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1391} ) && 0 ) )+                             || ( $bool = 1 )+                             )+                             ## </quant>+    +                           &&+      +                             ## <group>+                             ## pos: 5182 5352+                              (   ( $pad{I1392} = $pos or 1 ) &&+                               ## <named_capture>+                               ## pos: 5182 5341+                               do{+                    my $from = $pos;+                    my $bool =                                    ## <quant>+                                       ## pos: 5193 5340+                                       do { while (+                                        (   ( $pad{I1393} = $pos or 1 ) &&+                                           ## <alt>+                                           ## pos: 5207 5327+                                           (+                                               ( $pad{I1394} = $pos or 1 )+                                               && (+                                               ## <concat>+                                               ## pos: 5221 5253+                                               (+      +                                                 ## <group>+                                                 ## pos: 5221 5226+                                                  (   ( $pad{I1395} = $pos or 1 ) &&+    +                                                   ## <constant>+                                                   ## pos: 5223 5225+                                                   ( ( substr( $s, $pos, 1 ) eq '\\' )+                                                       ? ( $pos += 1 or 1 )+                                                       : 0+                                                   )+                                                   ## </constant>+     ||    ( ( $pos = $pad{I1395} ) && 0 ) )+                                                 ## </group>+    +                                               &&+      +                                                 ## <group>+                                                 ## pos: 5226 5253+                                                  (   ( $pad{I1396} = $pos or 1 ) &&+                                                   ## <named_capture>+                                                   ## pos: 5226 5240+                                                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                                               $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'special_char'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                                   ## </named_capture>+     ||    ( ( $pos = $pad{I1396} ) && 0 ) )+                                                 ## </group>+    +                                               )+                                               ## </concat>+    +                                               )+                                             || (+                                               ( ( $bool = 1 ) && ( $pos = $pad{I1394} ) or 1 )+                                               &&   +                                               ## <group>+                                               ## pos: 5254 5302+                                                (   ( $pad{I1397} = $pos or 1 ) &&+                                                ## <metasyntax>+                                                 ## pos: 5256 5289+                                                 do{+                    my $match = +              ## <variable>+              ## pos: 5256 5289+              do {+                our $I1398;+                our $I1398_sizes;+                unless ( $I1398 ) {+                    my $hash = \%Pugs::Grammar::Rule::variables;+                    my %sizes = map { length($_) => 1 } keys %$hash;+                    $I1398_sizes = [ sort { $b <=> $a } keys %sizes ];+                    $I1398 = $hash;+                }+                my $match = 0;+                my $key;+                for ( @$I1398_sizes ) {+                    $key = ( $pos <= length( $s )+                                ? substr( $s, $pos, $_ )+                                : '' );+                    if ( exists $I1398->{$key} ) {+                        #$named{KEY} = $key;+                        #$::_V6_MATCH_ = $m;+                        #print "m: ", Dumper( $::_V6_MATCH_->data )+                        #    if ( $key eq 'until' );+                        $match = Pugs::Runtime::Regex::preprocess_hash( $I1398, $key )->( $s, $grammar, { p => ( $pos + $_ ), positionals => [ ], args => { KEY => $key } }, undef );+                        last if $match;+                    }+                }+                if ( $match ) {+                    $pos = $match->to;+                    #print "match: $key at $pos = ", Dumper( $match->data );+                    $bool = 1;+                }; # else { $bool = 0 }+                $match;+              }+              ## </variable>+    ;+                    if ( $match ) { push @{$named{'Pugs::Grammar::Rule::variables'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                                                ## </metasyntax>+     ||    ( ( $pos = $pad{I1397} ) && 0 ) )+                                               ## </group>+    +                                               )+                                             || (+                                               ( ( $bool = 1 ) && ( $pos = $pad{I1394} ) or 1 )+                                               &&   +                                               ## <group>+                                               ## pos: 5303 5327+                                                (   ( $pad{I1399} = $pos or 1 ) &&+                                                 ## <perl5>+                                                 ( ( substr( $s, $pos ) =~ m/^((?:(?![\>]))\X)/ )+                                                     ? ( $pos += length( $1 ) or 1 )+                                                     : 0+                                                 )+                                                 ## </perl5>+     ||    ( ( $pos = $pad{I1399} ) && 0 ) )+                                               ## </group>+    +                                             )+                                           )+                                           ## </alt>+     ||    ( ( $pos = $pad{I1393} ) && 0 ) )) {}; $bool = 1 }+                                       ## </quant>+    ;+                    my $match = Pugs::Runtime::Match->new(+                        { str => \$s, from => \$from, match => [], named => {}, bool => \1, to => \(0+$pos), capture => undef }+                    ); $named{'str'} = $match;+                    $bool+                }+                               ## </named_capture>+     ||    ( ( $pos = $pad{I1392} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 5352 5365+                              (   ( $pad{I1400} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 5352 5354+                               ( ( substr( $s, $pos, 1 ) eq '>' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1400} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 5365 6129+                              (   ( $pad{I1401} = $pos or 1 ) &&+                               ## <closure>+                               ## pos: 5365 6120+                               do {+                                 local $::_V6_SUCCEED = 1;+                                 $::_V6_MATCH_ = $m;+                                 $m->data->{capture} = \( sub {+                if  ( ${ $_[0]->{qw(ident)} } eq 'before'+                   || ${ $_[0]->{qw(ident)} } eq 'after'+                    ) {+                    return { ${ $_[0]->{qw(ident)} } => {+                        rule     => { metasyntax => {+                                    metasyntax => '\'' . ${ $_[0]->{qw(str)} } . '\'',+                                },+                            _pos => [ $_[0]->{qw(str)}->from, $_[0]->{qw(str)}->to ],                   },+                        modifier => ${ $_[0]->{qw(modifier)} },+                        _pos => [ $_[0]->from - 1, $_[0]->to ],+                    } }+                }+                return { metasyntax => {+                    metasyntax => ${ $_[0]->{qw(ident)} },+                    string   => ${ $_[0]->{qw(str)} },+                    modifier => ${ $_[0]->{qw(modifier)} },+                },+                    _pos => [ $_[0]->from - 1, $_[0]->to ],+                }+              }->( $m ) ); +                                 $bool = $::_V6_SUCCEED;+                                 $::_V6_MATCH_ = $m if $bool; +                                 return $m if $bool; +                               }+                               ## </closure>+     ||    ( ( $pos = $pad{I1401} ) && 0 ) )+                             ## </group>+    +                           )+                           ## </concat>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1385} ) or 1 )+                           &&                        ## <concat>+                           ## pos: 6130 6388+                           (+      +                             ## <group>+                             ## pos: 6130 6145+                              (   ( $pad{I1402} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 6141 6143+                               ( ( substr( $s, $pos, 1 ) eq '(' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1402} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 6145 6160+                              (   ( $pad{I1403} = $pos or 1 ) &&+                               ## <named_capture>+                               ## pos: 6145 6158+                               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                           $grammar->parsed_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parsed_code'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                               ## </named_capture>+     ||    ( ( $pos = $pad{I1403} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 6160 6163+                              (   ( $pad{I1404} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 6160 6162+                               ( ( substr( $s, $pos, 1 ) eq ')' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1404} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 6163 6176+                              (   ( $pad{I1405} = $pos or 1 ) &&+    +                               ## <constant>+                               ## pos: 6163 6165+                               ( ( substr( $s, $pos, 1 ) eq '>' )+                                   ? ( $pos += 1 or 1 )+                                   : 0+                               )+                               ## </constant>+     ||    ( ( $pos = $pad{I1405} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 6176 6388+                              (   ( $pad{I1406} = $pos or 1 ) &&+                               ## <closure>+                               ## pos: 6176 6379+                               do {+                                 local $::_V6_SUCCEED = 1;+                                 $::_V6_MATCH_ = $m;+                                 $m->data->{capture} = \( sub { return { call => {+                  method   => ${ $_[0]->{qw(ident)} },+                  params   => ${ $_[0]->{qw(parsed_code)} },+                  modifier => ${ $_[0]->{qw(modifier)} },+              },+                  _pos => [$_[0]->from - 1, $_[0]->to], } }->( $m ) ); +                                 $bool = $::_V6_SUCCEED;+                                 $::_V6_MATCH_ = $m if $bool; +                                 return $m if $bool; +                               }+                               ## </closure>+     ||    ( ( $pos = $pad{I1406} ) && 0 ) )+                             ## </group>+    +                           )+                           ## </concat>+    +                         )+                       )+                       ## </alt>+     ||    ( ( $pos = $pad{I1384} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                   )+                 || (+                   ( ( $bool = 1 ) && ( $pos = $pad{I1372} ) or 1 )+                   &&                ## <concat>+                   ## pos: 6395 6619+                   (+      +                     ## <group>+                     ## pos: 6395 6418+                      (   ( $pad{I1407} = $pos or 1 ) &&+                       ## <named_capture>+                       ## pos: 6404 6416+                       do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                   $grammar->metasyntax( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'metasyntax'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                       ## </named_capture>+     ||    ( ( $pos = $pad{I1407} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 6418 6429+                      (   ( $pad{I1408} = $pos or 1 ) &&+    +                       ## <constant>+                       ## pos: 6418 6420+                       ( ( substr( $s, $pos, 1 ) eq '>' )+                           ? ( $pos += 1 or 1 )+                           : 0+                       )+                       ## </constant>+     ||    ( ( $pos = $pad{I1408} ) && 0 ) )+                     ## </group>+    +                   &&+      +                     ## <group>+                     ## pos: 6429 6619+                      (   ( $pad{I1409} = $pos or 1 ) &&+                       ## <closure>+                       ## pos: 6429 6614+                       do {+                         local $::_V6_SUCCEED = 1;+                         $::_V6_MATCH_ = $m;+                         $m->data->{capture} = \( sub { return { metasyntax => {+                  metasyntax => "${ $_[0]->{qw(metasyntax)} }",+                  modifier   => ${ $_[0]->{qw(modifier)} },+            },+                  _pos => [ $_[0]->from - 1, $_[0]->to ],+            } }->( $m ) ); +                         $bool = $::_V6_SUCCEED;+                         $::_V6_MATCH_ = $m if $bool; +                         return $m if $bool; +                       }+                       ## </closure>+     ||    ( ( $pos = $pad{I1409} ) && 0 ) )+                     ## </group>+    +                   )+                   ## </concat>+    +                 )+               )+               ## </alt>+     ||    ( ( $pos = $pad{I1371} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token var1+*var1 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 6731 6833+           (+      +             ## <group>+             ## pos: 6731 6739+              (   ( $pad{I1410} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 6731 6738+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ident( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'ident'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1410} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 6739 6750+              (   ( $pad{I1411} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 6739 6741+               ( ( substr( $s, $pos, 1 ) eq '>' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1411} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 6750 6833+              (   ( $pad{I1412} = $pos or 1 ) &&+               ## <closure>+               ## pos: 6750 6832+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { match_variable => '$' . $_[0]->{ident}, _pos => [$_[0]->from - 2, $_[0]->to], }; }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1412} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $variables{'$<'} = sub { var1($_[1], $_[0], $_[2], $_[3]) }; ++# token var2+*var2 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 6925 7149+           (+               ( $pad{I1413} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 6925 7023+               (+                 ## <quant>+                 ## pos: 6925 6943+                 (+                  (   ( $pad{I1414} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 6925 6933+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1414} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1414} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 6925 6933+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1414} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 6943 7023+                  (   ( $pad{I1415} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 6943 7018+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { match_variable => '$' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to], }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1415} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1413} ) or 1 )+               &&            ## <concat>+               ## pos: 7024 7149+               (+                 ## <quant>+                 ## pos: 7024 7045+                 (+                  (   ( $pad{I1416} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 7033 7035+                     ( ( substr( $s, $pos, 1 ) eq '^' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1416} ) && 0 ) )+                 || ( $bool = 1 )+                 )+                 ## </quant>+    +               &&+                 ## <quant>+                 ## pos: 7045 7079+                 (+                  (   ( $pad{I1417} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7046 7068+                     (+                         ( $pad{I1418} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7046 7056+                          (   ( $pad{I1419} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7047 7055+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1419} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1418} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7057 7060+                          (   ( $pad{I1420} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7058 7059+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1420} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1418} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7061 7068+                         (+      +                           ## <group>+                           ## pos: 7061 7065+                            (   ( $pad{I1421} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7062 7064+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1421} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7065 7068+                            (   ( $pad{I1422} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7065 7067+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1422} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1417} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1417} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7046 7068+                     (+                         ( $pad{I1418} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7046 7056+                          (   ( $pad{I1419} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7047 7055+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1419} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1418} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7057 7060+                          (   ( $pad{I1420} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7058 7059+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1420} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1418} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7061 7068+                         (+      +                           ## <group>+                           ## pos: 7061 7065+                            (   ( $pad{I1421} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7062 7064+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1421} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7065 7068+                            (   ( $pad{I1422} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7065 7067+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1422} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1417} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 7079 7149+                  (   ( $pad{I1423} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 7079 7148+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { variable => '$' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to], }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1423} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $variables{'$'} = sub { var2($_[1], $_[0], $_[2], $_[3]) }; ++# token var3+*var3 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 7240 7462+           (+               ( $pad{I1424} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 7240 7337+               (+                 ## <quant>+                 ## pos: 7240 7258+                 (+                  (   ( $pad{I1425} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 7240 7248+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1425} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1425} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 7240 7248+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1425} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 7258 7337+                  (   ( $pad{I1426} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 7258 7332+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { match_variable => '@' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to], } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1426} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1424} ) or 1 )+               &&            ## <concat>+               ## pos: 7338 7462+               (+                 ## <quant>+                 ## pos: 7338 7359+                 (+                  (   ( $pad{I1427} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 7347 7349+                     ( ( substr( $s, $pos, 1 ) eq '^' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1427} ) && 0 ) )+                 || ( $bool = 1 )+                 )+                 ## </quant>+    +               &&+                 ## <quant>+                 ## pos: 7359 7393+                 (+                  (   ( $pad{I1428} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7360 7382+                     (+                         ( $pad{I1429} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7360 7370+                          (   ( $pad{I1430} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7361 7369+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1430} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1429} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7371 7374+                          (   ( $pad{I1431} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7372 7373+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1431} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1429} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7375 7382+                         (+      +                           ## <group>+                           ## pos: 7375 7379+                            (   ( $pad{I1432} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7376 7378+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1432} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7379 7382+                            (   ( $pad{I1433} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7379 7381+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1433} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1428} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1428} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7360 7382+                     (+                         ( $pad{I1429} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7360 7370+                          (   ( $pad{I1430} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7361 7369+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1430} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1429} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7371 7374+                          (   ( $pad{I1431} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7372 7373+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1431} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1429} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7375 7382+                         (+      +                           ## <group>+                           ## pos: 7375 7379+                            (   ( $pad{I1432} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7376 7378+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1432} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7379 7382+                            (   ( $pad{I1433} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7379 7381+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1433} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1428} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 7393 7462+                  (   ( $pad{I1434} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 7393 7461+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { variable => '@' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to], } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1434} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $variables{'@'} = sub { var3($_[1], $_[0], $_[2], $_[3]) }; ++# token var4+*var4 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 7553 7773+           (+               ( $pad{I1435} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 7553 7649+               (+                 ## <quant>+                 ## pos: 7553 7571+                 (+                  (   ( $pad{I1436} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 7553 7561+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1436} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1436} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 7553 7561+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->digit( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1436} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 7571 7649+                  (   ( $pad{I1437} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 7571 7644+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { match_variable => '%' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to] } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1437} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1435} ) or 1 )+               &&            ## <concat>+               ## pos: 7650 7773+               (+                 ## <quant>+                 ## pos: 7650 7671+                 (+                  (   ( $pad{I1438} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 7659 7661+                     ( ( substr( $s, $pos, 1 ) eq '^' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1438} ) && 0 ) )+                 || ( $bool = 1 )+                 )+                 ## </quant>+    +               &&+                 ## <quant>+                 ## pos: 7671 7705+                 (+                  (   ( $pad{I1439} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7672 7694+                     (+                         ( $pad{I1440} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7672 7682+                          (   ( $pad{I1441} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7673 7681+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1441} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1440} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7683 7686+                          (   ( $pad{I1442} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7684 7685+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1442} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1440} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7687 7694+                         (+      +                           ## <group>+                           ## pos: 7687 7691+                            (   ( $pad{I1443} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7688 7690+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1443} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7691 7694+                            (   ( $pad{I1444} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7691 7693+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1444} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1439} ) && 0 ) )+                 && do { while (+                  (   ( $pad{I1439} = $pos or 1 ) &&+                     ## <alt>+                     ## pos: 7672 7694+                     (+                         ( $pad{I1440} = $pos or 1 )+                         && (+      +                         ## <group>+                         ## pos: 7672 7682+                          (   ( $pad{I1441} = $pos or 1 ) &&+                           ## <metasyntax>+                           ## pos: 7673 7681+                           do {+                                my $prior = $::_V6_PRIOR_;+                                my $match =+                                       $grammar->alnum( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                $::_V6_PRIOR_ = $prior;+                                my $bool = (!$match != 1);+                                $pos = $match->to if $bool;+                                $match;+                           }+                           ## </metasyntax>+     ||    ( ( $pos = $pad{I1441} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1440} ) or 1 )+                         &&   +                         ## <group>+                         ## pos: 7683 7686+                          (   ( $pad{I1442} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 7684 7685+                           ( ( substr( $s, $pos, 1 ) eq '_' )+                               ? ( $pos += 1 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1442} ) && 0 ) )+                         ## </group>+    +                         )+                       || (+                         ( ( $bool = 1 ) && ( $pos = $pad{I1440} ) or 1 )+                         &&                      ## <concat>+                         ## pos: 7687 7694+                         (+      +                           ## <group>+                           ## pos: 7687 7691+                            (   ( $pad{I1443} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7688 7690+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1443} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 7691 7694+                            (   ( $pad{I1444} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 7691 7693+                             ( ( substr( $s, $pos, 1 ) eq ':' )+                                 ? ( $pos += 1 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1444} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    +                       )+                     )+                     ## </alt>+     ||    ( ( $pos = $pad{I1439} ) && 0 ) )) {}; $bool = 1 }+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 7705 7773+                  (   ( $pad{I1445} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 7705 7772+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { variable => '%' . $_[0], _pos => [$_[0]->from - 1, $_[0]->to] } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1445} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $variables{'%'} = sub { var4($_[1], $_[0], $_[2], $_[3]) }; ++# token term1+*term1 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 7974 8124+            (   ( $pad{I1446} = $pos or 1 ) &&+             ## <closure>+             ## pos: 7974 8123+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { metasyntax => {+                            metasyntax => 'null',+            },+                            _pos => [ $_[0]->from, $_[0]->to ],+            } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1446} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'{*}'} = sub { term1($_[1], $_[0], $_[2], $_[3]) }; ++# token term2+*term2 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 8220 8435+           (+      +             ## <group>+             ## pos: 8220 8235+              (   ( $pad{I1447} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 8220 8230+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->literal( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1447} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8235 8246+              (   ( $pad{I1448} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 8235 8237+               ( ( substr( $s, $pos, 1 ) eq chr(39) )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1448} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8246 8435+              (   ( $pad{I1449} = $pos or 1 ) &&+               ## <closure>+               ## pos: 8246 8434+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                    metasyntax => {+                        metasyntax => '\'' . ${$_[0]},+                    },+                        _pos => [ $_[0]->from - 1, $_[0]->to ],+                };+            }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1449} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'\''} = sub { term2($_[1], $_[0], $_[2], $_[3]) }; ++# token term3+*term3 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 8530 8646+           (+      +             ## <group>+             ## pos: 8530 8537+              (   ( $pad{I1450} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 8530 8536+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1450} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8537 8548+              (   ( $pad{I1451} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 8537 8539+               ( ( substr( $s, $pos, 1 ) eq ')' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1451} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8548 8646+              (   ( $pad{I1452} = $pos or 1 ) &&+               ## <closure>+               ## pos: 8548 8645+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { capturing_group => ${ $_[0]->{qw(rule)} },+                       _pos => [ $_[0]->from - 1, $_[0]->to ], }; }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1452} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'('} = sub { term3($_[1], $_[0], $_[2], $_[3]) }; ++# token term4+*term4 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 8740 8861+           (+      +             ## <group>+             ## pos: 8740 8748+              (   ( $pad{I1453} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 8740 8746+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1453} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8748 8761+              (   ( $pad{I1454} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 8748 8752+               ( ( substr( $s, $pos, 2 ) eq ')>' )+                   ? ( $pos += 2 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1454} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 8761 8861+              (   ( $pad{I1455} = $pos or 1 ) &&+               ## <closure>+               ## pos: 8761 8860+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { capture_as_result => ${ $_[0]->{qw(rule)} },+                       _pos => [ $_[0]->from - 2, $_[0]->to ], }; }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1455} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<('} = sub { term4($_[1], $_[0], $_[2], $_[3]) }; ++# token term5+*term5 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 8956 9216+           (+      +             ## <group>+             ## pos: 8956 8977+              (   ( $pad{I1456} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 8956 8968+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1456} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 8977 9010+             do { while (+              (   ( $pad{I1457} = $pos or 1 ) &&+    +                 ## <capture>+                 do{+                     my $hash = do {+                       my $bool = 1;+                       my $from = $pos;+                       my @match;+                       my %named;+                       $bool = 0 unless+                         ## <concat>+                         ## pos: 8978 8999+                         (+      +                           ## <group>+                           ## pos: 8978 8986+                            (   ( $pad{I1458} = $pos or 1 ) &&+                             ## <perl5>+                             ( ( substr( $s, $pos ) =~ m/^((?:(?=[+-]))\X)/ )+                                 ? ( $pos += length( $1 ) or 1 )+                                 : 0+                             )+                             ## </perl5>+     ||    ( ( $pos = $pad{I1458} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 8986 8999+                            (   ( $pad{I1459} = $pos or 1 ) &&+                             ## <named_capture>+                             ## pos: 8986 8998+                             do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                         $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                             ## </named_capture>+     ||    ( ( $pos = $pad{I1459} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    ;+                       { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                     };+                     my $bool = ${$hash->{'bool'}};+                     if ( $bool ) {+                         push @{ $match[ 0 ] }, Pugs::Runtime::Match->new( $hash );+                     }+                     $bool;+                 }+                 ## </capture>+     ||    ( ( $pos = $pad{I1457} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 9010 9021+              (   ( $pad{I1460} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 9010 9012+               ( ( substr( $s, $pos, 1 ) eq '>' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1460} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 9021 9216+              (   ( $pad{I1461} = $pos or 1 ) &&+               ## <closure>+               ## pos: 9021 9215+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                _pos => [ $_[0]->from - 2, $_[0]->to ],+                char_class => [+                    '+' . $_[0]->{qw(char_class)},+                    @{$_[0]->[0]},   # TODO - stringify+                ] }+            }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1461} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<+'} = sub { term5($_[1], $_[0], $_[2], $_[3]) }; ++# token term6+*term6 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 9311 9571+           (+      +             ## <group>+             ## pos: 9311 9332+              (   ( $pad{I1462} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 9311 9323+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1462} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 9332 9365+             do { while (+              (   ( $pad{I1463} = $pos or 1 ) &&+    +                 ## <capture>+                 do{+                     my $hash = do {+                       my $bool = 1;+                       my $from = $pos;+                       my @match;+                       my %named;+                       $bool = 0 unless+                         ## <concat>+                         ## pos: 9333 9354+                         (+      +                           ## <group>+                           ## pos: 9333 9341+                            (   ( $pad{I1464} = $pos or 1 ) &&+                             ## <perl5>+                             ( ( substr( $s, $pos ) =~ m/^((?:(?=[+-]))\X)/ )+                                 ? ( $pos += length( $1 ) or 1 )+                                 : 0+                             )+                             ## </perl5>+     ||    ( ( $pos = $pad{I1464} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 9341 9354+                            (   ( $pad{I1465} = $pos or 1 ) &&+                             ## <named_capture>+                             ## pos: 9341 9353+                             do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                         $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                             ## </named_capture>+     ||    ( ( $pos = $pad{I1465} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    ;+                       { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                     };+                     my $bool = ${$hash->{'bool'}};+                     if ( $bool ) {+                         push @{ $match[ 0 ] }, Pugs::Runtime::Match->new( $hash );+                     }+                     $bool;+                 }+                 ## </capture>+     ||    ( ( $pos = $pad{I1463} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 9365 9376+              (   ( $pad{I1466} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 9365 9367+               ( ( substr( $s, $pos, 1 ) eq '>' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1466} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 9376 9571+              (   ( $pad{I1467} = $pos or 1 ) &&+               ## <closure>+               ## pos: 9376 9570+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                _pos => [ $_[0]->from - 2, $_[0]->to ],+                char_class => [+                    '-' . $_[0]->{qw(char_class)},+                    @{$_[0]->[0]},   # TODO - stringify+                ] }+            }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1467} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<-'} = sub { term6($_[1], $_[0], $_[2], $_[3]) }; ++# token term7+*term7 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 9666 9937+           (+      +             ## <group>+             ## pos: 9666 9680+              (   ( $pad{I1468} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 9666 9678+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->char_range( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_range'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1468} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 9680 9691+              (   ( $pad{I1469} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 9680 9682+               ( ( substr( $s, $pos, 1 ) eq ']' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1469} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 9691 9724+             do { while (+              (   ( $pad{I1470} = $pos or 1 ) &&+    +                 ## <capture>+                 do{+                     my $hash = do {+                       my $bool = 1;+                       my $from = $pos;+                       my @match;+                       my %named;+                       $bool = 0 unless+                         ## <concat>+                         ## pos: 9692 9713+                         (+      +                           ## <group>+                           ## pos: 9692 9700+                            (   ( $pad{I1471} = $pos or 1 ) &&+                             ## <perl5>+                             ( ( substr( $s, $pos ) =~ m/^((?:(?=[+-]))\X)/ )+                                 ? ( $pos += length( $1 ) or 1 )+                                 : 0+                             )+                             ## </perl5>+     ||    ( ( $pos = $pad{I1471} ) && 0 ) )+                           ## </group>+    +                         &&+      +                           ## <group>+                           ## pos: 9700 9713+                            (   ( $pad{I1472} = $pos or 1 ) &&+                             ## <named_capture>+                             ## pos: 9700 9712+                             do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                         $grammar->char_class( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'char_class'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                             ## </named_capture>+     ||    ( ( $pos = $pad{I1472} ) && 0 ) )+                           ## </group>+    +                         )+                         ## </concat>+    ;+                       { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                     };+                     my $bool = ${$hash->{'bool'}};+                     if ( $bool ) {+                         push @{ $match[ 0 ] }, Pugs::Runtime::Match->new( $hash );+                     }+                     $bool;+                 }+                 ## </capture>+     ||    ( ( $pos = $pad{I1470} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 9724 9735+              (   ( $pad{I1473} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 9724 9726+               ( ( substr( $s, $pos, 1 ) eq '>' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1473} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 9735 9937+              (   ( $pad{I1474} = $pos or 1 ) &&+               ## <closure>+               ## pos: 9735 9936+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                _pos => [ $_[0]->from - 2, $_[0]->to ],+                char_class => [+                    '+[' . $_[0]->{qw(char_range)} . ']',+                    @{$_[0]->[0]},   # TODO - stringify+                ] }+            }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1474} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<['} = sub { term7($_[1], $_[0], $_[2], $_[3]) }; ++# token term8+*term8 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 10032 10091+           (+      +             ## <group>+             ## pos: 10032 10059+              (   ( $pad{I1475} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 10032 10050+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->parse_metasyntax( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parse_metasyntax'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1475} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10059 10091+              (   ( $pad{I1476} = $pos or 1 ) &&+               ## <closure>+               ## pos: 10059 10090+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return ${ $_[0]->{qw(parse_metasyntax)} } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1476} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<'} = sub { term8($_[1], $_[0], $_[2], $_[3]) }; ++# token term9+*term9 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 10185 10375+           (+      +             ## <group>+             ## pos: 10185 10200+              (   ( $pad{I1477} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 10185 10198+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->parsed_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parsed_code'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1477} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10200 10211+              (   ( $pad{I1478} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 10200 10202+               ( ( substr( $s, $pos, 1 ) eq '}' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1478} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10211 10375+              (   ( $pad{I1479} = $pos or 1 ) &&+               ## <closure>+               ## pos: 10211 10374+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { closure => {+                closure => ${ $_[0]->{qw(parsed_code)} },+                modifier => 'plain',+            },+                _pos => [$_[0]->from - 1, $_[0]->to],+            } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1479} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'{'} = sub { term9($_[1], $_[0], $_[2], $_[3]) }; ++# token term10+*term10 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 10470 10521+           (+      +             ## <group>+             ## pos: 10470 10493+              (   ( $pad{I1480} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 10470 10484+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->special_char( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'special_char'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1480} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10493 10521+              (   ( $pad{I1481} = $pos or 1 ) &&+               ## <closure>+               ## pos: 10493 10520+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return ${ $_[0]->{qw(special_char)} } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1481} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'\\'} = sub { term10($_[1], $_[0], $_[2], $_[3]) }; ++# token term11+*term11 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 10618 10677+            (   ( $pad{I1482} = $pos or 1 ) &&+             ## <closure>+             ## pos: 10618 10676+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { 'dot' => 1, _pos => [$_[0]->from - 1, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1482} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'.'} = sub { term11($_[1], $_[0], $_[2], $_[3]) }; ++# token term12+*term12 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 10773 10811+           (+      +             ## <group>+             ## pos: 10773 10780+              (   ( $pad{I1483} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 10773 10779+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1483} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10780 10791+              (   ( $pad{I1484} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 10780 10782+               ( ( substr( $s, $pos, 1 ) eq ']' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1484} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 10791 10811+              (   ( $pad{I1485} = $pos or 1 ) &&+               ## <closure>+               ## pos: 10791 10810+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return ${ $_[0]->{qw(rule)} } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1485} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'['} = sub { term12($_[1], $_[0], $_[2], $_[3]) }; ++# token term13+*term13 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 10899 10962+            (   ( $pad{I1486} = $pos or 1 ) &&+             ## <closure>+             ## pos: 10899 10961+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => ':::', _pos => [$_[0]->from - 3, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1486} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':::'} = sub { term13($_[1], $_[0], $_[2], $_[3]) }; ++# token term14+*term14 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11052 11114+            (   ( $pad{I1487} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11052 11113+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => ':?', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1487} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':?'} = sub { term14($_[1], $_[0], $_[2], $_[3]) }; ++# token term15+*term15 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11203 11265+            (   ( $pad{I1488} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11203 11264+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => ':+', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1488} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':+'} = sub { term15($_[1], $_[0], $_[2], $_[3]) }; ++# token term16+*term16 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11354 11416+            (   ( $pad{I1489} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11354 11415+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '::', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1489} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'::'} = sub { term16($_[1], $_[0], $_[2], $_[3]) }; ++# token term17+*term17 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11505 11566+            (   ( $pad{I1490} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11505 11565+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => ':', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1490} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':'} = sub { term17($_[1], $_[0], $_[2], $_[3]) }; ++# token term18+*term18 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11654 11716+            (   ( $pad{I1491} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11654 11715+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '$$', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1491} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'$$'} = sub { term18($_[1], $_[0], $_[2], $_[3]) }; ++# token term19+*term19 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11805 11867+            (   ( $pad{I1492} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11805 11866+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '$', _pos => [$_[0]->from - 1, $_[0]->to],  } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1492} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'$'} = sub { term19($_[1], $_[0], $_[2], $_[3]) }; ++# token term20+*term20 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 11955 12017+            (   ( $pad{I1493} = $pos or 1 ) &&+             ## <closure>+             ## pos: 11955 12016+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '^^', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1493} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'^^'} = sub { term20($_[1], $_[0], $_[2], $_[3]) }; ++# token term21+*term21 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 12106 12167+            (   ( $pad{I1494} = $pos or 1 ) &&+             ## <closure>+             ## pos: 12106 12166+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '^', _pos => [$_[0]->from - 1, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1494} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'^'} = sub { term21($_[1], $_[0], $_[2], $_[3]) }; ++# token term22+*term22 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 12255 12317+            (   ( $pad{I1495} = $pos or 1 ) &&+             ## <closure>+             ## pos: 12255 12316+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '>>', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1495} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'>>'} = sub { term22($_[1], $_[0], $_[2], $_[3]) }; ++# Code block from grammar spec+ $rule_terms{'»'} = sub { term22($_[1], $_[0], $_[2], $_[3]) }; ++# token term24+*term24 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+      +           ## <group>+           ## pos: 12559 12621+            (   ( $pad{I1496} = $pos or 1 ) &&+             ## <closure>+             ## pos: 12559 12620+             do {+               local $::_V6_SUCCEED = 1;+               $::_V6_MATCH_ = $m;+               $m->data->{capture} = \( sub { return { colon => '<<', _pos => [$_[0]->from - 2, $_[0]->to], } }->( $m ) ); +               $bool = $::_V6_SUCCEED;+               $::_V6_MATCH_ = $m if $bool; +               return $m if $bool; +             }+             ## </closure>+     ||    ( ( $pos = $pad{I1496} ) && 0 ) )+           ## </group>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{'<<'} = sub { term24($_[1], $_[0], $_[2], $_[3]) }; ++# Code block from grammar spec+ $rule_terms{'«'} = sub { term24($_[1], $_[0], $_[2], $_[3]) }; ++# token term26+*term26 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 12871 13048+           (+      +             ## <group>+             ## pos: 12871 12877+              (   ( $pad{I1497} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 12871 12876+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1497} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 12877 12892+              (   ( $pad{I1498} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 12877 12883+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1498} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 12892 13048+              (   ( $pad{I1499} = $pos or 1 ) &&+               ## <closure>+               ## pos: 12892 13047+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                modifier => {+                    modifier => 'ignorecase',+                    rule => ${ $_[0]->{qw(rule)} },+                    }+                },+            }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1499} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':i'} = sub { term26($_[1], $_[0], $_[2], $_[3]) }; ++# Code block from grammar spec+ $rule_terms{':ignorecase'} = sub { term26($_[1], $_[0], $_[2], $_[3]) }; ++# token term28+*term28 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 13328 13405+           (+      +             ## <group>+             ## pos: 13328 13334+              (   ( $pad{I1500} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 13328 13333+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1500} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 13334 13349+              (   ( $pad{I1501} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 13334 13340+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1501} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 13349 13405+              (   ( $pad{I1502} = $pos or 1 ) &&+               ## <closure>+               ## pos: 13349 13404+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'sigspace', rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1502} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':s'} = sub { term28($_[1], $_[0], $_[2], $_[3]) }; ++# Code block from grammar spec+ $rule_terms{':sigspace'} = sub { term28($_[1], $_[0], $_[2], $_[3]) }; ++# token term30+*term30 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 13684 13758+           (+      +             ## <group>+             ## pos: 13684 13690+              (   ( $pad{I1503} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 13684 13689+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1503} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 13690 13705+              (   ( $pad{I1504} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 13690 13696+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1504} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 13705 13758+              (   ( $pad{I1505} = $pos or 1 ) &&+               ## <closure>+               ## pos: 13705 13757+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'Perl5', rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1505} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':P5'} = sub { term30($_[1], $_[0], $_[2], $_[3]) }; ++# Code block from grammar spec+ $rule_terms{':Perl5'} = sub { term30($_[1], $_[0], $_[2], $_[3]) }; ++# token term32+*term32 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 14031 14105+           (+      +             ## <group>+             ## pos: 14031 14037+              (   ( $pad{I1506} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 14031 14036+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1506} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14037 14052+              (   ( $pad{I1507} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 14037 14043+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1507} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14052 14105+              (   ( $pad{I1508} = $pos or 1 ) &&+               ## <closure>+               ## pos: 14052 14104+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'bytes', rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1508} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':bytes'} = sub { term32($_[1], $_[0], $_[2], $_[3]) }; ++# token term33+*term33 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 14206 14280+           (+      +             ## <group>+             ## pos: 14206 14212+              (   ( $pad{I1509} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 14206 14211+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1509} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14212 14227+              (   ( $pad{I1510} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 14212 14218+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1510} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14227 14280+              (   ( $pad{I1511} = $pos or 1 ) &&+               ## <closure>+               ## pos: 14227 14279+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'codes', rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1511} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':codes'} = sub { term33($_[1], $_[0], $_[2], $_[3]) }; ++# token term34+*term34 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 14381 14456+           (+      +             ## <group>+             ## pos: 14381 14387+              (   ( $pad{I1512} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 14381 14386+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1512} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14387 14402+              (   ( $pad{I1513} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 14387 14393+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1513} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14402 14456+              (   ( $pad{I1514} = $pos or 1 ) &&+               ## <closure>+               ## pos: 14402 14455+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'graphs', rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1514} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':graphs'} = sub { term34($_[1], $_[0], $_[2], $_[3]) }; ++# token term35+*term35 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 14558 14633+           (+      +             ## <group>+             ## pos: 14558 14564+              (   ( $pad{I1515} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 14558 14563+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1515} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14564 14579+              (   ( $pad{I1516} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 14564 14570+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1516} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 14579 14633+              (   ( $pad{I1517} = $pos or 1 ) &&+               ## <closure>+               ## pos: 14579 14632+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { modifier => 'langs',  rule => ${ $_[0]->{qw(rule)} } } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1517} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# Code block from grammar spec+ $rule_terms{':langs'} = sub { term35($_[1], $_[0], $_[2], $_[3]) }; ++# token term+*term =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 14728 15530+           (+               ( $pad{I1518} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 14729 15207+               (+      +                 ## <group>+                 ## pos: 14729 14772+                  (   ( $pad{I1519} = $pos or 1 ) &&+                  ## <metasyntax>+                   ## pos: 14731 14764+                   do{+                    my $match = +              ## <variable>+              ## pos: 14731 14764+              do {+                our $I1520;+                our $I1520_sizes;+                unless ( $I1520 ) {+                    my $hash = \%Pugs::Grammar::Rule::variables;+                    my %sizes = map { length($_) => 1 } keys %$hash;+                    $I1520_sizes = [ sort { $b <=> $a } keys %sizes ];+                    $I1520 = $hash;+                }+                my $match = 0;+                my $key;+                for ( @$I1520_sizes ) {+                    $key = ( $pos <= length( $s )+                                ? substr( $s, $pos, $_ )+                                : '' );+                    if ( exists $I1520->{$key} ) {+                        #$named{KEY} = $key;+                        #$::_V6_MATCH_ = $m;+                        #print "m: ", Dumper( $::_V6_MATCH_->data )+                        #    if ( $key eq 'until' );+                        $match = Pugs::Runtime::Regex::preprocess_hash( $I1520, $key )->( $s, $grammar, { p => ( $pos + $_ ), positionals => [ ], args => { KEY => $key } }, undef );+                        last if $match;+                    }+                }+                if ( $match ) {+                    $pos = $match->to;+                    #print "match: $key at $pos = ", Dumper( $match->data );+                    $bool = 1;+                }; # else { $bool = 0 }+                $match;+              }+              ## </variable>+    ;+                    if ( $match ) { $named{'Pugs::Grammar::Rule::variables'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                  ## </metasyntax>+     ||    ( ( $pos = $pad{I1519} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 14772 15207+                  (   ( $pad{I1521} = $pos or 1 ) &&+                   ## <alt>+                   ## pos: 14773 15201+                   (+                       ( $pad{I1522} = $pos or 1 )+                       && (+                       ## <concat>+                       ## pos: 14773 15114+                       (+                         ## <quant>+                         ## pos: 14773 14782+                         (+                          (   ( $pad{I1523} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 14775 14780+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1523} ) && 0 ) )+                         || ( $bool = 1 )+                         )+                         ## </quant>+    +                       &&+      +                         ## <group>+                         ## pos: 14782 14787+                          (   ( $pad{I1524} = $pos or 1 ) &&+    +                           ## <constant>+                           ## pos: 14782 14786+                           ( ( substr( $s, $pos, 2 ) eq ':=' )+                               ? ( $pos += 2 or 1 )+                               : 0+                           )+                           ## </constant>+     ||    ( ( $pos = $pad{I1524} ) && 0 ) )+                         ## </group>+    +                       &&+                         ## <quant>+                         ## pos: 14787 14794+                         (+                          (   ( $pad{I1525} = $pos or 1 ) &&+                             ## <metasyntax>+                             ## pos: 14787 14792+                             do {+                                  my $prior = $::_V6_PRIOR_;+                                  my $match =+                                         $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                  $::_V6_PRIOR_ = $prior;+                                  my $bool = (!$match != 1);+                                  $pos = $match->to if $bool;+                                  $match;+                             }+                             ## </metasyntax>+     ||    ( ( $pos = $pad{I1525} ) && 0 ) )+                         || ( $bool = 1 )+                         )+                         ## </quant>+    +                       &&+      +                         ## <group>+                         ## pos: 14794 14825+                          (   ( $pad{I1526} = $pos or 1 ) &&+                           ## <named_capture>+                           ## pos: 14794 14814+                           do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                       $grammar->named_capture_body( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'named_capture_body'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                           ## </named_capture>+     ||    ( ( $pos = $pad{I1526} ) && 0 ) )+                         ## </group>+    +                       &&+      +                         ## <group>+                         ## pos: 14825 15114+                          (   ( $pad{I1527} = $pos or 1 ) &&+                           ## <closure>+                           ## pos: 14825 15106+                           do {+                             local $::_V6_SUCCEED = 1;+                             $::_V6_MATCH_ = $m;+                             $m->data->{capture} = \( sub {+                return { named_capture => {+                            rule =>  ${ $_[0]->{qw(named_capture_body)} },+                            ident => ${ $_[0]->{qw(Pugs::Grammar::Rule::variables)} },+                         },+                            _pos => [ $_[0]->from, $_[0]->to ],+                         };+              }->( $m ) ); +                             $bool = $::_V6_SUCCEED;+                             $::_V6_MATCH_ = $m if $bool; +                             return $m if $bool; +                           }+                           ## </closure>+     ||    ( ( $pos = $pad{I1527} ) && 0 ) )+                         ## </group>+    +                       )+                       ## </concat>+    +                       )+                     || (+                       ( ( $bool = 1 ) && ( $pos = $pad{I1522} ) or 1 )+                       &&   +                       ## <group>+                       ## pos: 15115 15201+                        (   ( $pad{I1528} = $pos or 1 ) &&+                         ## <closure>+                         ## pos: 15126 15193+                         do {+                           local $::_V6_SUCCEED = 1;+                           $::_V6_MATCH_ = $m;+                           $m->data->{capture} = \( sub {+                return ${ $_[0]->{qw(Pugs::Grammar::Rule::variables)} }+              }->( $m ) ); +                           $bool = $::_V6_SUCCEED;+                           $::_V6_MATCH_ = $m if $bool; +                           return $m if $bool; +                         }+                         ## </closure>+     ||    ( ( $pos = $pad{I1528} ) && 0 ) )+                       ## </group>+    +                     )+                   )+                   ## </alt>+     ||    ( ( $pos = $pad{I1521} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1518} ) or 1 )+               &&            ## <concat>+               ## pos: 15208 15376+               (+      +                 ## <group>+                 ## pos: 15208 15253+                  (   ( $pad{I1529} = $pos or 1 ) &&+                  ## <metasyntax>+                   ## pos: 15210 15244+                   do{+                    my $match = +              ## <variable>+              ## pos: 15210 15244+              do {+                our $I1530;+                our $I1530_sizes;+                unless ( $I1530 ) {+                    my $hash = \%Pugs::Grammar::Rule::rule_terms;+                    my %sizes = map { length($_) => 1 } keys %$hash;+                    $I1530_sizes = [ sort { $b <=> $a } keys %sizes ];+                    $I1530 = $hash;+                }+                my $match = 0;+                my $key;+                for ( @$I1530_sizes ) {+                    $key = ( $pos <= length( $s )+                                ? substr( $s, $pos, $_ )+                                : '' );+                    if ( exists $I1530->{$key} ) {+                        #$named{KEY} = $key;+                        #$::_V6_MATCH_ = $m;+                        #print "m: ", Dumper( $::_V6_MATCH_->data )+                        #    if ( $key eq 'until' );+                        $match = Pugs::Runtime::Regex::preprocess_hash( $I1530, $key )->( $s, $grammar, { p => ( $pos + $_ ), positionals => [ ], args => { KEY => $key } }, undef );+                        last if $match;+                    }+                }+                if ( $match ) {+                    $pos = $match->to;+                    #print "match: $key at $pos = ", Dumper( $match->data );+                    $bool = 1;+                }; # else { $bool = 0 }+                $match;+              }+              ## </variable>+    ;+                    if ( $match ) { $named{'Pugs::Grammar::Rule::rule_terms'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                  ## </metasyntax>+     ||    ( ( $pos = $pad{I1529} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 15253 15376+                  (   ( $pad{I1531} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 15253 15371+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub {+                #print "term: ", Dumper( $_[0]->data );+                return ${ $_[0]->{qw(Pugs::Grammar::Rule::rule_terms)} }+            }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1531} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1518} ) or 1 )+               &&            ## <concat>+               ## pos: 15377 15530+               (+      +                 ## <group>+                 ## pos: 15377 15424+                  (   ( $pad{I1532} = $pos or 1 ) &&+                   ## <perl5>+                   ( ( substr( $s, $pos ) =~ m/^((?:(?![\]\}\)\>\:\?\+\*\|\&]))\X)/ )+                       ? ( $pos += length( $1 ) or 1 )+                       : 0+                   )+                   ## </perl5>+     ||    ( ( $pos = $pad{I1532} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 15424 15530+                  (   ( $pad{I1533} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 15424 15529+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub {+                return { 'constant' => ${$_[0]},+                         _pos => [ $_[0]->from, $_[0]->to ] }+            }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1533} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token quant+*quant =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 15551 15665+           (+               ( $pad{I1534} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 15552 15643+               (+      +                 ## <group>+                 ## pos: 15552 15560+                  (   ( $pad{I1535} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 15555 15559+                   ( ( substr( $s, $pos, 2 ) eq '**' )+                       ? ( $pos += 2 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1535} ) && 0 ) )+                 ## </group>+    +               &&+                 ## <quant>+                 ## pos: 15560 15567+                 (+                  (   ( $pad{I1536} = $pos or 1 ) &&+                     ## <metasyntax>+                     ## pos: 15560 15565+                     do {+                          my $prior = $::_V6_PRIOR_;+                          my $match =+                                 $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                          $::_V6_PRIOR_ = $prior;+                          my $bool = (!$match != 1);+                          $pos = $match->to if $bool;+                          $match;+                     }+                     ## </metasyntax>+     ||    ( ( $pos = $pad{I1536} ) && 0 ) )+                 || ( $bool = 1 )+                 )+                 ## </quant>+    +               &&+      +                 ## <group>+                 ## pos: 15567 15571+                  (   ( $pad{I1537} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 15567 15569+                   ( ( substr( $s, $pos, 1 ) eq '{' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1537} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 15571 15586+                  (   ( $pad{I1538} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 15571 15584+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->parsed_code( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'parsed_code'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1538} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 15586 15597+                  (   ( $pad{I1539} = $pos or 1 ) &&+    +                   ## <constant>+                   ## pos: 15586 15588+                   ( ( substr( $s, $pos, 1 ) eq '}' )+                       ? ( $pos += 1 or 1 )+                       : 0+                   )+                   ## </constant>+     ||    ( ( $pos = $pad{I1539} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 15597 15643+                  (   ( $pad{I1540} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 15597 15638+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return { closure => ${ $_[0]->{qw(parsed_code)} } } }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1540} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1534} ) or 1 )+               &&            ## <quant>+               ## pos: 15644 15665+               (+                (   ( $pad{I1541} = $pos or 1 ) &&+                   ## <perl5>+                   ( ( substr( $s, $pos ) =~ m/^((?:(?=[\?\*\+]))\X)/ )+                       ? ( $pos += length( $1 ) or 1 )+                       : 0+                   )+                   ## </perl5>+     ||    ( ( $pos = $pad{I1541} ) && 0 ) )+               || ( $bool = 1 )+               )+               ## </quant>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token quantifier+*quantifier =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 15691 16457+           (+      +             ## <group>+             ## pos: 15691 15716+              (   ( $pad{I1542} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15691 15711+               do{+                    my $match = Pugs::Runtime::Match->new( do {+                        my $bool = 1;+                        my $from = $pos;+                        my @match;+                        my %named;+                        $bool = 0 unless +                       ## <capture>+                       do{+                           my $hash = do {+                             my $bool = 1;+                             my $from = $pos;+                             my @match;+                             my %named;+                             $bool = 0 unless+                               ## <quant>+                               ## pos: 15704 15710+                               (+                                (   ( $pad{I1543} = $pos or 1 ) &&+                                   ## <metasyntax>+                                   ## pos: 15704 15709+                                   do {+                                        my $prior = $::_V6_PRIOR_;+                                        my $match =+                                               $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                        $::_V6_PRIOR_ = $prior;+                                        my $bool = (!$match != 1);+                                        $pos = $match->to if $bool;+                                        $match;+                                   }+                                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1543} ) && 0 ) )+                               || ( $bool = 1 )+                               )+                               ## </quant>+    ;+                             { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                           };+                           my $bool = ${$hash->{'bool'}};+                           $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                           $bool;+                       }+                       ## </capture>+    ;+                        { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                    } );+                    if ( $match ) { $named{'ws1'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1542} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15716 15751+              (   ( $pad{I1544} = $pos or 1 ) &&+               ## <negate>+               ## pos: 15716 15746+               do{+                   my $pos1 = $pos;+                   do {+                     my $pos = $pos1;+                     my $from = $pos;+                     my @match;+                     my %named;+                     $bool = +                         ## <before>+                         ## pos: 15726 15745+                         do{+                             my $pos1 = $pos;+                             do {+                               my $pos = $pos1;+                               my $from = $pos;+                               my @match;+                               my %named;+                               $bool = 0 unless+      +                                   ## <group>+                                   ## pos: 15726 15745+                                    (   ( $pad{I1545} = $pos or 1 ) &&+                                     ## <perl5>+                                     ( ( substr( $s, $pos ) =~ m/^((?:(?=[\}\]\)]))\X)/ )+                                         ? ( $pos += length( $1 ) or 1 )+                                         : 0+                                     )+                                     ## </perl5>+     ||    ( ( $pos = $pad{I1545} ) && 0 ) )+                                   ## </group>+    ;+                               $bool;+                             };+                         }+                         ## </before>+     ? 0 : 1;+                     $bool;+                   };+               }+               ## </negate>+     ||    ( ( $pos = $pad{I1544} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15751 15762+              (   ( $pad{I1546} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15751 15757+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->term( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'term'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1546} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15762 15787+              (   ( $pad{I1547} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15762 15782+               do{+                    my $match = Pugs::Runtime::Match->new( do {+                        my $bool = 1;+                        my $from = $pos;+                        my @match;+                        my %named;+                        $bool = 0 unless +                       ## <capture>+                       do{+                           my $hash = do {+                             my $bool = 1;+                             my $from = $pos;+                             my @match;+                             my %named;+                             $bool = 0 unless+                               ## <quant>+                               ## pos: 15775 15781+                               (+                                (   ( $pad{I1548} = $pos or 1 ) &&+                                   ## <metasyntax>+                                   ## pos: 15775 15780+                                   do {+                                        my $prior = $::_V6_PRIOR_;+                                        my $match =+                                               $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                        $::_V6_PRIOR_ = $prior;+                                        my $bool = (!$match != 1);+                                        $pos = $match->to if $bool;+                                        $match;+                                   }+                                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1548} ) && 0 ) )+                               || ( $bool = 1 )+                               )+                               ## </quant>+    ;+                             { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                           };+                           my $bool = ${$hash->{'bool'}};+                           $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                           $bool;+                       }+                       ## </capture>+    ;+                        { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                    } );+                    if ( $match ) { $named{'ws2'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1547} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15787 15799+              (   ( $pad{I1549} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15787 15794+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->quant( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'quant'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1549} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15799 15833+              (   ( $pad{I1550} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15799 15828+               do{+                    my $match = Pugs::Runtime::Match->new( do {+                        my $bool = 1;+                        my $from = $pos;+                        my @match;+                        my %named;+                        $bool = 0 unless +                       ## <capture>+                       do{+                           my $hash = do {+                             my $bool = 1;+                             my $from = $pos;+                             my @match;+                             my %named;+                             $bool = 0 unless+                               ## <quant>+                               ## pos: 15813 15827+                               (+                                (   ( $pad{I1551} = $pos or 1 ) &&+                                   ## <perl5>+                                   ( ( substr( $s, $pos ) =~ m/^((?:(?=[\?\+]))\X)/ )+                                       ? ( $pos += length( $1 ) or 1 )+                                       : 0+                                   )+                                   ## </perl5>+     ||    ( ( $pos = $pad{I1551} ) && 0 ) )+                               || ( $bool = 1 )+                               )+                               ## </quant>+    ;+                             { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                           };+                           my $bool = ${$hash->{'bool'}};+                           $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                           $bool;+                       }+                       ## </capture>+    ;+                        { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                    } );+                    if ( $match ) { $named{'greedy'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1550} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15833 15858+              (   ( $pad{I1552} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 15833 15853+               do{+                    my $match = Pugs::Runtime::Match->new( do {+                        my $bool = 1;+                        my $from = $pos;+                        my @match;+                        my %named;+                        $bool = 0 unless +                       ## <capture>+                       do{+                           my $hash = do {+                             my $bool = 1;+                             my $from = $pos;+                             my @match;+                             my %named;+                             $bool = 0 unless+                               ## <quant>+                               ## pos: 15846 15852+                               (+                                (   ( $pad{I1553} = $pos or 1 ) &&+                                   ## <metasyntax>+                                   ## pos: 15846 15851+                                   do {+                                        my $prior = $::_V6_PRIOR_;+                                        my $match =+                                               $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                                        $::_V6_PRIOR_ = $prior;+                                        my $bool = (!$match != 1);+                                        $pos = $match->to if $bool;+                                        $match;+                                   }+                                   ## </metasyntax>+     ||    ( ( $pos = $pad{I1553} ) && 0 ) )+                               || ( $bool = 1 )+                               )+                               ## </quant>+    ;+                             { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                           };+                           my $bool = ${$hash->{'bool'}};+                           $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                           $bool;+                       }+                       ## </capture>+    ;+                        { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                    } );+                    if ( $match ) { $named{'ws3'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1552} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 15858 16457+              (   ( $pad{I1554} = $pos or 1 ) &&+               ## <closure>+               ## pos: 15858 16456+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+          if (+                   ${$_[0]->{'quant'}}  eq ''+                && ${$_[0]->{'greedy'}} eq ''+                && ${$_[0]->{'ws1'}}    eq ''+                && ${$_[0]->{'ws2'}}    eq ''+                && ${$_[0]->{'ws3'}}    eq ''+          ) {+              return ${$_[0]->{'term'}};+          }+          return {+            quant => {+                    term    => ${$_[0]->{'term'}},+                    quant   => ${$_[0]->{'quant'}},+                    greedy  => ${$_[0]->{'greedy'}},+                    ws1     => ${$_[0]->{'ws1'}},+                    ws2     => ${$_[0]->{'ws2'}},+                    ws3     => ${$_[0]->{'ws3'}},+                },+            _pos => [$_[0]->from, $_[0]->to],+          }+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1554} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token concat+*concat =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 16479 16688+           (+             ## <quant>+             ## pos: 16479 16497+             (+              (   ( $pad{I1555} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 16479 16491+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->quantifier( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'quantifier'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1555} ) && 0 ) )+             && do { while (+              (   ( $pad{I1555} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 16479 16491+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->quantifier( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'quantifier'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1555} ) && 0 ) )) {}; $bool = 1 }+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 16497 16688+              (   ( $pad{I1556} = $pos or 1 ) &&+               ## <closure>+               ## pos: 16497 16687+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+            my @a = map {  $_->()  }  @{ $::_V6_MATCH_->{'quantifier'} };+            return { concat => \@a, _pos => [$_[0]->from, $_[0]->to] }+                if scalar @a > 1;+            return $a[0];+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1556} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token conjunctive1+*conjunctive1 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 16716 16996+           (+             ## <quant>+             ## pos: 16716 16750+             (+              (   ( $pad{I1557} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 16717 16742+                 (+                   ## <quant>+                   ## pos: 16717 16725+                   (+                    (   ( $pad{I1558} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 16718 16723+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1558} ) && 0 ) )+                   || ( $bool = 1 )+                   )+                   ## </quant>+    +                 &&+      +                   ## <group>+                   ## pos: 16725 16728+                    (   ( $pad{I1559} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 16725 16727+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1559} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 16728 16742+                    (   ( $pad{I1560} = $pos or 1 ) &&+                     ## <negate>+                     ## pos: 16728 16741+                     do{+                         my $pos1 = $pos;+                         do {+                           my $pos = $pos1;+                           my $from = $pos;+                           my @match;+                           my %named;+                           $bool = +                               ## <before>+                               ## pos: 16737 16740+                               do{+                                   my $pos1 = $pos;+                                   do {+                                     my $pos = $pos1;+                                     my $from = $pos;+                                     my @match;+                                     my %named;+                                     $bool = 0 unless+      +                                         ## <group>+                                         ## pos: 16737 16740+                                          (   ( $pad{I1561} = $pos or 1 ) &&+    +                                           ## <constant>+                                           ## pos: 16737 16739+                                           ( ( substr( $s, $pos, 1 ) eq '&' )+                                               ? ( $pos += 1 or 1 )+                                               : 0+                                           )+                                           ## </constant>+     ||    ( ( $pos = $pad{I1561} ) && 0 ) )+                                         ## </group>+    ;+                                     $bool;+                                   };+                               }+                               ## </before>+     ? 0 : 1;+                           $bool;+                         };+                     }+                     ## </negate>+     ||    ( ( $pos = $pad{I1560} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1557} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 16750 16768+             (+              (   ( $pad{I1562} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 16750 16758+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->concat( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'concat'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1562} ) && 0 ) )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 16768 16817+             do { while (+              (   ( $pad{I1563} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 16769 16809+                 (+      +                   ## <group>+                   ## pos: 16769 16781+                    (   ( $pad{I1564} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 16778 16780+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1564} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 16781 16796+                    (   ( $pad{I1565} = $pos or 1 ) &&+                     ## <negate>+                     ## pos: 16781 16794+                     do{+                         my $pos1 = $pos;+                         do {+                           my $pos = $pos1;+                           my $from = $pos;+                           my @match;+                           my %named;+                           $bool = +                               ## <before>+                               ## pos: 16790 16793+                               do{+                                   my $pos1 = $pos;+                                   do {+                                     my $pos = $pos1;+                                     my $from = $pos;+                                     my @match;+                                     my %named;+                                     $bool = 0 unless+      +                                         ## <group>+                                         ## pos: 16790 16793+                                          (   ( $pad{I1566} = $pos or 1 ) &&+    +                                           ## <constant>+                                           ## pos: 16790 16792+                                           ( ( substr( $s, $pos, 1 ) eq '&' )+                                               ? ( $pos += 1 or 1 )+                                               : 0+                                           )+                                           ## </constant>+     ||    ( ( $pos = $pad{I1566} ) && 0 ) )+                                         ## </group>+    ;+                                     $bool;+                                   };+                               }+                               ## </before>+     ? 0 : 1;+                           $bool;+                         };+                     }+                     ## </negate>+     ||    ( ( $pos = $pad{I1565} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 16796 16809+                    (   ( $pad{I1567} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 16796 16804+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->concat( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'concat'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1567} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1563} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 16817 16996+              (   ( $pad{I1568} = $pos or 1 ) &&+               ## <closure>+               ## pos: 16817 16995+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+            my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'concat'} };+            return { conjunctive1 => \@a, _pos => [$_[0]->from, $_[0]->to] }  if scalar @a > 1;+            return $a[0];+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1568} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token disjunctive1+*disjunctive1 =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 17024 17313+           (+             ## <quant>+             ## pos: 17024 17058+             (+              (   ( $pad{I1569} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17025 17050+                 (+                   ## <quant>+                   ## pos: 17025 17033+                   (+                    (   ( $pad{I1570} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 17026 17031+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1570} ) && 0 ) )+                   || ( $bool = 1 )+                   )+                   ## </quant>+    +                 &&+      +                   ## <group>+                   ## pos: 17033 17036+                    (   ( $pad{I1571} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17033 17035+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1571} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17036 17050+                    (   ( $pad{I1572} = $pos or 1 ) &&+                     ## <negate>+                     ## pos: 17036 17049+                     do{+                         my $pos1 = $pos;+                         do {+                           my $pos = $pos1;+                           my $from = $pos;+                           my @match;+                           my %named;+                           $bool = +                               ## <before>+                               ## pos: 17045 17048+                               do{+                                   my $pos1 = $pos;+                                   do {+                                     my $pos = $pos1;+                                     my $from = $pos;+                                     my @match;+                                     my %named;+                                     $bool = 0 unless+      +                                         ## <group>+                                         ## pos: 17045 17048+                                          (   ( $pad{I1573} = $pos or 1 ) &&+    +                                           ## <constant>+                                           ## pos: 17045 17047+                                           ( ( substr( $s, $pos, 1 ) eq '|' )+                                               ? ( $pos += 1 or 1 )+                                               : 0+                                           )+                                           ## </constant>+     ||    ( ( $pos = $pad{I1573} ) && 0 ) )+                                         ## </group>+    ;+                                     $bool;+                                   };+                               }+                               ## </before>+     ? 0 : 1;+                           $bool;+                         };+                     }+                     ## </negate>+     ||    ( ( $pos = $pad{I1572} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1569} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17058 17082+             (+              (   ( $pad{I1574} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 17058 17072+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->conjunctive1( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'conjunctive1'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1574} ) && 0 ) )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17082 17136+             do { while (+              (   ( $pad{I1575} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17083 17128+                 (+      +                   ## <group>+                   ## pos: 17083 17095+                    (   ( $pad{I1576} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17092 17094+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1576} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17095 17109+                    (   ( $pad{I1577} = $pos or 1 ) &&+                     ## <negate>+                     ## pos: 17095 17108+                     do{+                         my $pos1 = $pos;+                         do {+                           my $pos = $pos1;+                           my $from = $pos;+                           my @match;+                           my %named;+                           $bool = +                               ## <before>+                               ## pos: 17104 17107+                               do{+                                   my $pos1 = $pos;+                                   do {+                                     my $pos = $pos1;+                                     my $from = $pos;+                                     my @match;+                                     my %named;+                                     $bool = 0 unless+      +                                         ## <group>+                                         ## pos: 17104 17107+                                          (   ( $pad{I1578} = $pos or 1 ) &&+    +                                           ## <constant>+                                           ## pos: 17104 17106+                                           ( ( substr( $s, $pos, 1 ) eq '|' )+                                               ? ( $pos += 1 or 1 )+                                               : 0+                                           )+                                           ## </constant>+     ||    ( ( $pos = $pad{I1578} ) && 0 ) )+                                         ## </group>+    ;+                                     $bool;+                                   };+                               }+                               ## </before>+     ? 0 : 1;+                           $bool;+                         };+                     }+                     ## </negate>+     ||    ( ( $pos = $pad{I1577} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17109 17128+                    (   ( $pad{I1579} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 17109 17123+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->conjunctive1( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'conjunctive1'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1579} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1575} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 17136 17313+              (   ( $pad{I1580} = $pos or 1 ) &&+               ## <closure>+               ## pos: 17136 17312+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+            my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'conjunctive1'} };+            return { alt1 => \@a, _pos => [$_[0]->from, $_[0]->to] }  if scalar @a > 1;+            return $a[0];+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1580} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token conjunctive+*conjunctive =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 17340 17614+           (+             ## <quant>+             ## pos: 17340 17363+             (+              (   ( $pad{I1581} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17341 17355+                 (+                   ## <quant>+                   ## pos: 17341 17349+                   (+                    (   ( $pad{I1582} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 17342 17347+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1582} ) && 0 ) )+                   || ( $bool = 1 )+                   )+                   ## </quant>+    +                 &&+      +                   ## <group>+                   ## pos: 17349 17352+                    (   ( $pad{I1583} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17349 17351+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1583} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17352 17355+                    (   ( $pad{I1584} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17352 17354+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1584} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1581} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17363 17387+             (+              (   ( $pad{I1585} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 17363 17377+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->disjunctive1( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'disjunctive1'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1585} ) && 0 ) )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17387 17430+             do { while (+              (   ( $pad{I1586} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17388 17422+                 (+      +                   ## <group>+                   ## pos: 17388 17400+                    (   ( $pad{I1587} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17397 17399+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1587} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17400 17403+                    (   ( $pad{I1588} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17400 17402+                     ( ( substr( $s, $pos, 1 ) eq '&' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1588} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17403 17422+                    (   ( $pad{I1589} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 17403 17417+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->disjunctive1( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'disjunctive1'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1589} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1586} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 17430 17614+              (   ( $pad{I1590} = $pos or 1 ) &&+               ## <closure>+               ## pos: 17430 17613+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+            my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'disjunctive1'} };+            return { conjunctive => \@a, _pos => [$_[0]->from, $_[0]->to] }  if scalar @a > 1;+            return $a[0];+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1590} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token rule+*rule =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 17634 17898+           (+             ## <quant>+             ## pos: 17634 17657+             (+              (   ( $pad{I1591} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17635 17649+                 (+                   ## <quant>+                   ## pos: 17635 17643+                   (+                    (   ( $pad{I1592} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 17636 17641+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1592} ) && 0 ) )+                   || ( $bool = 1 )+                   )+                   ## </quant>+    +                 &&+      +                   ## <group>+                   ## pos: 17643 17646+                    (   ( $pad{I1593} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17643 17645+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1593} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17646 17649+                    (   ( $pad{I1594} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17646 17648+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1594} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1591} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17657 17680+             (+              (   ( $pad{I1595} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 17657 17670+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->conjunctive( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'conjunctive'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1595} ) && 0 ) )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 17680 17722+             do { while (+              (   ( $pad{I1596} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 17681 17714+                 (+      +                   ## <group>+                   ## pos: 17681 17693+                    (   ( $pad{I1597} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17690 17692+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1597} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17693 17696+                    (   ( $pad{I1598} = $pos or 1 ) &&+    +                     ## <constant>+                     ## pos: 17693 17695+                     ( ( substr( $s, $pos, 1 ) eq '|' )+                         ? ( $pos += 1 or 1 )+                         : 0+                     )+                     ## </constant>+     ||    ( ( $pos = $pad{I1598} ) && 0 ) )+                   ## </group>+    +                 &&+      +                   ## <group>+                   ## pos: 17696 17714+                    (   ( $pad{I1599} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 17696 17709+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->conjunctive( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'conjunctive'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1599} ) && 0 ) )+                   ## </group>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1596} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 17722 17898+              (   ( $pad{I1600} = $pos or 1 ) &&+               ## <closure>+               ## pos: 17722 17897+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub {+            my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'conjunctive'} };+            return { alt => \@a, _pos => [$_[0]->from, $_[0]->to], }  if scalar @a > 1;+            return $a[0];+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1600} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token named_regex+*named_regex =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 17925 18145+           (+      +             ## <group>+             ## pos: 17925 17960+              (   ( $pad{I1601} = $pos or 1 ) &&+    +               ## <capture>+               do{+                   my $hash = do {+                     my $bool = 1;+                     my $from = $pos;+                     my @match;+                     my %named;+                     $bool = 0 unless+                       ## <alt>+                       ## pos: 17926 17954+                       (+                           ( $pad{I1602} = $pos or 1 )+                           && (+      +                           ## <group>+                           ## pos: 17926 17935+                            (   ( $pad{I1603} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 17927 17934+                             ( ( substr( $s, $pos, 5 ) eq 'token' )+                                 ? ( $pos += 5 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1603} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1602} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 17936 17945+                            (   ( $pad{I1604} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 17937 17944+                             ( ( substr( $s, $pos, 5 ) eq 'regex' )+                                 ? ( $pos += 5 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1604} ) && 0 ) )+                           ## </group>+    +                           )+                         || (+                           ( ( $bool = 1 ) && ( $pos = $pad{I1602} ) or 1 )+                           &&   +                           ## <group>+                           ## pos: 17946 17954+                            (   ( $pad{I1605} = $pos or 1 ) &&+    +                             ## <constant>+                             ## pos: 17947 17953+                             ( ( substr( $s, $pos, 4 ) eq 'rule' )+                                 ? ( $pos += 4 or 1 )+                                 : 0+                             )+                             ## </constant>+     ||    ( ( $pos = $pad{I1605} ) && 0 ) )+                           ## </group>+    +                         )+                       )+                       ## </alt>+    ;+                     { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                   };+                   my $bool = ${$hash->{'bool'}};+                   $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                   $bool;+               }+               ## </capture>+     ||    ( ( $pos = $pad{I1601} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 17960 17966+              (   ( $pad{I1606} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 17960 17965+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1606} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 17966 17974+              (   ( $pad{I1607} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 17966 17973+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ident( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'ident'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1607} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 17974 17981+             (+              (   ( $pad{I1608} = $pos or 1 ) &&+                 ## <metasyntax>+                 ## pos: 17974 17979+                 do {+                      my $prior = $::_V6_PRIOR_;+                      my $match =+                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                      $::_V6_PRIOR_ = $prior;+                      my $bool = (!$match != 1);+                      $pos = $match->to if $bool;+                      $match;+                 }+                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1608} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 17981 17993+              (   ( $pad{I1609} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 17981 17984+               ( ( substr( $s, $pos, 1 ) eq '{' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1609} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 17993 18008+             (+              (   ( $pad{I1610} = $pos or 1 ) &&+                 ## <metasyntax>+                 ## pos: 17993 17998+                 do {+                      my $prior = $::_V6_PRIOR_;+                      my $match =+                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                      $::_V6_PRIOR_ = $prior;+                      my $bool = (!$match != 1);+                      $pos = $match->to if $bool;+                      $match;+                 }+                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1610} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18008 18019+              (   ( $pad{I1611} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 18008 18014+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->rule( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'rule'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1611} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18019 18023+              (   ( $pad{I1612} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 18019 18022+               ( ( substr( $s, $pos, 1 ) eq '}' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1612} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 18023 18033+             (+              (   ( $pad{I1613} = $pos or 1 ) &&+    +                 ## <constant>+                 ## pos: 18023 18026+                 ( ( substr( $s, $pos, 1 ) eq ';' )+                     ? ( $pos += 1 or 1 )+                     : 0+                 )+                 ## </constant>+     ||    ( ( $pos = $pad{I1613} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18033 18145+              (   ( $pad{I1614} = $pos or 1 ) &&+               ## <closure>+               ## pos: 18033 18144+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                type => ${ $_[0]->[0] },+                name => ${ $_[0]->{qw(ident)} },+                ast => ${ $_[0]->{qw(rule)} }+            };+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1614} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token verbatim+*verbatim =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 18207 18329+           (+      +             ## <group>+             ## pos: 18207 18212+              (   ( $pad{I1615} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 18207 18211+               ( ( substr( $s, $pos, 2 ) eq '%{' )+                   ? ( $pos += 2 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1615} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18212 18238+              (   ( $pad{I1616} = $pos or 1 ) &&+    +               ## <capture>+               do{+                   my $hash = do {+                     my $bool = 1;+                     my $from = $pos;+                     my @match;+                     my %named;+                     $bool = 0 unless+                       ## <quant>+                       ## pos: 18213 18236+                       do { while (+                        (   ( $pad{I1617} = $pos or 1 ) &&+                           ## <concat>+                           ## pos: 18215 18233+                           (+      +                             ## <group>+                             ## pos: 18215 18231+                              (   ( $pad{I1618} = $pos or 1 ) &&+                               ## <negate>+                               ## pos: 18216 18230+                               do{+                                   my $pos1 = $pos;+                                   do {+                                     my $pos = $pos1;+                                     my $from = $pos;+                                     my @match;+                                     my %named;+                                     $bool = +                                         ## <before>+                                         ## pos: 18225 18229+                                         do{+                                             my $pos1 = $pos;+                                             do {+                                               my $pos = $pos1;+                                               my $from = $pos;+                                               my @match;+                                               my %named;+                                               $bool = 0 unless+    +                                                   ## <constant>+                                                   ## pos: 18225 18229+                                                   ( ( substr( $s, $pos, 2 ) eq '%}' )+                                                       ? ( $pos += 2 or 1 )+                                                       : 0+                                                   )+                                                   ## </constant>+    ;+                                               $bool;+                                             };+                                         }+                                         ## </before>+     ? 0 : 1;+                                     $bool;+                                   };+                               }+                               ## </negate>+     ||    ( ( $pos = $pad{I1618} ) && 0 ) )+                             ## </group>+    +                           &&+      +                             ## <group>+                             ## pos: 18231 18233+                              (   ( $pad{I1619} = $pos or 1 ) &&+    +                               ## <dot>+                               ## pos: 18231 18232+                               ( substr( $s, $pos++, 1 ) ne '' )+                               ## </dot>+     ||    ( ( $pos = $pad{I1619} ) && 0 ) )+                             ## </group>+    +                           )+                           ## </concat>+     ||    ( ( $pos = $pad{I1617} ) && 0 ) )) {}; $bool = 1 }+                       ## </quant>+    ;+                     { str => \$s, from => \$from, match => \@match, named => \%named, bool => \$bool, to => \(0+$pos), capture => undef }+                   };+                   my $bool = ${$hash->{'bool'}};+                   $match[ 0 ] = Pugs::Runtime::Match->new( $hash );+                   $bool;+               }+               ## </capture>+     ||    ( ( $pos = $pad{I1616} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18238 18247+              (   ( $pad{I1620} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 18238 18242+               ( ( substr( $s, $pos, 2 ) eq '%}' )+                   ? ( $pos += 2 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1620} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18247 18329+              (   ( $pad{I1621} = $pos or 1 ) &&+               ## <closure>+               ## pos: 18247 18328+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                type => 'block',+                value => ${ $_[0]->[0] }+            };+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1621} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token item+*item =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <alt>+           ## pos: 18349 18441+           (+               ( $pad{I1622} = $pos or 1 )+               && (+               ## <concat>+               ## pos: 18350 18397+               (+      +                 ## <group>+                 ## pos: 18350 18368+                  (   ( $pad{I1623} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 18351 18361+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->verbatim( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'verbatim'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1623} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 18368 18397+                  (   ( $pad{I1624} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 18368 18392+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return ${ $_[0]->{qw(verbatim)} }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1624} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +               )+             || (+               ( ( $bool = 1 ) && ( $pos = $pad{I1622} ) or 1 )+               &&            ## <concat>+               ## pos: 18398 18441+               (+      +                 ## <group>+                 ## pos: 18398 18413+                  (   ( $pad{I1625} = $pos or 1 ) &&+                   ## <named_capture>+                   ## pos: 18399 18412+                   do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                               $grammar->named_regex( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'named_regex'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                   ## </named_capture>+     ||    ( ( $pos = $pad{I1625} ) && 0 ) )+                 ## </group>+    +               &&+      +                 ## <group>+                 ## pos: 18413 18441+                  (   ( $pad{I1626} = $pos or 1 ) &&+                   ## <closure>+                   ## pos: 18413 18440+                   do {+                     local $::_V6_SUCCEED = 1;+                     $::_V6_MATCH_ = $m;+                     $m->data->{capture} = \( sub { return ${ $_[0]->{qw(named_regex)} }; }->( $m ) ); +                     $bool = $::_V6_SUCCEED;+                     $::_V6_MATCH_ = $m if $bool; +                     return $m if $bool; +                   }+                   ## </closure>+     ||    ( ( $pos = $pad{I1626} ) && 0 ) )+                 ## </group>+    +               )+               ## </concat>+    +             )+           )+           ## </alt>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token grammar+*grammar =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 18464 18580+           (+             ## <quant>+             ## pos: 18464 18471+             (+              (   ( $pad{I1627} = $pos or 1 ) &&+                 ## <metasyntax>+                 ## pos: 18464 18469+                 do {+                      my $prior = $::_V6_PRIOR_;+                      my $match =+                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                      $::_V6_PRIOR_ = $prior;+                      my $bool = (!$match != 1);+                      $pos = $match->to if $bool;+                      $match;+                 }+                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1627} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18471 18481+              (   ( $pad{I1628} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 18471 18480+               ( ( substr( $s, $pos, 7 ) eq 'grammar' )+                   ? ( $pos += 7 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1628} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18481 18487+              (   ( $pad{I1629} = $pos or 1 ) &&+               ## <metasyntax>+               ## pos: 18481 18486+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    my $bool = (!$match != 1);+                    $pos = $match->to if $bool;+                    $match;+               }+               ## </metasyntax>+     ||    ( ( $pos = $pad{I1629} ) && 0 ) )+             ## </group>+    +           &&+      +             ## <group>+             ## pos: 18487 18495+              (   ( $pad{I1630} = $pos or 1 ) &&+               ## <named_capture>+               ## pos: 18487 18494+               do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                           $grammar->ident( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { $named{'ident'} = $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+               ## </named_capture>+     ||    ( ( $pos = $pad{I1630} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 18495 18502+             (+              (   ( $pad{I1631} = $pos or 1 ) &&+                 ## <metasyntax>+                 ## pos: 18495 18500+                 do {+                      my $prior = $::_V6_PRIOR_;+                      my $match =+                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                      $::_V6_PRIOR_ = $prior;+                      my $bool = (!$match != 1);+                      $pos = $match->to if $bool;+                      $match;+                 }+                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1631} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18502 18510+              (   ( $pad{I1632} = $pos or 1 ) &&+    +               ## <constant>+               ## pos: 18502 18505+               ( ( substr( $s, $pos, 1 ) eq ';' )+                   ? ( $pos += 1 or 1 )+                   : 0+               )+               ## </constant>+     ||    ( ( $pos = $pad{I1632} ) && 0 ) )+             ## </group>+    +           &&+             ## <quant>+             ## pos: 18510 18521+             (+              (   ( $pad{I1633} = $pos or 1 ) &&+                 ## <metasyntax>+                 ## pos: 18510 18515+                 do {+                      my $prior = $::_V6_PRIOR_;+                      my $match =+                             $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                      $::_V6_PRIOR_ = $prior;+                      my $bool = (!$match != 1);+                      $pos = $match->to if $bool;+                      $match;+                 }+                 ## </metasyntax>+     ||    ( ( $pos = $pad{I1633} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 18521 18544+             do { while (+              (   ( $pad{I1634} = $pos or 1 ) &&+                 ## <concat>+                 ## pos: 18522 18537+                 (+      +                   ## <group>+                   ## pos: 18522 18530+                    (   ( $pad{I1635} = $pos or 1 ) &&+                     ## <named_capture>+                     ## pos: 18523 18529+                     do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                                 $grammar->item( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'item'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                     ## </named_capture>+     ||    ( ( $pos = $pad{I1635} ) && 0 ) )+                   ## </group>+    +                 &&+                   ## <quant>+                   ## pos: 18530 18537+                   (+                    (   ( $pad{I1636} = $pos or 1 ) &&+                       ## <metasyntax>+                       ## pos: 18530 18535+                       do {+                            my $prior = $::_V6_PRIOR_;+                            my $match =+                                   $grammar->ws( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                            $::_V6_PRIOR_ = $prior;+                            my $bool = (!$match != 1);+                            $pos = $match->to if $bool;+                            $match;+                       }+                       ## </metasyntax>+     ||    ( ( $pos = $pad{I1636} ) && 0 ) )+                   || ( $bool = 1 )+                   )+                   ## </quant>+    +                 )+                 ## </concat>+     ||    ( ( $pos = $pad{I1634} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18544 18580+              (   ( $pad{I1637} = $pos or 1 ) &&+               ## <closure>+               ## pos: 18544 18579+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return { ${ $_[0]->{qw(ident)} } => $_[0]->{qw(item)} } }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1637} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++# token spec+*spec =+    ## <global>+    ## sigspace: 0+    ## ratchet: 1+    do { my $rule; $rule = sub {+      my $grammar = $_[0];+      my $s = $_[1];+      $_[3] = $_[2] unless defined $_[3]; # backwards compat+      no warnings 'substr', 'uninitialized', 'syntax';+      my %pad;+      my $m;+      my $bool;+      my @pos;+      # XXX :pos(X) takes the precedence over :continue ?+      if (defined $_[3]{p}) {+        push @pos, $_[3]{p} || 0;+      } elsif ($_[3]{continue}) {+        push @pos, (pos($_[1]) || 0) .. length($s);+      } else {+        push @pos, 0..length($s);+      }+      for my $pos ( @pos ) {+        my %index;+        my @match;+        my %named;+        $bool = 1;+        $named{KEY} = $_[3]{KEY} if exists $_[3]{KEY};+        $m = Pugs::Runtime::Match->new( {+          str => \$s, from => \(0+$pos), to => \($pos),+          bool => \$bool, match => \@match, named => \%named, capture => undef,+        } );+        {+          my $prior = $::_V6_PRIOR_;+          local $::_V6_PRIOR_ = $prior;+          $bool = 0 unless+           ## <concat>+           ## pos: 18600 18720+           (+             ## <quant>+             ## pos: 18600 18616+             (+              (   ( $pad{I1638} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 18600 18610+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->verbatim( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'verbatim'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1638} ) && 0 ) )+             || ( $bool = 1 )+             )+             ## </quant>+    +           &&+             ## <quant>+             ## pos: 18616 18631+             do { while (+              (   ( $pad{I1639} = $pos or 1 ) &&+                 ## <named_capture>+                 ## pos: 18616 18625+                 do {+                    my $prior = $::_V6_PRIOR_;+                    my $match =+                             $grammar->grammar( $s, { p => $pos, positionals => [  ], args => {}, }, undef );+                    $::_V6_PRIOR_ = $prior;+                    if ( $match ) { push @{$named{'grammar'}}, $match;+                        $pos = $match->to;+                        1+                    }+                    else { 0 }+                }+                 ## </named_capture>+     ||    ( ( $pos = $pad{I1639} ) && 0 ) )) {}; $bool = 1 }+             ## </quant>+    +           &&+      +             ## <group>+             ## pos: 18631 18720+              (   ( $pad{I1640} = $pos or 1 ) &&+               ## <closure>+               ## pos: 18631 18719+               do {+                 local $::_V6_SUCCEED = 1;+                 $::_V6_MATCH_ = $m;+                 $m->data->{capture} = \( sub { return {+                block => $_[0]->{qw(verbatim)},+                'grammar' => $_[0]->{qw(grammar)} }+        }->( $m ) ); +                 $bool = $::_V6_SUCCEED;+                 $::_V6_MATCH_ = $m if $bool; +                 return $m if $bool; +               }+               ## </closure>+     ||    ( ( $pos = $pad{I1640} ) && 0 ) )+             ## </group>+    +           )+           ## </concat>+    ;+        }+        if ( $bool ) {+          my $prior = $::_V6_PRIOR_;+          $::_V6_PRIOR_ = sub {+            local $main::_V6_PRIOR_ = $prior;+            $rule->(@_);+          };+          #warn "pos2 = ", $pos, "\n";+          pos($_[1]) = $pos if $_[3]{continue};+          last;+        }+      } # /for+      $::_V6_MATCH_ = $m;+      return $m;+    } }+    ## </global>+;++++1;
+ blib6/pugs/perl5/lib/Pugs/Grammar/Rule2.pm view
@@ -0,0 +1,608 @@+# WARNING: This file is no longer used by PCR itself;+# we're using examples/Grammar.grammar to generate Pugs::Grammar::Rule.pmc+# instead.++use v6-alpha;+use utf8;++# Perl6 implementation of the 'Rule' syntax+# author: Flavio S. Glock - fglock@gmail.com++=for compiling++    The util/update-rule-pmc script is used to+    generate lib/Pugs/Grammar/Rule.pmc from+    this file.++    This script does the following:++    Use v6.pm to compile this file and+    post-process it after compiling:+    - remove all references to:+        Data::Bind+    - replace the header with:+        package Pugs::Grammar::Rule;+        use utf8;+        no strict 'refs';+        use Pugs::Runtime::Match;+        use Pugs::Runtime::Regex;+    The post-processing thing is done+    by the Perl 5 script util/patch-rule-pmc.pl++=cut++grammar Pugs::Grammar::Rule;++#use Pugs::Runtime::Match;++our %rule_terms;+our %variables;++token pod_begin {+    |   \n =end \N*+    |   . \N* <.pod_begin>+}++token pod_other {+    |   \n =cut \N*+    |   . \N* <.pod_other>+}++token ws {+    [+    |    \# \N*+    |    \n [ = [+            |  begin <.ws> END \N* .*+            |  begin  <.pod_begin>+            |  kwid   <.pod_other>+            |  pod    <.pod_other>+            |  for    <.pod_other>+            |  head1  <.pod_other>+            ]?+            ]?+    |    \s+    ]++}++# regex ident can start with a number+token ident {+    [ <.alnum> | _ | '::' ]++}++token alnum {+    <[0-9a-zA-Z]>+}++token alpha {+    <[a-zA-Z]>+}++token digit {+    <[0-9]>+}++# after '\\'+token special_char {+        | ( c | C ) \[ ( [<alnum>|\s| ';' | '(' | ')' | '-' ]+) \]+          #  \c[LATIN LETTER A]+          { return { special_char => '\\' ~ $0 ~ $1 , } }++        | [ x | X ] <xdigit>++          #  \x0021    \X0021+          { return { special_char => '\\' ~ $/ , } }+        | ( x | X ) \[ (<xdigit>+) \]+          #  \x[0021]  \X[0021]+          { return { special_char => '\\' ~ $0 ~ $1 , } }++        | [ o | O ] \d++          #  \o0021    \O0021+          { return { special_char => '\\' ~ $/ , } }+        | ( o | O ) \[ (\d+) \]+          #  \o[0021]  \O[0021]+          { return { special_char => '\\' ~ $0 ~ $1 , } }++        | .+          #  \e  \E+          { return { special_char => '\\' ~ $/ , } }+}++token literal {+    [+    |  \\ <special_char>+    |  <-[ \' ]>+    ]*+}++token double_quoted {+    [+    |  \\ <special_char>+    |  <%Pugs::Grammar::Rule::variables>+    |  <-[ \" ]>+    ]*+}++token metasyntax {+    [+    |  \\ <special_char>+    |  \'  <.literal>     \'+    |  \"  <.double_quoted>   \"+    |  \{  <.string_code>        \}+    |  \<  <.metasyntax>  \>+    |  <-[ \> ]>+    ]++}++token char_range {+    [+    |  \\ <special_char>+    |  <-[ \] ]>+    ]++}++token char_class {+    |  <.alpha>++    |  \[  <.char_range>  \]+}++token string_code {+    # bootstrap "code"+    [+    |  \\ <special_char>+    |  \'  <.literal>     \'+    |  \"  <.double_quoted>   \"+    |  \{  [ <.string_code> | '' ]  \}+    |  \(  [ <.string_code> | '' ]  \)+    |  \<  [ <.string_code> | '' ]  \>+    |  [ <.ws> | \> | \= | \- ] \>+    |  <.ws>+    |  <-[ \} \) \> ]>+    ]++}++token parsed_code {+    # this subrule is overridden inside the perl6 compiler+    <.string_code>+    { return '{' ~ $/ ~ '}' }+}++token named_capture_body {+    | \(  <rule>        \)  { return { capturing_group => $$<rule> ,} }+    | \[  <rule>        \]  { return $$<rule> }+    | \<  <parse_metasyntax>  { return $$<parse_metasyntax> }+    | \'  <.literal>    \'+        { return { metasyntax => { metasyntax => ~ $$/ ,} } }+    | { die "invalid alias syntax"; }+}++token parse_metasyntax {+        $<modifier> := [ '!' | '?' | '.' | '' ]+    [+        '{'  <parsed_code>  '}>'+        { return { closure => {+            closure  => $$<parsed_code>,+            modifier => $$<modifier>,+        } } }+    |+        <char_class>+        ( <[+-]> <char_class> )++        \>+        {+            if ( $$<modifier> eq '!' ) {+              return {+                negate => {+                  char_class => [+                    '+' ~ $<char_class>,+                    @($/[0]),   # TODO - stringify+              ] } }+            }+            return {+              char_class => [+                '+' ~ $<char_class>,+                @($/[0]),   # TODO - stringify+            ] }+        }+    |+        <ident>+        [+          <.ws> <rule> \>+          {+            if  ( $$<ident> eq 'before'+               || $$<ident> eq 'after'+                ) {+                return { $$<ident> => { rule => $$<rule>, modifier => $$<modifier> } }+            }+            return { metasyntax => {+                metasyntax => $$<ident>,+                rule       => $$<rule>,+                modifier   => $$<modifier>,+            } }+          }+        |+          ':' <.ws>?+          $<str> := [+            [+            |  \\ <special_char>+            |  <%Pugs::Grammar::Rule::variables>+            |  <-[ \> ]>+            ]*+          ]+          \>+          {+            if  ( $$<ident> eq 'before'+               || $$<ident> eq 'after'+                ) {+                return { $$<ident> => {+                    rule     => { metasyntax => {+                        metasyntax => '\'' ~ $$<str> ~ '\''+                    } },+                    modifier => $$<modifier>,+                } }+            }+            return { metasyntax => {+                metasyntax => $$<ident>,+                string   => $$<str>,+                modifier => $$<modifier>,+            } }+          }+        |+          \(  <parsed_code>  \) \>+          { return { call => {+              method   => $$<ident>,+              params   => $$<parsed_code>,+              modifier => $$<modifier>,+          } } }+        ]+    |+        <metasyntax>  \>+        { return { metasyntax => {+              metasyntax => ~$$<metasyntax>,+              modifier   => $$<modifier>,+        } } }+    ]+}+++%variables = (++    '$<' => token {+        <ident> \>+        { return { match_variable => '$' ~ $/<ident> ,} }+    },+    '$' => token {+        <.digit>++        { return { match_variable => '$' ~ $/ ,} }+    |+        \^?+        [ <.alnum> | _ | \: \: ]++        { return { variable => '$' ~ $/ ,} }+    },+    '@' => token {+        <.digit>++        { return { match_variable => '@' ~ $/ ,} }+    |+        \^?+        [ <.alnum> | _ | \: \: ]++        { return { variable => '@' ~ $/ ,} }+    },+    '%' => token {+        <.digit>++        { return { match_variable => '%' ~ $/ ,} }+    |+        \^?+        [ <.alnum> | _ | \: \: ]++        { return { variable => '%' ~ $/ ,} }+    },++); # /%variables+++%rule_terms = (++    '{*}' => token {+        # placeholder+        { return { metasyntax => { metasyntax => 'null' ,} } }+    },++    '\'' => token {+        <.literal>     \'+        { return { metasyntax => { metasyntax => '\'' ~ $$/ ,} } }+    },+    '(' => token {+        <rule> \)+        { return { capturing_group => $$<rule> ,} }+    },+    '<(' => token {+        <rule>  ')>'+        { return { capture_as_result => $$<rule> ,} }+    },+    '<+' => token {+        <char_class>+        ( <[+-]> <char_class> )*+        \>+        { return {+            char_class => [+                '+' ~ $<char_class>,+                @($/[0]),   # TODO - stringify+            ] }+        }+    },+    '<-' => token {+        <char_class>+        ( <[+-]> <char_class> )*+        \>+        { return {+            char_class => [+                '-' ~ $<char_class>,+                @($/[0]),   # TODO - stringify+            ] }+        }+    },+    '<[' => token {+        <char_range>  \]+        ( <[+-]> <char_class> )*+        \>+        { return {+            char_class => [+                '+[' ~ $<char_range> ~ ']',+                @($/[0]),   # TODO - stringify+            ] }+        }+    },+    '<' => token {+        <parse_metasyntax>+        { return $$<parse_metasyntax> }+    },+    '{' => token {+        <parsed_code>  \}+        { return { closure => {+            closure => $$<parsed_code>,+            modifier => 'plain',+        } } }+    },+    '\\' => token {+        <special_char>+        { return $$<special_char> }+    },+    '.' => token {+        { return { 'dot' => 1 ,} }+    },+    '[' => token {+        <rule> \]+        { return $$<rule> }+    },+    ':::' => token { { return { colon => ':::' ,} } },+    ':?'  => token { { return { colon => ':?' ,} } },+    ':+'  => token { { return { colon => ':+' ,} } },+    '::'  => token { { return { colon => '::' ,} } },+    ':'   => token { { return { colon => ':'  ,} } },+    '$$'  => token { { return { colon => '$$' ,} } },+    '$'   => token { { return { colon => '$'  ,} } },+    '^^'  => token { { return { colon => '^^' ,} } },+    '^'   => token { { return { colon => '^'  ,} } },++    '>>'  => token { { return { colon => '>>' ,} } },+    '»'   => token { { return { colon => '>>' ,} } },++    '<<'  => token { { return { colon => '<<' ,} } },+    '«'   => token { { return { colon => '<<' ,} } },++    ':i'  => token {+        <.ws> <rule>+        { return { modifier => { modifier => 'ignorecase', :$$<rule>, } } } },+    ':ignorecase'  => token {+        <.ws> <rule>+        { return { modifier => { modifier => 'ignorecase', :$$<rule>, } } } },+    ':s'  => token {+        <.ws> <rule>+        { return { modifier => 'sigspace',   :$$<rule>, } } },+    ':sigspace'    => token {+        <.ws> <rule>+        { return { modifier => 'sigspace',   :$$<rule>, } } },+    ':P5' => token {+        <.ws> <rule>+        { return { modifier => 'Perl5',  :$$<rule>, } } },+    ':Perl5'       => token {+        <.ws> <rule>+        { return { modifier => 'Perl5',  :$$<rule>, } } },+    ':bytes'       => token {+        <.ws> <rule>+        { return { modifier => 'bytes',  :$$<rule>, } } },+    ':codes'       => token {+        <.ws> <rule>+        { return { modifier => 'codes',  :$$<rule>, } } },+    ':graphs'      => token {+        <.ws> <rule>+        { return { modifier => 'graphs', :$$<rule>, } } },+    ':langs'       => token {+        <.ws> <rule>+        { return { modifier => 'langs',  :$$<rule>, } } },++); # /%rule_terms++token term {+    |  <%Pugs::Grammar::Rule::variables>+       [  <.ws>? ':=' <.ws>? <named_capture_body>+          {+            return { named_capture => {+                rule =>  $$<named_capture_body>,+                ident => $$<Pugs::Grammar::Rule::variables>,+            }, };+          }+       |+          {+            return $$<Pugs::Grammar::Rule::variables>+          }+       ]+    |  <%Pugs::Grammar::Rule::rule_terms>+        {+            #print "term: ", Dumper( $_[0]->data );+            return $$<Pugs::Grammar::Rule::rule_terms>+        }+    |  <-[ \] \} \) \> \: \? \+ \* \| \& ]>+        {+            #print "constant: ", Dumper( $_[0]->data );+            return { 'constant' => $$/ ,}+        }+}++token quant {+    |   '**' <.ws>? \{  <parsed_code>  \}+        { return { closure => $$<parsed_code> ,} }+    |   <[  \? \* \+  ]>?+}++token quantifier {+    $<ws1>   := (<.ws>?)+    <!before  <[   \} \] \)   ]> >+    <term>+    $<ws2>   := (<.ws>?)+    <quant>+    $<greedy> := (<[  \? \+  ]>?)+    $<ws3>   := (<.ws>?)+    {+      if+               $$/{'quant'}   eq ''+            && $$/{'greedy'} eq ''+            && $$/{'ws1'}    eq ''+            && $$/{'ws2'}    eq ''+            && $$/{'ws3'}    eq ''+      {+          return $$/{'term'};+      }+      return {+        quant => {+            term    => $$/{'term'},+            quant   => $$/{'quant'},+            greedy  => $$/{'greedy'},+            ws1     => $$/{'ws1'},+            ws2     => $$/{'ws2'},+            ws3     => $$/{'ws3'},+        } }+    }+}++token concat {+    <quantifier>++    {+      use v5;+        my @a = map {  $_->()  }  @{ $::_V6_MATCH_->{'quantifier'} };+        return { concat => \@a ,}  if scalar @a > 1;+        return $a[0];+      use v6;+    }+}++token conjunctive1 {+    [ <.ws>? \& <!before \& > ]?++    <concat>**{1}+    [+        \& <!before \& >  <concat>+    ]*++    {+      use v5;+        my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'concat'} };+        return { conjunctive1 => \@a ,}  if scalar @a > 1;+        return $a[0];+      use v6;+    }+}++token disjunctive1 {+    [ <.ws>? \| <!before \| > ]?++    <conjunctive1>**{1}+    [+        \| <!before \| > <conjunctive1>+    ]*++    {+      use v5;+        my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'conjunctive1'} };+        return { alt1 => \@a ,}  if scalar @a > 1;+        return $a[0];+      use v6;+    }+}++token conjunctive {+    [ <.ws>? \& \& ]?++    <disjunctive1>**{1}+    [+        \& \& <disjunctive1>+    ]*++    {+      use v5;+        my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'disjunctive1'} };+        return { conjunctive => \@a ,}  if scalar @a > 1;+        return $a[0];+      use v6;+    }+}++token rule {+    [ <.ws>? \| \| ]?++    <conjunctive>**{1}+    [+        \| \| <conjunctive>+    ]*++    {+      use v5;+        my @a = map {  $$_  }  @{ $::_V6_MATCH_->{'conjunctive'} };+        return { alt => \@a ,}  if scalar @a > 1;+        return $a[0];+      use v6;+    }+}++token named_regex {+    ( 'token' | 'regex' | 'rule' )+    <.ws> <ident> <.ws>? '{'+        <.ws>?+        <rule>+    '}' ';'?++    { return {+            type => $$0,+            name => $$<ident>,+            ast => $$<rule>+        };+    }+}++# This is hacky, will do better later+token verbatim {+    '%{' ( [ <!before '%}'> . ]* ) '%}'+    { return {+            type => 'block',+            value => $$0+        };+    }+}++token item {+    | <verbatim>       { return $$<verbatim>; }+    | <named_regex> { return $$<named_regex>; }+}++token grammar {+    <.ws>? 'grammar' <.ws> <ident> <.ws>? ';'+    <.ws>?+    [ <item> <.ws>? ]*+    { return { $$<ident> => $<item> } }+}++token spec {+    <verbatim>?+    <grammar>*+    { return {+            block => $<verbatim>,+            'grammar' => $<grammar> }+    }+}+
+ blib6/pugs/perl5/lib/Pugs/Grammar/RulePure.pm view
@@ -0,0 +1,263 @@++use v6-alpha;++# Pure-Perl6 implementation of the 'Rule' syntax +# author: Flavio S. Glock - fglock@gmail.com++# This is for demonstation only, it currently can't be run by +# Pugs::Compiler::Rule runtime++grammar Pugs::Grammar::Rule;++our %rule_terms;+our %variables;++token pod_begin {+    |   \n =end \N*+    |   . \N* <?pod_begin>+}++token pod_other {+    |   \n =cut \N*+    |   . \N* <?pod_other>+}++token ws {+    [+    |    \# \N*+    |    \n [ = [+            |  begin <?ws> END \N* .*+            |  begin  <?pod_begin>+            |  kwid   <?pod_other>+            |  pod    <?pod_other>+            |  for    <?pod_other>+            |  head1  <?pod_other>+            ]?+            ]?+    |    \s+    ]++}++# regex ident can start with a number+token ident {+    [ <?alnum> | _ | <'::'> ]++}++token literal {+    [ +    |  \\ .+    |  <-[ \' ]> +    ]*+}++token metasyntax {+    [ +    |  \\ .+    |  \'  <?literal>     \'+    |  \{  <?string_code>        \}+    |  \<  <?metasyntax>  \>+    |  <-[ \> ]> +    ]+ +    { return { metasyntax => $$/ ,} }+}++token string_code {+    # bootstrap "code"+    [ +    |  \\ .+    |  \'  <?literal>     \'+    |  \{  <?string_code>        \}+    |  <-[ \} ]> +    ]+ +}++token parsed_code {+    # this subrule is overridden inside the perl6 compiler+    <?string_code>+    { return '{' ~ $/ ~ '}' }+}++token named_capture_body {+    | \(  <rule>        \)  { return { capturing_group => $$<rule> ,} } +    | \[  <rule>        \]  { return $$<rule> } +    | \<  <metasyntax>  \>  { return $$<metasyntax> } +    | { die "invalid alias syntax" }+}++%variables = (++    '$<' => token {+        <ident> \> +        { return { match_variable => '$' ~ $/<ident> ,} }+    },+    '$' => token { +        <?digit>++        { return { match_variable => '$' ~ $/ ,} }+    |+        \^?+        [ <?alnum> | _ | \: \: ]++        { return { variable => '$' ~ $/ ,} }+    },+    '@' => token { +        <?digit>++        { return { match_variable => '@' ~ $/ ,} }+    |+        \^?+        [ <?alnum> | _ | \: \: ]++        { return { variable => '@' ~ $/ ,} }+    },+    '%' => token { +        <?digit>++        { return { match_variable => '%' ~ $/ ,} }+    |+        \^?+        [ <?alnum> | _ | \: \: ]++        { return { variable => '%' ~ $/ ,} }+    },++); # /%variables+    ++%rule_terms = (++    '(' => token {+        <rule> \)+        { return { capturing_group => $$<rule> ,} }+    },+    '<(' => token {+        <rule>  <')>'>+        { return { capture_as_result => $$<rule> ,} }+    },+    '<after' => token {+        <?ws> <rule> \> +        { return { after => :$$<rule>, } }+    },+    '<before' => token {+        <?ws> <rule> \> +        { return { before => :$$<rule>, } }+    },+    '<!before' => token {+        <?ws> <rule> \> +        { return { not_before => :$$<rule>, } }+    },+    '<!' => token {+        <metasyntax> \> +        { return { negate  => :$$<metasyntax>, } }+    },+    '<' => token { +        <metasyntax>  \>+        { return $$<metasyntax> }+    },+    '{' => token { +        <parsed_code>  \}+        { return { closure => $$<parsed_code> ,} }+    },+    '\\' => token {  +        .+        { return { special_char => '\\' ~ $/ , } } +    },+    '.' => token { +        { return { 'dot' => 1 ,} }+    },+    '[' => token { +        <rule> \] +        { return $$<rule> }+    },+    ':::' => token { { return { colon => ':::' ,} } },+    ':?'  => token { { return { colon => ':?' ,} } },+    ':+'  => token { { return { colon => ':+' ,} } },+    '::'  => token { { return { colon => '::' ,} } },+    ':'   => token { { return { colon => ':'  ,} } },+    '$$'  => token { { return { colon => '$$' ,} } },+    '$'   => token { { return { colon => '$'  ,} } },+    '^^'  => token { { return { colon => '^^' ,} } },+    '^'   => token { { return { colon => '^'  ,} } },++    ':i'           => token { { return { modifier => 'ignorecase'  ,} } },+    ':ignorecase'  => token { { return { modifier => 'ignorecase'  ,} } },+    ':s'           => token { { return { modifier => 'sigspace'  ,} } },+    ':sigspace'    => token { { return { modifier => 'sigspace'  ,} } },+    ':P5'          => token { { return { modifier => 'Perl5'  ,} } },+    ':Perl5'       => token { { return { modifier => 'Perl5'  ,} } },+    ':bytes'       => token { { return { modifier => 'bytes'  ,} } },+    ':codes'       => token { { return { modifier => 'codes'  ,} } },+    ':graphs'      => token { { return { modifier => 'graphs' ,} } },+    ':langs'       => token { { return { modifier => 'langs'  ,} } },++); # /%rule_terms+    +token term {+    |  <%Pugs::Grammar::Rule::variables>+       [  <?ws>? <':='> <?ws>? <named_capture_body>+          { +            return { named_capture => {+                rule =>  $$<named_capture_body>,+                ident => $$<Pugs::Grammar::Rule::variables>,+            }, }; +          }+       |+          { +            return $$<Pugs::Grammar::Rule::variables> +          }+       ]+    |  <%Pugs::Grammar::Rule::rule_terms>+        { +            #print "term: ", Dumper( $_[0]->data );+            return $$<Pugs::Grammar::Rule::rule_terms> +        }+    |  <-[ \] \} \) \> \: \? \+ \* \| \& ]> +        { +            #print "constant: ", Dumper( $_[0]->data );+            return { 'constant' => $$/ ,} +        }+}++token quant {+    |   <'**'> <?ws>? \{  <parsed_code>  \}+        { return { closure => $$<parsed_code> ,} }+    |   <[  \? \* \+  ]>?+}++token quantifier {+    $<ws1>   := (<?ws>?)+    <!before  <[   \} \] \) \>   ]> >+    <term> +    $<ws2>   := (<?ws>?)+    <quant>+    $<greedy> := (<[  \? \+  ]>?)+    $<ws3>   := (<?ws>?)+    { return { +        quant => { +            term    => $$/{'term'},+            quant   => $$/{'quant'},+            greedy  => $$/{'greedy'},+            ws1     => $$/{'ws1'},+            ws2     => $$/{'ws2'},+            ws3     => $$/{'ws3'},+        } }+    }+}++token concat {+    <quantifier>+ +    {             +        my $a = $<quantifier>.map( {  $$_  } );+        return { concat => $a ,}  if $a.elems > 1;+        return $a[0];+    }+}++token rule {+    [ <?ws>? \| ]?+    +    <concat>+    [+        \|  <concat> +    ]*+    +    {             +        my $a = $<concat>.map( {  $$_  } );+        return { alt => $a ,}  if $a.elems > 1;+        return $a[0];+    }+}
+ blib6/pugs/perl5/lib/Pugs/Runtime/Common.pm view
@@ -0,0 +1,62 @@++package Pugs::Runtime::Common;++use strict;+use warnings;++our %quote = (+    # left => # right+    "'"    => "'",    +    '"'    => '"',    +    '/'    => '/',+    '!'    => '!',+    '('    => ')',+    '['    => ']',+    '{'    => '}',+    '<'    => '>',+    '<<'   => '>>',+    '«'    => '»',    +    '“'    => '”',    +    '‘'    => '’',+);++our %perl6_name = (+    # perl 5        => # perl 6+    '%::ENV'        => '%*ENV',  +    '$^O'           => '$*OS',  +    '$$'            => '$*PID',  +    '$0'            => '$*EXECUTABLE_NAME',  +    '$0'            => '$*PROGRAM_NAME',+    '@INC'          => '@*INC',+    +    '\\*STDERR'     => '$*ERR',  ++    '__FILE__'      => '$?FILE',+    +    '$::_V6_ERR_'   => '$!',+    '$::_V6_MATCH_' => '$/',+    '$::_V6_STDIN'  => '$*IN',  +    '$::_V6_STDOUT' => '$*OUT',  +    '$::_V6_BACKEND'=> '$?PUGS_BACKEND',+    '$::_V6_COMPILER_OS'      => '$?OS',+    '$::_V6_COMPILER_NAME'    => '$?COMPILER', +    '$::_V6_COMPILER_VERSION' => '$?VERSION',+);+our %perl5_name = reverse %perl6_name;++sub mangle_ident {+    my $s = shift;+    Carp::confess unless defined $s;+    $s =~ s/ ([^a-zA-Z0-9_:] | (?<!:):(?!:) ) / '_'.ord($1).'_' /xge;+    return $s;+}++sub mangle_var {+    my $s = $_[0];+    #warn "mangle: $s";+    return $perl5_name{$s} if exists $perl5_name{$s};+    substr($s,1) =~ s/ ([^a-zA-Z0-9_:] | (?<!:):(?!:)) / '_'.ord($1).'_' /xge;+    return $s;+}++1;
+ blib6/pugs/perl5/lib/Pugs/Runtime/Match.pm view
@@ -0,0 +1,309 @@+package Pugs::Runtime::Match;+# Documentation in the __END__++use 5.006;+use strict;+use warnings;+use Data::Dumper;+#use Class::InsideOut qw( public register id );+use Scalar::Util qw( refaddr blessed );+use Pugs::Runtime::StrPos;++use overload (+    '@{}'    => \&array,+    '%{}'    => \&hash,+    'bool'   => \&bool,+    '&{}'    => \&code,+    '${}'    => \&scalar,+    '""'     => \&flat,+    '0+'     => \&flat,+    fallback => 1,+);++# class method+# ::fail can be called from inside closures+# sub ::fail { $::_V6_SUCCEED = 0 }++my %_data;++sub new {+    my $obj = bless \$_[1], $_[0];+    $_data{ refaddr $obj } = $_[1];+    return $obj;+}++sub DESTROY {  +    delete $_data{ refaddr $_[0] };+}++sub data  {    $_data{refaddr $_[0]}           }+sub bool  {  ${$_data{refaddr $_[0]}->{bool}}  }+sub array {    $_data{refaddr $_[0]}->{match}  }++sub from  {  ++    return ${$_data{refaddr $_[0]}->{from}};++    my $obj = $_data{refaddr $_[0]};+    #return ${$obj->{from}} if blessed ${$obj->{from}};+    Pugs::Runtime::StrPos->from_str_codes( ${$obj->{str}}, ${$obj->{from}} );+}+sub pos   { $_[0]->to } # pugs pos.t - lvalue ??? +sub to    {  ++    return ${$_data{refaddr $_[0]}->{to}};++    my $obj = $_data{refaddr $_[0]};+    #return ${$obj->{to}} if blessed ${$obj->{to}};+    #print "TO: ",${$obj->{to}},"\n";+    Pugs::Runtime::StrPos->from_str_codes( ${$obj->{str}}, ${$obj->{to}} );+}+# "low-level" position defaults to perl5-utf8+sub from_as_codes  {  ${$_data{refaddr $_[0]}->{from}}  }+sub to_as_codes    {  ${$_data{refaddr $_[0]}->{to}}    }++sub hash  {   +    my $array = $_data{refaddr $_[0]}->{match};+    my $hash  = $_data{refaddr $_[0]}->{named};+    $hash->{$_} = $array->[$_] for 0 .. $#$array;+    return $hash;++    #my $array = $_data{refaddr $_[0]}->{match};+    #return {+    #    %{ $_data{refaddr $_[0]}->{named} },+    #    (+    #    map { ( $_, $array->[$_] ) } +    #        0 .. $#$array+    #    ),+    #}+}+sub keys   { +    CORE::keys   %{$_data{refaddr $_[0]}->{named}},+    0 .. $#{ $_[0]->array }+}+sub values { +    CORE::values %{$_data{refaddr $_[0]}->{named}},+    @{ $_[0]->array }+}+sub kv {+    map { ( $_, $_[0]->{$_} ) } +        $_[0]->keys +}+sub elems  { +    scalar $_[0]->keys+}++sub chars  { CORE::length $_[0]->str }++sub flat {+    my $obj = $_data{refaddr $_[0]};+    my $cap = $obj->{capture};+    #print ref $cap;+    return $$cap+        if ref $cap eq 'REF'   ||+           ref $cap eq 'SCALAR';+    return '' unless ${$obj->{bool}};+    +    return '' if $_[0]->from > length( ${$obj->{str}} );+    +    return substr( ${$obj->{str}}, $_[0]->from, $_[0]->to - $_[0]->from );+}++sub str {+    "" . $_[0]->flat;+}++sub perl {+    local $Data::Dumper::Terse    = 1;+    local $Data::Dumper::Sortkeys = 1;+    local $Data::Dumper::Pad = '  ';+    return __PACKAGE__ . "->new( " . Dumper( $_[0]->data ) . ")\n";+}++sub yaml {+    require YAML::Syck;+    # interoperability with other YAML/Syck bindings:+    $YAML::Syck::ImplicitTyping = 1;+    YAML::Syck::Dump( $_[0] );+}++# for Pugs interoperability+sub dump_hs {+    my $obj;+    if (ref($_[0]) eq 'SCALAR') {+        $obj = ${$_[0]};+    }+    else {+        $obj = $_data{refaddr $_[0]};+    }++    if ($obj) {+        # Ok, this is a genuine Match object.+        return "PGE_Fail" unless ${$obj->{bool}};++        # Now we matched; dump the rest of data+        join(' ', 'PGE_Match', ${$obj->{from}}, ${$obj->{to}},+            ('['.join(', ', map { dump_hs($_) } @{$obj->{match}||[]} ).']'),+            ('['.join(', ', map {+                my $str = $_;+                if ( my $dump = dump_hs($obj->{named}{$_}) ) {+                    $str =~ s/([^ \!\#\$\%\&\x28-\x5B\x5D-\x7E])/'\\'.ord($1)/eg;+                    qq[("$str", $dump)];+                }+                else {+                    ();+                }+            } sort(CORE::keys(%{$obj->{named}||{}})) ).']'),+        )+    }+    elsif (ref($_[0]) eq 'ARRAY') {+        return "PGE_Array [" . join(', ', map { dump_hs($_) } @$obj) . "]"+    }+    elsif (!ref($_[0])) {+        my $str = shift;+        $str =~ s/([^ \!\#\$\%\&\x28-\x5B\x5D-\x7E])/'\\'.ord($1)/eg;+        return "PGE_String \"$str\"";+    }+    else {+        warn "Unrecognized blessed match object: $_[0]";+        return '';+    }+}++# tail() for backwards compatibility+# - doesn't work on failed matches+sub tail {+    return substr( ${$_data{refaddr $_[0]}->{str}}, $_[0]->to );+}++# state() is used for multiple matches and backtracking control+sub state {+    return $_data{refaddr $_[0]}->{state};+}++# return the capture+sub code {+    my $c = $_[0];+    return sub { $c->flat };+}++# return the capture+sub scalar {+    return \( $_[0]->flat );+}++1;++__END__++=head1 NAME ++Pugs::Runtime::Match - Match object created by rules++=head1 METHODS++* array++- return the positional matches++* hash++- return both the named and positional (numbered) matches++* str++- return the stringified capture object. +If there is no capture, return the matched substring++* scalar++- return the capture object+If there is no capture, return the matched substring++* bool++- return whether there was a match++* from++- return the string position (a C<Pugs::Runtime::StrPos> object) where the match started.++* to++- return the string position (a C<Pugs::Runtime::StrPos> object) immediately after where the match finished.++* from_as_codes+* to_as_codes++- same as C<from>/C<to> methods, but return perl5 integers.++=head1 "Hash" methods++* elems++* kv++* keys++* values++=head1 "Str" methods++* chars++=head1 OVERLOADS++* $$match++- return the capture object++* $match->[$n]++- return the positional matches++* $match->{$n}++- return the named matches++* $match ? 1 : 0++- return whether there was a match++=head1 Dumper methods++* data++- return the internal representation as a data structure.++* perl++- return the internal representation as Perl source code. ++* yaml++- return the internal representation as YAML. +Requires the C<YAML::Syck> module.++* dump_hs++- for Pugs interoperability++=head1 SEE ALSO++C<v6> on CPAN++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 COPYRIGHT++Copyright 2006 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut+
+ blib6/pugs/perl5/lib/Pugs/Runtime/Match/HsBridge.pm view
@@ -0,0 +1,83 @@+package Pugs::Runtime::Match::HsBridge;++use utf8;+use strict;+use warnings;+use Pugs::Grammar::Base ();+use Pugs::Compiler::Regex ();+use base 'Pugs::Grammar::Base';++BEGIN { local $@; eval { require 'utf8_heavy.pl' } }++use ops ($ENV{PUGS_SAFEMODE} ? (':default', 'binmode', 'entereval') : ());++sub __RUN__ {+    my $self        = shift;+    my $match_text  = shift;+    my $rule_text   = shift;+    my %subrules    = @_;++    while (my ($name, $body) = each %subrules) {+        my %sub_opts = (grammar => __PACKAGE__);+        ($1 and $sub_opts{$1} = 1) while $body =~ s/^:(\w*)\(1?\)\[(.*)\]\z/$2/s;+        Pugs::Compiler::Regex->reinstall( $name => $body, \%sub_opts );+    }++    my %opts = (grammar => __PACKAGE__);+    ($1 and $opts{$1} = 1) while $rule_text =~ s/^:(\w*)\(1?\)\[(.*)\]\z/$2/s;++    # L<S05/Modifiers/"The C<:ratchet> modifier also implies that the anchoring">+    if ( $opts{ratchet} ) {+        $rule_text  = "^$rule_text" unless $opts{p} or $opts{pos};+        $rule_text .= '$'           unless $opts{c} or $opts{continue};+    }++    local $SIG{__WARN__} = sub { 1 };++    my $rule    = Pugs::Compiler::Regex->compile( $rule_text, \%opts );+    my $match   = $rule->match( $match_text );++    return $match->dump_hs;+}++sub __CMD__ {+    local $| = 1;++    # Command line shell interface - compatible with run_pge.pir+    if ($] >= 5.007) {+        binmode STDIN, ':utf8';+        binmode STDOUT, ':utf8';+    }++    my @subrules;+    while (<STDIN>) {+        #/^(\w+) (\d+) (\d+)/ or die "Unrecognized command: $_";+        /^(\w+) \d+ \d+/ or die "Unrecognized command: $_";+        my $cmd = $1; # my ($cmd, $sz1, $sz2) = ($1, $2, $3);++        my $line1 = <STDIN>; chomp($line1); $line1 =~ s{\\(?:(\\)|(n))}{$1 ? $1 : "\n"}eg;+        my $line2 = <STDIN>; chomp($line2); $line2 =~ s{\\(?:(\\)|(n))}{$1 ? $1 : "\n"}eg;++        if ($cmd eq 'add_rule') {+            push @subrules, $line1, $line2;+        }+        elsif ($cmd eq 'match') {+            if (my $rv = eval { __PACKAGE__->__RUN__($line1, $line2, @subrules) }) {+                my $len = bytes::length($rv)+1;+                print "OK $len\n";+                print "$rv\n\n";+            }+            else {+                my $err = $@;+                $err =~ s/([\\\n])/\\$1/g;+                print "$err\n";+            }+            @subrules = ();+        }+        else {+            die "Unrecognized command: $cmd";+        }+    }+}++1;
+ blib6/pugs/perl5/lib/Pugs/Runtime/Regex.pm view
@@ -0,0 +1,822 @@+package Pugs::Runtime::Regex;++# documentation after __END__++use strict;+use warnings;+no warnings qw(recursion);++#use Smart::Comments; #for debugging, look also at Filtered-Comments.pm+use Data::Dumper;+use Pugs::Runtime::Match;+use Carp qw(croak);++# note: alternation is first match (not longest). +# note: the list in @$nodes can be modified at runtime+sub alternation {+    my $nodes = shift;+    return sub {+        my @state = $_[1] ? @{$_[1]} : ( 0, undef );+        while ( $state[0] <= $#$nodes ) {+            #print "alternation $state[0] ",Dumper($nodes->[ $state[0] ]);+            $nodes->[ $state[0] ]->( $_[0], $state[1], @_[2..7] );+            last unless defined $_[3];  # test case ???+            $state[1] = $_[3]->state;+            $state[0]++ unless $state[1];+            if ( $_[3] || $_[3]->data->{abort} ) {+                $_[3]->data->{state} = $state[0] > $#$nodes +                    ? undef+                    : \@state;+                return;+            }+        }+        $_[3] = failed()->(@_);+    }+}++sub concat {+    my $nodes = shift;+    $nodes = [ $nodes, @_ ] unless ref($nodes) eq 'ARRAY';  # backwards compat+    return null()      if ! @$nodes;+    return $nodes->[0] if @$nodes == 1;+    if ( @$nodes > 2 ) {+        return concat(+            concat( [ $nodes->[0], $nodes->[1] ] ),+            @$nodes[ 2 .. $#$nodes ],+        );+    }+    return sub {+        my @state = $_[1] ? @{$_[1]} : ( undef, undef );+        #print "enter state ",Dumper(\@state);+        my $m2;+        my $redo_count = 0;  +            # XXX - workaround for t/regex/from_perl6_rules/capture.t test #38:+            # regex single { o | k | e };+            # # ...+            # ok(!( "bokeper" ~~ m/(<?single>) ($0)/ ), 'Failed positional backref');++        do {++            my %param1 = defined $_[7] ? %{$_[7]} : ();+            #print "concat 1: @{[ %param1 ]} \n";++            $nodes->[0]->( $_[0], $state[0], @_[2..7] );+            return if ! $_[3] +                   || $_[3]->data->{abort};++            my $is_empty = ( $_[3]->from == $_[3]->to );+            #    && ( $param1{was_empty} )+            #    ; # fix a problem with '^'+            if ( $is_empty && $param1{was_empty} ) {+                #    # perl5 perlre says "the following match after a zero-length match+                #   is prohibited to have a length of zero"+                return unless $_[3]->from == 0;+            }++            my $param = { ( defined $_[7] ? %{$_[7]} : () ), +                          p => $_[3]->to,+                          was_empty => $is_empty,+                        };     +            # TODO - retry the second submatch only, until it fails+            my $next_state = $_[3]->state;+            #print "next_state ",Dumper($next_state);+            #print "concat 2: "," \n";+            $nodes->[1]->( $_[0], $state[1], $_[2], $m2, +                           $_[4], $_[3]->to, $_[6], $param );+            +              #return if $is_empty && $m2->from == $m2->to; +            $state[1] = $m2->state;+            $state[0] = $next_state unless $state[1];+            #print "concat 3: "," \n";+            #print "return state ",Dumper(\@state);++        } while    ! $m2 +                && ! $m2->data->{abort} +                && defined $state[0]+                && $redo_count++ < 512+                ; ++        # push capture data+        # print "Concat positional: ", Dumper( $_[3]->data->{match}, $m2->data->{match} );+        for ( 0 .. $#{ $m2 } ) { +            if ( ref $m2->[$_] eq 'ARRAY' ) {+                # TODO - fully static count+                # push @{ $_[3]->data->{match}[$_] }, @{ $m2->[$_] };+                $_[3]->data->{match}[$_] = [+                    ( ref( $_[3]->data->{match}[$_] ) eq 'ARRAY' +                      ? @{ $_[3]->data->{match}[$_] }+                      : defined( $_[3]->data->{match}[$_] ) +                      ?    $_[3]->data->{match}[$_] +                      :    () +                    ), +                    @{ $m2->[$_] },+                ];+            }+            elsif ( defined $m2->[$_] ) {+                $_[3]->data->{match}[$_] = $m2->[$_];+            }+        }+        #print "Concat named: ", Dumper( $_[3]->data->{named}, $m2->data->{named} );+        for ( keys %{$m2} ) {+            if ( ref $m2->{$_} eq 'ARRAY' ) {+                # TODO - fully static count+                #push @{ $_[3]->data->{named}{$_} }, @{ $m2->{$_} };+                $_[3]->data->{named}{$_} = [+                    ( ref( $_[3]->data->{named}{$_} ) eq 'ARRAY'+                      ? @{ $_[3]->data->{named}{$_} }+                      : defined( $_[3]->data->{named}{$_} ) +                      ?    $_[3]->data->{named}{$_} +                      :    () +                    ),+                    @{ $m2->{$_} },+                ];+            }+            elsif ( defined $m2->{$_} ) {+                $_[3]->data->{named}{$_} = $m2->{$_};+            }+        }+        # /push capture data++        %{$_[3]->data} = (+                %{$_[3]->data},+                bool    => \($m2->bool),+                to      => \($m2->to),+                capture => $m2->data->{capture} || $_[3]->data->{capture},+                abort   => $m2->data->{abort},+                state   => ( defined $state[0] || defined $state[1] +                             ? \@state +                             : undef ),+        );+    }+}++sub try_method { +    my $method = shift;+    my $param_list = shift;  # XXX+    no warnings qw( uninitialized );+    # XXX method call must be inlined, due to inheritance problems+    my $sub = 'sub {+        my $bool = $_[0]->'.$method.'( '.$param_list.' ) ? 1 : 0;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \$bool,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+            });+    }';+    #print "sub: $sub\n";+    return eval $sub;+}+++sub ignorecase { +    my $sub = shift;+    no warnings qw( uninitialized );+    return sub {+        my %param = ( ( defined $_[7] ? %{$_[7]} : () ), ignorecase => 1 );+        $sub->( @_[0..6], \%param );+    }+}++sub constant { +    my $const = shift;+    my $lconst = length( $const );+    no warnings qw( uninitialized );+    return sub {+        my $bool = $_[7]{ignorecase}+            ? lc( $const ) eq lc( substr( $_[0], $_[5], $lconst ) )+            : $const eq substr( $_[0], $_[5], $lconst );+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \$bool,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \($_[5] + $lconst),+                named => {},+                match => [],+            });+    }+}++sub perl5 {+    my $rx;+    no warnings qw( uninitialized );+    { +        local $@;+        $rx = eval " use charnames ':full'; qr(^($_[0]))s ";+        #print "regex perl5<< $_[0] >>\n";+        print "Error in perl5 regex: << $_[0] >> \n$@\n"+            if $@;+        #die "Error in perl5 regex: $_[0]"+        #    if $@;+    }+    return sub {+        #use charnames ':full';+        my $bool = $_[7]{ignorecase}+            ? substr( $_[0], $_[5] ) =~ m/(?i)$rx/+            : substr( $_[0], $_[5] ) =~ m/$rx/;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \$bool,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \($_[5] + length $1),+                named => {},+                match => [],+            });+    };+}++sub null {+    no warnings qw( uninitialized );+    return sub {+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \1,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+            });+    }+};++sub failed {+    no warnings qw( uninitialized );+    return sub {+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \0,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                state => undef,+            });+    }+};++sub failed_abort {+    no warnings qw( uninitialized );+    return sub {+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \0,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 1,+            });+    }+};++sub named {+    # return a named capture+    my $label = shift;+    my $capture_to_array = shift;  +    my $node = shift;+    sub {+        my $match;+        $node->( @_[0,1,2], $match, @_[4,5,6,7] );+        my %matches;+        $matches{ $label } = $capture_to_array ? [ $match ] : $match;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $match->bool ),+                str   => \$_[0],+                from  => \( $match->from ),+                to    => \( $match->to ),+                named => \%matches,+                match => [],+                capture => $match->data->{capture},+                state => $match->state,+            });+    }+}+sub capture { named(@_) } # backwards compat++sub positional {+    # return a positional capture+    my $num = shift;  +    my $capture_to_array = shift;  +    my $node = shift;+    sub {+        my $match;+        $node->( @_[0,1,2], $match, @_[4,5,6,7] );+        my @matches;+        $matches[ $num ] = $capture_to_array ? [ $match ] : $match;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $match->bool ),+                str   => \$_[0],+                from  => \( $match->from ),+                to    => \( $match->to ),+                named => {},+                match => \@matches,+                capture => $match->data->{capture},+                state => $match->state,+            });+    }+}++sub capture_as_result {+    # return a capture as the result object+    my $node = shift;+    sub {+        my $match;+        $node->( @_[0,1,2], $match, @_[4,5,6,7] );+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $match->bool ),+                str   => \$_[0],+                from  => \( $match->from ),+                to    => \( $match->to ),+                named => {},+                match => [],+                capture => ( +                    sub {+                        # print "Match: ", Dumper( $match );+                        '' . $match +                    } +                ),+                state => $match->state,+            });+    }+}++sub ___abort { +    my $op = shift;+    return sub {+        print "ABORTING\n";+        $op->( @_ );+        print "ABORT: [0] ",Dumper(@_);  #$_[3]->perl;+        $_[3]->data->{abort} = 1;+        print "ABORT: ",$_[3]->perl;+    };+};++sub ___fail { +    my $op = shift;+    return abort( +        sub {+            print "FAILING\n";+            $op->( @_ );+            $_[3]->data->{bool} = \0;+            print "FAIL: ",Dumper( $_[3] );+        } +    );+};++sub before { +    my $op = shift;+    return sub {+        my $match;+        $op->( @_[0,1,2], $match, @_[4,5,6,7] );+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $match->bool ),+                str   => \$_[0],+                from  => \( $match->from ),+                to    => \( $match->from ),+                named => {},+                match => [],+                state => $match->state,+            });+    };+}++sub at_start {+    no warnings qw( uninitialized );+    return sub {+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $_[5] == 0 ),+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 0,+            });+    }+};++sub at_line_start {+    no warnings qw( uninitialized );+    return sub {+        my $bool = $_[5] == 0+            ||  substr( $_[0], 0, $_[5] ) =~ /\n$/s;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \$bool,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 0,+            });+    }+};++sub at_line_end {+    no warnings qw( uninitialized );+    return sub {+        my $bool = $_[5] >= length( $_[0] )+            ||  substr( $_[0], $_[5] ) =~ /^\n/s;+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \$bool,+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 0,+            });+    }+};++sub at_end_of_string {+    no warnings qw( uninitialized );+    return sub {+        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $_[5] == length( $_[0] ) ),+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 0,+            });+    }+};++# experimental!+sub negate { +    my $op = shift;+    return sub {+        #my $str = $_[0];+        my $match = $op->( @_ );+        my $bool = ! $match;++        $_[3] = Pugs::Runtime::Match->new({ +                bool  => \( $bool ),+                str   => \$_[0],+                from  => \(0 + $_[5]),+                to    => \(0 + $_[5]),+                named => {},+                match => [],+                abort => 0,+            });++    };+};++# ------- higher-order ruleops++sub optional {+    my $node = shift;+    alternation( [ $node, null() ] );+}++sub null_or_optional {+    my $node = shift;+    alternation( [ null(), $node ] );+}++sub greedy_star { +    greedy_plus( $_[0], $_[1] || 0, $_[2] ) +}++sub non_greedy_star { +    non_greedy_plus( $_[0], $_[1] || 0, $_[2] ) +}++# XXX - needs optimization for faster backtracking, less stack usage+# TODO - run-time ranges (iterator)+sub greedy_plus { +    my $node = shift;+    my $min_count = defined( $_[0] ) ? $_[0] : 1;+    my $max_count = $_[1];  +    if (  defined $max_count +       && $max_count < 1e99+       ) {+        return concat( [ +            ( $node )             x $min_count, +            ( optional( $node ) ) x ($max_count - $min_count) +        ] );+    }+    # $max_count == infinity+    my $alt;+    $alt = concat( [+        $node, +        optional( sub{ goto $alt } ),  +    ] );+    return optional( $alt ) if $min_count < 1;+    return concat( [ ( $node ) x ($min_count - 1), $alt ] );+}++# XXX - needs optimization for faster backtracking, less stack usage+# TODO - run-time ranges (iterator)+sub non_greedy_plus { +    my $node = shift;+    my $min_count = defined( $_[0] ) ? $_[0] : 1;+    my $max_count = $_[1] || 1e99;+    return sub {+        my $state = $_[1] +            || { node  => concat( [ ( $node ) x $min_count ] ), +                 count => $min_count };+        return failed()->(@_)+            if $state->{count} > $max_count;+        $state->{node}->( $_[0], undef, @_[2..7] );+        $_[3]->data->{state} = +            { node  => concat( [ $node, $state->{node} ] ), +              count => $state->{count} + 1 };+    }+}++sub range {+    my $node = shift;+    my $min_count = shift;+    my $max_count = shift;+    my $greedy = not shift;+    return sub {++        my $continuation = $_[1]; #XXX how do optional continuations work?++        # Forward declarations++        my $try_getting_more;++        my $default_behavior;+        my $fallback_behavior;++        # Loop variables++        my $count = 0;+        my $previous_pos = -1;++        # Loop 1 - getting to min_count++        my $continue_towards_min;+        my $get_minimum = sub {+            if ( $count < $min_count ) {+                $count++;+                goto &$continue_towards_min;+            } else {+                goto &$try_getting_more;+            }+        };+        $continue_towards_min = concat( [ $node, $get_minimum ] );++        # Loop 2 - beyond the minimum++        $try_getting_more = sub {++            my $current_pos = $_[5];++            # (1) Stop when max_count is reached, or if pos does not move.++            if ( !( $count < $max_count ) ||+                 !( $previous_pos < $current_pos ) )+            {+                goto &$continuation;+            }+            $count++;+            $previous_pos = $current_pos;++            # (2) Attempt the default behavior.++            # XXX - This section needs to be filled in.+            # try $default_behavior+            #  if successful, return.+            #  if abort, do whatever is needed.+            #  if fail, we need to backtrack:+            #    undo any side-effects from trying the $default_behavior,+            #    so we can do the $fallback_behavior.++            # (3) Since the default behavior failed, do the fall-back beharvior.++            goto &$fallback_behavior;++        };+        my $get_one_and_maybe_more = concat( [ $node, $try_getting_more ] );++        # Final preparations.++        if ( $greedy ) {+            $default_behavior = $get_one_and_maybe_more;+            $fallback_behavior = $continuation;+        } else { # non-greedy+            $default_behavior = $continuation;+            $fallback_behavior = $get_one_and_maybe_more;+        }++        # Start.++        goto &$get_minimum;+    };+}+++sub preprocess_hash {+    # TODO - move to Pugs::Runtime::Regex+    my ( $h, $key ) = @_;+    # returns AST depending on $h+    #print "preprocess_hash: ", Dumper( \@_ );+    if ( ref( $h->{$key} ) eq 'CODE') {+        return sub { +            my ( $str, $grammar, $args ) = @_;+            #print "data: ", Dumper( \@_ );+            my $ret = $h->{$key}->( @_ ); +            #print "ret: ", Dumper( $ret );+            +            return $ret +                if ref( $ret ) eq 'Pugs::Runtime::Match';+            +            Pugs::Runtime::Match->new( { +                bool => \1, +                str =>  \$str,+                from => \( 0 + ( $args->{p} || 0 ) ),+                to =>   \( 0 + ( $args->{p} || 0 ) ),+                named => {},+                match => [],+            } ) }+    } +    if ( ref( $h->{$key} ) =~ /Pugs::Compiler::/ ) {+        return sub { $h->{$key}->match( @_ ) };+    }+    # fail is number != 1 +    if ( $h->{$key} =~ /^(\d+)$/ ) {+        return sub { +            my ( $str, $grammar, $args ) = @_;+            Pugs::Runtime::Match->new( { +                bool => \0, +                str =>  \$str,+                from => \( 0 + ( $args->{p} || 0 ) ),+                to =>   \( 0 + ( $args->{p} || 0 ) ),+                named => {},+                match => [],+            } ) } unless $1 == 1;+        return sub { +            my ( $str, $grammar, $args ) = @_;+            Pugs::Runtime::Match->new( { +                bool => \1, +                str =>  \$str,+                from => \( 0 + ( $args->{p} || 0 ) ),+                to =>   \( 0 + ( $args->{p} || 0 ) ),+                named => {},+                match => [],+            } ) };+    }+    # subrule+    #print "compile: ",$h->{$key}, "\n";++    # XXX - compile to Token or to Regex ? (v6.pm needs Token)+    my $r = Pugs::Compiler::Token->compile( $h->{$key} );+    $h->{$key} = $r;+    return sub { $r->match( @_ ) };+    # return sub { warn "uncompiled subrule: $h->{$key} - not implemented " };+}++# see commit #9783 for an alternate implementation+sub hash {+    my %hash = %{shift()};+    #print "HASH: @{[ %hash ]}\n";+    my @keys = sort {length $b <=> length $a } keys %hash;+    #print "hash keys [ @keys ]\n";+    for ( @keys ) {+        my $h = preprocess_hash( \%hash, $_ );+        my $key = $_;+        $_ = +          concat( [+            constant( $key ),+            sub { +              # print "hash param: ",Dumper(\@_);+              # TODO - add $<KEY> to $_[7]+              $_[3] = $h->( $_[0], $_[4], $_[7], $_[1] );+              # print "result: ",Dumper($_[3]);+            }+          ] );+    }+    return alternation( \@keys );+}++# not a 'rule node'+# gets a variable from the user's pad+# this is used by the <$var> rule+sub get_variable {+    my $name = shift;+    +    local $@;+    my($idx, $pad) = 0;+    while(eval { require PadWalker; $pad = PadWalker::peek_my($idx) }) {+        $idx++, next+          unless exists $pad->{$name};++        #print "NAME $name $pad->{$name}\n";+        return ${ $pad->{$name} } if $name =~ /^\$/;+        return $pad->{$name};  # arrayref/hashref+    }+    croak "Couldn't find '$name' in surrounding lexical scope.";+}+++1;++__END__++=for About++Original file: pX/Common/iterator_engine.pl - fglock++TODO++- There are no tests yet for <before>, hashes, end_of_string++- It needs a 'direction' flag, in order to implement <after>.++- Quantified matches could use less stack space.++- Simplify arg list - the functions currently take 8 arguments.++- weaken self-referential things++=cut++=pod++A "rule" function gets as argument a list:++0 - the string to match +1 - an optional "continuation"+2 - the partially built match tree+3 - a leaf pointer in the match tree+4 - the grammar name+5 - pos +#6 - the whole string to match +7 - argument list - <subrule($x,$y)>++it modifies argument #3 to a Match object:++    bool  - an "assertion" (true/false)+    from  - string pointer for start of this match+    to    - string pointer for next match (end+1)+    match - positional submatches+    named - named submatches+    capture - return'ed things+    +    state - a "continuation" or undef+    abort - the match was stopped by a { return } or a fail(),+           and it should not backtrack or whatever++A "ruleop" function gets some arguments and returns a "rule" funtion.++=cut++=for later+# experimental!+sub try { +    my $op = shift;+    return sub {+        my $match = $op->( @_ );+        ### abortable match...+        $match->{abort} = 0;+        return $match;+    };+};++=cut++=for later++sub fail { +    return abort( +        sub {+            return { bool => \0 };+        } +    );+};++=cut++# experimental!++=for example+    # adds an 'before' or 'after' sub call, which may print a debug message +    wrap( { +            before => sub { print "matching variable: $_[0]\n" },+            after  => sub { $_[0]->{bool} ? print "matched\n" : print "no match\n" },+        },+        \&variable+    )+=cut++=for later+sub wrap {+    my $debug = shift;+    my $node = shift;+    sub {+        $debug->{before}( @_ ) if $debug->{before};+        my $match = $node->( @_ );+        $debug->{after}( $match, @_ ) if $debug->{after};+        return $match;+    }+}+=cut+
+ blib6/pugs/perl5/lib/Pugs/Runtime/Rule.pm view
@@ -0,0 +1,5 @@+package Pugs::Runtime::Rule;++die __PACKAGE__;++1;
+ blib6/pugs/perl5/lib/Pugs/Runtime/StrPos.pm view
@@ -0,0 +1,230 @@+package Pugs::Runtime::StrPos;+# Documentation in the __END__++#use 5.006; ???+use strict;+use warnings;+use utf8;+use Data::Dumper;++use overload (+    'bool'   => \&bool,+    '0+'     => \&graphs,+    '++'     => sub { +        $_[0]->{codes} = ($_[0]->add_graphs( 1 ))->{codes}; +    },+    '+='     => sub { +        $_[0]->{codes} += $_[1]; +    },+    '+'     => sub { +        ($_[0]->add_graphs( $_[1] ))->{codes}; +    }, +    '='     => sub {+           my $self = shift;+           bless {%$self}, ref $self;+         }, +    fallback => 1,+);++# new({ str => "...", codes => $n });+# $str must be utf-8+# $n can be undef, meaning "nowhere in this string" +sub new {+    return bless $_[1], $_[0];+}++# codes is the default perl5 representation+# graphs is the default perl6 representation+sub from_str_graphs {+    +    # -- downgrade as appropriate+    #die "string has invalid internal encoding" +    return from_str_codes( @_ )+        unless utf8::is_utf8( $_[1] );+        +    $_[1] =~ m/^\X{$_[2]}/g;+    return bless { str => $_[1], codes => pos($_[1]) }, $_[0];+}++sub from_str_codes {+    return bless { str => $_[1], codes => $_[2] }, $_[0];+}++sub from_str {+    return bless { str => $_[1], codes => pos( $_[1] ) }, $_[0];+}++sub clone {+    return bless { %{$_[0]} }, ref( $_[0] );+}++sub bool  { +    defined $_[0]->{codes} +}++sub codes  { +    $_[0]->{codes} +}++sub bytes { +    return undef unless defined $_[0]->{codes};++    # -- downgrade as appropriate+    #die "string has invalid internal encoding" +    return $_[0]->codes+        unless utf8::is_utf8( $_[0]->{str} );++    my $s = substr( $_[0]->{str}, 0, $_[0]->{codes} );+    {+        use bytes;+        return length( $s );+    }+    #my @bytes = unpack("C*", substr( $_[0]->{str}, 0, $_[0]->{codes} ) );+    #print "[",join(",", @bytes),"]\n";+    #return scalar @bytes;+}++sub graphs { +    return undef unless defined $_[0]->{codes};++    # -- downgrade as appropriate+    #die "string has invalid internal encoding" +    return $_[0]->codes+        unless utf8::is_utf8( $_[0]->{str} );+        +    #return scalar( substr( $_[0]->{str}, 0, $_[0]->{codes} ) =~ m/\X/g );+    my @g = substr( $_[0]->{str}, 0, $_[0]->{codes} ) =~ m/\X/g;+    return scalar @g;+}++sub langs {+    die "TODO: langs()";+}++sub add_codes {+    (ref $_[0])->from_str_codes( $_[0]->{str}, $_[0]->codes + $_[1] );+}++sub add_graphs {+    (ref $_[0])->from_str_graphs( $_[0]->{str}, $_[0]->graphs + $_[1] );+}++sub perl {+    local $Data::Dumper::Terse    = 1;+    local $Data::Dumper::Sortkeys = 1;+    local $Data::Dumper::Pad = '  ';+    return Dumper( $_[0] );+}++sub yaml {+    require YAML::Syck;+    # interoperability with other YAML/Syck bindings:+    $YAML::Syck::ImplicitTyping = 1;+    YAML::Syck::Dump( $_[0] );+}++# for Pugs interoperability+sub dump_hs {+    die "TODO";+}++1;++__END__++=head1 NAME ++Pugs::Runtime::StrPos - Represent a position inside a string++=head1 OPTIONAL MODULES++* YAML::Syck++- in order to support 'yaml()'++=head1 METHODS++* new({ str => "...", codes => $n });++create a new StrPos object.++'str' must be utf-8.++'codes' can be undef, meaning "nowhere in this string".++* from_str( $str )++create a new StrPos object, using the perl5-string internal 'pos'.++* from_str_graphs( $str, $graphs )+* from_str_codes( $str, $codes )++create a new StrPos object using grapheme or codepoint units.++* bytes()+* codes()+* graphs()++- return the position as an integer, counting in bytes, codepoints, or graphemes.++* langs()++- TODO - return the position as an integer, counting in language dependent chars. ++* bool()++- test whether a position is defined.++* add_codes($n)+* add_graphs($n)++- return a new StrPos with the new position++* clone++- return a new StrPos with the same position++=head1 OVERLOADS++* numeric++- return the count of graphemes, or undef.++* boolean ++- test whether a position is defined. The position 'zero' is true.++=head1 Dumper methods++* perl++- return the internal representation as Perl source code. ++* yaml++- return the internal representation as YAML. +Requires the C<YAML::Syck> module.++* dump_hs++- for Pugs interoperability++=head1 SEE ALSO++C<v6> on CPAN++=head1 AUTHORS++The Pugs Team E<lt>perl6-compiler@perl.orgE<gt>.++=head1 COPYRIGHT++Copyright 2007 by Flavio Soibelmann Glock and others.++This program is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.++See L<http://www.perl.com/perl/misc/Artistic.html>++=cut+
+ blib6/pugs/perl5/lib/Pugs/Runtime/Tracer.pm view
@@ -0,0 +1,124 @@+package Pugs::Runtime::Tracer;++use strict;+use warnings;+use base 'Exporter';+#use Smart::Comments;++our @EXPORT = qw(+   trace_begin trace_end trace+   expand_tracing_code+);++sub trace_begin ($$$$) {+   my ($name, $from, $to, $pos) = @_;+   trace(">>BEGIN $name<< $from..$to at $pos\n");+}++sub trace_end ($$$) {+   my ($name, $res, $pos) = @_;+   trace(">>END $name<< ", $res ? 'success' : 'fail', " at $pos\n");+}++sub trace ($@) {+   if (!defined $::PCR_TRACE_FH) {+       $::PCR_TRACE_FH = \*STDOUT;+   }+   print $::PCR_TRACE_FH @_;+}++sub expand_tracing_code {+    my $s = shift;+    open my $in, '<', \$s or die;+    my (@names, $name, $new, @has_pos);+    while (<$in>) {+        chomp;+        if (/\s+## <(\w+)>$/) {+            $name = $1;+            push @names, $name;+            push @has_pos, 0;+            ### begin: $name+            $new .= $_ . "\n";+        } elsif (/(\s+)## pos: (\d+) (\d+)$/) {+            my ($tab, $from, $to) = ($1, $2, $3);+            $has_pos[-1] = 1;+            $new .= <<"_EOC_";+$_+$tab do {+$tab   Pugs::Runtime::Tracer::trace_begin('$name', $from, $to, \$pos);+$tab   my \$retval =+_EOC_+        } elsif (/(\s+)## <\/(\w+)>$/) {+            my ($tab, $n) = ($1, $2);+            $name = pop @names;+            my $has_pos = pop @has_pos;+            ### end: $n . "<=>" . $name+            if (!defined $name || $n ne $name) {+                die "ERROR: unexpected closing tag </$n>";+            } elsif ($has_pos) {+                $new .= <<"_EOC_";+$_+$tab ;+$tab   Pugs::Runtime::Tracer::trace_end('$name', \$retval, \$pos);+$tab   \$retval;+$tab }+_EOC_+            }+            if (!$has_pos) {+                #warn "No pos info found for <$n>";+            }+        } else {+            $new .= $_ . "\n";+        }+    }+    return $new;+}++1;+__END__++=head1 NAME++Pugs::Runtime::Tracer - tracer runtime for Pugs::Compiler::Rule++=head1 SYNOPSIS++    use Pugs::Runtime::Tracer;+    trace("blah blah blah");+    trace_begin($regex_name, $regex_pos_from, $regex_pos_to, $input_pos);+    trace_end($regex_name, $success, $input_pos);+    $perl5_code_with_tracing_code = expand_tracing_code($perl5_code);++=head1 DESCRIPTION++This module provides tracing facilities for both PCR compile-time and run-time.++=head1 SEE ALSO++=over++=item *++L<compile_p6grammar.pl>++=item *++"A graphical tracer for Perl 6 regexes based on PCR"++L<http://pugs.blogs.com/pugs/2007/10/a-graphical-tra.html>.++=back++=head1 AUTHOR++Agent Zhang E<lt>agentzh@yahoo.cnE<gt>.++=head1 COPYRIGHT++Copyright 2007 by Yahoo! China Inc. L<http://cn.yahoo.com>.++=head1 LICENSE++This module is free software; you can redistribute it and/or modify it+under the same terms as Perl itself.+
+ perl5/p5embed.c view
@@ -0,0 +1,590 @@+#include "p5embed.h"+#include <XSUB.h>+#include "perlxsi.c"+#include "pugsembed.c"++/* define to enable pugsembed debug messages */+#define PERL5_EMBED_DEBUG 0++#if PERL5_EMBED_DEBUG+#define oRZ ""+#define hate Perl_croak(aTHX_ "hate software")+#else+#define oRZ "#"+#define hate+#endif++/* Workaround for mapstart: the only op which needs a different ppaddr */+#undef Perl_pp_mapstart+#define Perl_pp_mapstart Perl_pp_grepstart+#undef OP_MAPSTART+#define OP_MAPSTART OP_GREPSTART++static PerlInterpreter *my_perl;++int _P5EMBED_INIT = 0;++const char pugs_guts_code[] =+"use strict;\n\n"++"package pugs;\n\n"++"our $AUTOLOAD;\n"+"sub AUTOLOAD { pugs::guts::invoke($AUTOLOAD, @_) } \n"+"sub DESTROY {}\n\n"++"package pugs::guts;\n"+"our @ISA=('pugs');\n"+"sub Code { my ($class, $val) = @_;\n"+"            sub { pugs::guts::invoke($val, undef, @_) } }\n"++"sub Array { my ($class, $val) = @_;\n"+"            my $array; tie @$array, 'pugs::array', $val;\n"+oRZ"   warn 'returning '.$array;\n"+"            return $array; }\n\n"++"sub Hash { my ($class, $val) = @_;\n"+"           my $hash; tie %$hash, 'pugs::hash', $val;\n"+oRZ"   warn 'returning '.$hash;\n"+"            return $hash; }\n\n"++"sub Pair { goto &Hash }\n"++"sub Scalar { my ($class, $val) = @_;\n"+"           my $scalar; tie $$scalar, 'pugs::scalar', $val;\n"+oRZ"   warn 'returning '.$scalar;\n"+"            return $scalar; }\n\n"++"sub Handle { my ($class, $val) = @_;\n"+"           tie *FH, 'pugs::handle', $val;\n"+oRZ"   warn 'returning '.$handle;\n"+"            return *FH; }\n\n"++"our $AUTOLOAD;\n"+"sub AUTOLOAD { my $type = $AUTOLOAD; $type =~ s/.*:://;\n"+"               return if $type =~ m/^[A-Z]*$/; die 'unhandled support type: '.$type } \n"+oRZ"warn 'compiled .'.__PACKAGE__;\n\n"++"package pugs::array;\n"++"our $AUTOLOAD;\n"++"sub AUTOLOAD { my $type = $AUTOLOAD; $type =~ s/.*:://;\n"+"               warn 'unhandled support type: '.$type } \n"++"sub TIEARRAY {\n"+"       my ($class, $val) = @_;\n"+"       bless \\$val, $class; }\n\n"++"sub DEREF { ${$_[0]} }\n"++"sub STORE {\n"+"       my ($self, $index, $elem) = @_;\n"+oRZ"    warn 'store! '.$elem;\n"+"       pugs::guts::eval_apply('sub ($x is rw, $y is rw, $z is rw) { item($x[$y] = $z);\n"+oRZ"                                                     warn $x\n"+"                               }', $$self, $index, $elem) }\n\n"++"sub PUSH {\n"+"       my ($self, @elems) = @_;\n"+"       pugs::guts::eval_apply('sub ($x is rw, @*y) { item $x.push(@y);\n"+oRZ"                                                 warn $x\n"+"                               }', $$self, @elems) }\n\n"++"sub FETCHSIZE {\n"+"       my ($self) = @_;\n"+"       my $ret = pugs::guts::invoke('elems', $$self); \n"+oRZ"    warn 'FETCHSIZE: '.$ret;\n"+"       $ret; }\n\n"++"sub EXISTS {\n"+"       my ($self, $index) = @_;\n"+"       pugs::guts::eval_apply('sub ($x, $y) { item $x.exists($y) }', $$self, $index) }\n"++"sub FETCH {\n"+"       my ($self, $index) = @_;\n"+oRZ"    warn 'FETCH: '.$index;\n"+"       pugs::guts::eval_apply('sub ($x, $y) { item $x.[$y] }', $$self, $index) }\n"++"package pugs::hash;\n"++"our $AUTOLOAD;\n"+"sub AUTOLOAD { my $type = $AUTOLOAD; $type =~ s/.*:://;\n"+"               warn 'unhandled support type: '.$type } \n"++"sub TIEHASH {\n"+"       my ($class, $val) = @_;\n"+"       bless [$val,0], $class; }\n\n"++"sub DEREF { $_[0][0] }\n"++"sub FETCH {\n"+"       my ($self, $index) = @_;\n"+oRZ"    warn 'FETCH: '.$index;\n"+"       pugs::guts::eval_apply('sub ($x, $y) { item $x.{$y} }', $self->[0], $index) }\n"++"sub DELETE {\n"+"       my ($self, $index) = @_;\n"+oRZ"    warn 'DELETE: '.$index;\n"+"       pugs::guts::eval_apply('sub ($x, $y) { item $x.delete($y) }', $self->[0], $index) }\n"++"sub CLEAR {\n"+"       my ($self) = @_;\n"+"       pugs::guts::eval_apply('sub ($x) { item $x.delete($x.keys) }', $self->[0]) }\n"++"sub STORE {\n"+"       my ($self, $index, $elem) = @_;\n"+oRZ"    warn 'store! '.$elem;\n"+"       pugs::guts::eval_apply('sub ($x is rw, $y, $z) { item($x{$y} = $z);\n"+oRZ"                                                     warn $x\n"+"                               }', $self->[0], $index, $elem) }\n\n"++"sub FIRSTKEY {\n"+"       my ($self) = @_;\n"+"       my $ret = pugs::guts::invoke('keys', $self->[0]); \n"+oRZ"       warn $ret;\n"+"       $self->[1] = 0; $self->[2] = $ret;"+"       $self->NEXTKEY; }\n"++"sub NEXTKEY {\n"+"       my ($self) = @_;\n"+"       return undef if $self->[1] > $#{$self->[2]};"+"       $self->[2]->[$self->[1]++]; }"++"package pugs::scalar;\n"++"our $AUTOLOAD;\n"+"sub AUTOLOAD { my $type = $AUTOLOAD; $type =~ s/.*:://;\n"+"               warn 'unhandled support type: '.$type } \n"++"sub TIESCALAR {\n"+"       my ($class, $val) = @_;\n"+"       bless \\$val, $class; }\n\n"++"sub DEREF { ${$_[0]} }\n"++"sub FETCH {\n"+"       my ($self) = @_;\n"+"       pugs::guts::eval_apply('sub ($x) { ~$x }', $$self) }\n"++"sub STORE {\n"+"       my ($self, $val) = @_;\n"+"       pugs::guts::eval_apply('sub ($x is rw, $y) { $$x = $y;\n"+oRZ"                                                     warn $x\n"+"                               }', $$self, $val) }\n\n"++"package pugs::handle;\n"++"our $AUTOLOAD;\n"+"sub AUTOLOAD { my $type = $AUTOLOAD; $type =~ s/.*:://;\n"+"               warn 'unhandled support type: '.$type } \n"++"sub TIEHANDLE {\n"+"       my ($class, $val) = @_;\n"+"       bless \\$val, $class; }\n\n"++"sub DEREF { ${$_[0]} }\n"++"sub PRINT {\n"+"       my ($self, @vals) = shift;\n"+"       pugs::guts::eval_apply('sub ($x, *@y) { $x.print(@y) }', $$self, @vals) }\n"++"sub READLINE {\n"+"       my ($self) = @_;\n"+"       pugs::guts::eval_apply('sub ($x) { ~($x.readline);\n"+oRZ"                                                     warn $x\n"+"                               }', $$self) }\n\n"++"sub GETC {\n"+"       my ($self) = @_;\n"+"       pugs::guts::eval_apply('sub ($x) { ~($x.getc);\n"+oRZ"                                                     warn $x\n"+"                               }', $$self) }\n\n"++oRZ"warn 'compiled';\n"+"1;\n";++XS(_pugs_guts_invoke) {+    Val *val, *inv, **stack;+    SV *ret, *sv;+    int i;+    dXSARGS;+    if (items < 1) {+      hate;+    }++    sv = ST(0);+    if (sv_isa(sv, "pugs")) {+        val = pugs_SvToVal(ST(0));+    }+    else {+        char *method, *fullname;+        fullname = SvPV_nolen(sv);+        method = strrchr(fullname, ':');+        method = method ? method+1 : fullname;+        val = pugs_PvnToVal(method, strlen(method));+    }+    inv = SvOK(ST(1)) ? pugs_SvToVal(ST(1)) : NULL;++    New(6, stack, items, Val*);++    for (i = 2; i < items; ++i) {+        stack[i-2] = pugs_SvToVal(ST(i));+    }+    stack[i-2] = NULL;+    +    ST(0) = pugs_Apply(val, inv, stack, GIMME_V);+    /* sv_dump (ret); */+    Safefree(stack);+    +    XSRETURN(1);+}+++XS(_pugs_guts_eval_apply) {+    Val *val, *inv, **stack;+    int i;+    dXSARGS;+    if (items < 1) {+        hate;+    }++    val = pugs_Eval(SvPV_nolen(ST(0)));++    New(6, stack, items, Val*);++    for (i = 1; i < items; ++i) {+#if PERL5_EMBED_DEBUG+        fprintf(stderr, "put into stack: %s\n", SvPV_nolen(ST(i)));+#endif+        stack[i-1] = pugs_SvToVal(ST(i));+    }+    stack[i-1] = NULL;+    +    ST(0) = pugs_Apply(val, NULL, stack, GIMME_V);+    Safefree(stack);+    +    XSRETURN(1);+}+++#ifdef HAS_PROCSELFEXE+/* This is a function so that we don't hold on to MAXPATHLEN+   bytes of stack longer than necessary+ */+STATIC void+S_procself_val(pTHX_ SV *sv, char *arg0)+{+    char buf[MAXPATHLEN];+    int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);++    /* On Playstation2 Linux V1.0 (kernel 2.2.1) readlink(/proc/self/exe)+       includes a spurious NUL which will cause $^X to fail in system+       or backticks (this will prevent extensions from being built and+       many tests from working). readlink is not meant to add a NUL.+       Normal readlink works fine.+     */+    if (len > 0 && buf[len-1] == '\0') {+      len--;+    }++    /* FreeBSD's implementation is acknowledged to be imperfect, sometimes+       returning the text "unknown" from the readlink rather than the path+       to the executable (or returning an error from the readlink).  Any valid+       path has a '/' in it somewhere, so use that to validate the result.+       See http://www.freebsd.org/cgi/query-pr.cgi?pr=35703+    */+    if (len > 0 && memchr(buf, '/', len)) {+        sv_setpvn(sv,buf,len);+    }+    else {+        sv_setpv(sv,arg0);+    }+}+#endif /* HAS_PROCSELFEXE */++#    if defined(__APPLE__)+#      include <crt_externs.h>  /* for the env array */+#      define p5embed_environ (*_NSGetEnviron())+#    else+#      define p5embed_environ environ+#    endif++PerlInterpreter *+perl5_init ( int argc, char **argv )+{+    int exitstatus;+    int i;++#ifdef PERL_GPROF_MONCONTROL+    PERL_GPROF_MONCONTROL(0);+#endif+#ifdef PERL_SYS_INIT3+    PERL_SYS_INIT3(&argc,&argv,&p5embed_environ);+#endif++#if (defined(USE_5005THREADS) || defined(USE_ITHREADS)) && defined(HAS_PTHREAD_ATFORK)+    /* XXX Ideally, this should really be happening in perl_alloc() or+     * perl_construct() to keep libperl.a transparently fork()-safe.+     * It is currently done here only because Apache/mod_perl have+     * problems due to lack of a call to cancel pthread_atfork()+     * handlers when shared objects that contain the handlers may+     * be dlclose()d.  This forces applications that embed perl to+     * call PTHREAD_ATFORK() explicitly, but if and only if it hasn't+     * been called at least once before in the current process.+     * --GSAR 2001-07-20 */+    PTHREAD_ATFORK(Perl_atfork_lock,+                   Perl_atfork_unlock,+                   Perl_atfork_unlock);+#endif++    if (!PL_do_undump) {+        my_perl = perl_alloc();+        if (!my_perl)+            exit(1);+        perl_construct( my_perl );+        PL_perl_destruct_level = 0;+    }+#ifdef PERL_EXIT_DESTRUCT_END+    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;+#endif /* PERL_EXIT_DESTRUCT_END */+#ifdef PERL_EXIT_EXPECTED+    PL_exit_flags |= PERL_EXIT_EXPECTED;+#endif /* PERL_EXIT_EXPECTED */++#if (defined(CSH) && defined(PL_cshname))+    if (!PL_cshlen)+      PL_cshlen = strlen(PL_cshname);+#endif++    exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL);++    if (exitstatus == 0)+        exitstatus = perl_run( my_perl );++    _P5EMBED_INIT = 1;++    newXS((char*) "pugs::guts::invoke", _pugs_guts_invoke, (char*)__FILE__);+    newXS((char*) "pugs::guts::eval_apply", _pugs_guts_eval_apply, (char*)__FILE__);++#if PERL5_EMBED_DEBUG+    fprintf(stderr, "(%s)", pugs_guts_code);+#endif+    eval_pv(pugs_guts_code, TRUE);++    if (SvTRUE(ERRSV)) {+        STRLEN n_a;+        printf("Error init perl: %s\n", SvPV(ERRSV,n_a));+        exit(1);+    }+    return my_perl;+}++char *+perl5_SvPV ( SV *sv )+{+    char *rv;+    rv = SvPV_nolen(sv);+    return rv;+}++int+perl5_SvIV ( SV *sv )+{+    return((int)SvIV(sv));+}++double+perl5_SvNV ( SV *sv )+{+    return((double)SvNV(sv));+}++bool+perl5_SvTRUE ( SV * sv )+{+    bool rv;+    rv = SvTRUE(sv);+    return(rv ? 1 : 0);+}++bool+perl5_SvROK ( SV * sv )+{+    bool rv;+    sv_dump(sv);+    rv = SvROK(sv);+    return(rv ? 1 : 0);+}++SV *+perl5_sv_undef ()+{+    return(&PL_sv_undef);+}++SV *+perl5_newSVpvn ( char * pv, int len )+{+    SV *sv = newSVpvn(pv, len);+#ifdef SvUTF8_on+    SvUTF8_on(sv);+#endif+    return(sv);+}++SV *+perl5_newSViv ( int iv )+{+    return(newSViv(iv));+}++SV *+perl5_newSVnv ( double iv )+{+    return(newSVnv(iv));+}++SV **+perl5_apply(SV *sub, SV *inv, SV** args, void *env, int cxt)+{+    SV **arg;+    SV **out;+    SV *rv;+    SV *sv;+    void *old_env = pugs_getenv();+    int count, i;++    dSP;++    ENTER;+    SAVETMPS;++    pugs_setenv(env);++    PUSHMARK(SP);+    if (inv != NULL) {+        XPUSHs(inv);+    }+    for (arg = args; *arg != NULL; arg++) {+        XPUSHs(*arg);+    }+    PUTBACK;++    if (inv != NULL) {+        count = call_method(SvPV_nolen(sub), cxt|G_EVAL);+    }+    else {+        count = call_sv(sub, cxt|G_EVAL);+    }++    SPAGAIN;++    if (SvTRUE(ERRSV)) {+        Newz(42, out, 3, SV*);+        if (SvROK(ERRSV)) {+            out[0] = newSVsv(ERRSV);+            out[1] = NULL;+        }+        else {+            out[0] = ERRSV;+            out[1] = ERRSV; /* for Haskell-side to read PV */+        }+        out[2] = NULL;+    }+    else {+        Newz(42, out, count+2, SV*);++        out[0] = NULL;++        for (i=count; i>0; --i) {+            out[i] = newSVsv(POPs);+        }+        out[count+1] = NULL;+    }++    PUTBACK;+    FREETMPS;+    LEAVE;++    pugs_setenv(old_env);+    return out;+}++SV *+perl5_get_sv(const char *name)+{+    SV *sv = get_sv(name, 1);+    /* sv_dump(sv); */+    return sv;+}++SV *+perl5_eval(char *code, void *env, int cxt)+{+    dSP;+    SV* sv;+    void *old_env = pugs_getenv();++    ENTER;+    SAVETMPS;++    pugs_setenv(env);++    sv = newSVpv(code, 0);+#ifdef SvUTF8_on+    SvUTF8_on(sv);+#endif+    eval_sv(sv, cxt);+    SvREFCNT_dec(sv);++    SPAGAIN;+    sv = POPs;+    SvREFCNT_inc(sv);+    PUTBACK;++    if (SvTRUE(ERRSV)) {+        STRLEN n_a;+        fprintf(stderr, "Error eval perl5: \"%s\"\n*** %s\n", code, SvPV(ERRSV,n_a));+    }++    FREETMPS;+    LEAVE;++    pugs_setenv(old_env);+    return sv;+}++bool+perl5_can(SV *inv, char *subname)+{+    int rv;++    dSP;++    ENTER;+    SAVETMPS;++    PUSHMARK(SP);+    XPUSHs(inv);+    XPUSHs(newSVpv(subname, 0));+    PUTBACK;++    call_pv("UNIVERSAL::can", G_SCALAR);++    SPAGAIN;++    rv = (POPi != 0);+    /* printf("Checking: %s->can(%s), ret %d\n", SvPV_nolen(inv), subname, rv); */++    PUTBACK;+    FREETMPS;+    LEAVE;++    return rv;+}++void perl5_finalize ( SV* sv )+{+    SvREFCNT_dec(sv);+}
src/Pugs/Embed/Perl5.hs view
@@ -186,7 +186,8 @@ import Foreign.C.Types import Foreign.C.String import {-# SOURCE #-} Pugs.AST.Internals-import qualified UTF8 as Str+import qualified Data.ByteString.UTF8 as Str+import qualified Data.ByteString.Char8 as Buf import qualified Pugs.Val as Val  type PerlInterpreter = Ptr ()@@ -295,10 +296,10 @@ svUndef = perl5_sv_undef  vstrToSV :: String -> IO PerlSV-vstrToSV str = Str.useAsCStringLen (cast str) $ \(cstr, len) -> perl5_newSVpvn cstr (toEnum len)+vstrToSV str = Buf.useAsCStringLen (cast str) $ \(cstr, len) -> perl5_newSVpvn cstr (toEnum len)  bufToSV :: ByteString -> IO PerlSV-bufToSV str = Str.useAsCStringLen str $ \(cstr, len) -> perl5_newSVpvn cstr (toEnum len)+bufToSV str = Buf.useAsCStringLen str $ \(cstr, len) -> perl5_newSVpvn cstr (toEnum len)  vintToSV :: (Integral a) => a -> IO PerlSV vintToSV int = perl5_newSViv (fromIntegral int)@@ -329,7 +330,7 @@                 return $ Perl5ErrorString str              canPerl5 :: PerlSV -> ByteString -> IO Bool-canPerl5 sv meth = Str.useAsCString meth $ \cstr -> perl5_can sv cstr+canPerl5 sv meth = Buf.useAsCString meth $ \cstr -> perl5_can sv cstr  mkSV :: IO PerlSV -> IO PerlSV mkSV action = action@@ -341,7 +342,7 @@ -}  evalPerl5 :: String -> PugsEnv -> CInt -> IO PerlSV-evalPerl5 str env cxt = mkSV $ Str.useAsCString (cast str) $ \cstr -> perl5_eval cstr env cxt+evalPerl5 str env cxt = mkSV $ Buf.useAsCString (cast str) $ \cstr -> perl5_eval cstr env cxt  freePerl5 :: PerlInterpreter -> IO () freePerl5 my_perl = do
src/Pugs/Prim/Match.hs view
@@ -9,6 +9,7 @@ import Pugs.Types import Pugs.Config import Pugs.Prim.Code+import Paths_Pugs import qualified Data.Map as Map import qualified Data.Array as Array import qualified Pugs.Prim.FileTest as FileTest@@ -31,10 +32,7 @@  doMatch :: String -> VRule -> Eval VMatch doMatch cs rule@MkRulePGE{ rxRule = ruleStr } = do-    let pwd1 = getConfig "installsitelib" ++ "/auto/pugs/perl5/lib"-        pwd2 = getConfig "sourcedir" ++ "/perl5/Pugs-Compiler-Rule/lib"-    hasSrc <- io $ doesDirectoryExist pwd2-    let pwd = if hasSrc then pwd2 else pwd1+    pwd     <- io $ getDataFileName "blib6/pugs/perl5/lib"     glob    <- askGlobal     let syms = [ (cast $ v_name var, entry)                | (var, entry) <- padToList glob
src/Pugs/Run/Perl5.hs view
@@ -1,4 +1,4 @@-{-# OPTIONS_GHC -fglasgow-exts -cpp -fno-warn-unused-binds -fno-warn-unused-imports -fallow-overlapping-instances #-}+{-# OPTIONS_GHC -fglasgow-exts -cpp -fno-warn-unused-binds -fno-warn-unused-imports -fallow-overlapping-instances -optc-DSTABLE_H -optc-w #-}  module Pugs.Run.Perl5 () where 
src/Pugs/Shell.hs view
@@ -45,7 +45,7 @@ -- parse the input and return the corresponding command getCommand :: Input Command getCommand = do-    input <- liftM (fmap encodeUTF8) $ getInputLine "pugs> " +    input <- fmap (fmap encodeUTF8) $ getInputLine "pugs> "      doCommand input  doCommand :: Maybe String -> Input Command@@ -75,7 +75,7 @@ initializeShell f = (`runInputT` f) =<< pugsSettings  readline :: String -> IO (Maybe String)-readline prompt = (`runInputT` liftM (fmap encodeUTF8) (getInputLine prompt)) =<< pugsSettings+readline prompt = (`runInputT` fmap (fmap encodeUTF8) (getInputLine prompt)) =<< pugsSettings  pugsSettings :: IO (Settings IO) pugsSettings = do
src/Pugs/Version.hs view
@@ -14,10 +14,10 @@ -- #include "pugs_version.h"  #ifndef PUGS_VERSION-#define PUGS_VERSION "6.2.13.8"+#define PUGS_VERSION "6.2.13.9" #endif #ifndef PUGS_DATE-#define PUGS_DATE "July 19, 2008"+#define PUGS_DATE "July 25, 2008" #endif #ifndef PUGS_SVN_REVISION #define PUGS_SVN_REVISION 0