# Do not edit this file - Generated by Perlito5 9.025

{
    package main;
    package Perlito5::Grammar::String;
    use Perlito5::Grammar::Precedence ;
    sub Perlito5::Grammar::String::term_q_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((do {
            my $tmp100 = $MATCH->{"to"};
            (((("q" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                my $tmp101 = $MATCH->{"to"};
                ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp101, ((do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                    if ($m2) {
                        $MATCH->{"to"} = $m2->{"to"};
                        1
                    }
                    else {;
                        0
                    }
                }) && (do {
                    my $tmp = $MATCH;
                    $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                    my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                    $MATCH = $tmp;
                    $res ? 0 : 1
                }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
            }))) || ($MATCH->{"to"} = $tmp100, (("'" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::q_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"q_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"q_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_qq_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((do {
            my $tmp112 = $MATCH->{"to"};
            (((("q" eq $str->[($MATCH->{"to"}) + 0]) && ("q" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2)) && (do {
                my $tmp113 = $MATCH->{"to"};
                ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp113, ((do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                    if ($m2) {
                        $MATCH->{"to"} = $m2->{"to"};
                        1
                    }
                    else {;
                        0
                    }
                }) && (do {
                    my $tmp = $MATCH;
                    $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                    my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                    $MATCH = $tmp;
                    $res ? 0 : 1
                }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
            }))) || ($MATCH->{"to"} = $tmp112, (("\"" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::qq_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"qq_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"qq_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_qw_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((("q" eq $str->[($MATCH->{"to"}) + 0]) && ("w" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2)) && (do {
            my $tmp124 = $MATCH->{"to"};
            ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp124, ((do {
                my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    1
                }
                else {;
                    0
                }
            }) && (do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                $MATCH = $tmp;
                $res ? 0 : 1
            }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::qw_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"qw_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"qw_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_m_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((do {
            my $tmp134 = $MATCH->{"to"};
            (((("m" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                my $tmp135 = $MATCH->{"to"};
                ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp135, ((do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                    if ($m2) {
                        $MATCH->{"to"} = $m2->{"to"};
                        1
                    }
                    else {;
                        0
                    }
                }) && (do {
                    my $tmp = $MATCH;
                    $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                    my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                    $MATCH = $tmp;
                    $res ? 0 : 1
                }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
            }))) || ($MATCH->{"to"} = $tmp134, (("/" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::m_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"m_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"m_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_s_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((("s" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
            my $tmp146 = $MATCH->{"to"};
            ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp146, ((do {
                my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    1
                }
                else {;
                    0
                }
            }) && (do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                $MATCH = $tmp;
                $res ? 0 : 1
            }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::s_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"s_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"s_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_qx {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((do {
            my $tmp156 = $MATCH->{"to"};
            (((("q" eq $str->[($MATCH->{"to"}) + 0]) && ("x" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2)) && (do {
                my $tmp157 = $MATCH->{"to"};
                ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp157, ((do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                    if ($m2) {
                        $MATCH->{"to"} = $m2->{"to"};
                        1
                    }
                    else {;
                        0
                    }
                }) && (do {
                    my $tmp = $MATCH;
                    $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                    my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                    $MATCH = $tmp;
                    $res ? 0 : 1
                }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
            }))) || ($MATCH->{"to"} = $tmp156, (("`" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::qx_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"qx_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"qx_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_glob {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((("<" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
            my $m2 = Perlito5::Grammar::String::glob_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"glob_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"glob_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_tr_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((do {
            my $tmp173 = $MATCH->{"to"};
            ((("t" eq $str->[($MATCH->{"to"}) + 0]) && ("r" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2))) || ($MATCH->{"to"} = $tmp173, (("y" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)))
        }) && (do {
            my $tmp174 = $MATCH->{"to"};
            ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp174, ((do {
                my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    1
                }
                else {;
                    0
                }
            }) && (do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                $MATCH = $tmp;
                $res ? 0 : 1
            }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::tr_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"tr_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"tr_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::term_qr_quote {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = (((("q" eq $str->[($MATCH->{"to"}) + 0]) && ("r" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2)) && (do {
            my $tmp185 = $MATCH->{"to"};
            ((("#" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) || ($MATCH->{"to"} = $tmp185, ((do {
                my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    1
                }
                else {;
                    0
                }
            }) && (do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = (("=" eq $str->[($MATCH->{"to"}) + 0]) && (">" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2));
                $MATCH = $tmp;
                $res ? 0 : 1
            }) && ('' ne $str->[$MATCH->{"to"}] && ++$MATCH->{"to"})))
        }) && (do {
            my $m2 = Perlito5::Grammar::String::qr_quote_parse($str, $MATCH->{"to"});
            if ($m2) {
                $MATCH->{"to"} = $m2->{"to"};
                $MATCH->{"qr_quote_parse"} = $m2;
                1
            }
            else {;
                0
            }
        }) && (do {
            $MATCH->{"capture"} = ["term", Perlito5::Match::flat($MATCH->{"qr_quote_parse"})];
            1
        })));
        $tmp ? $MATCH : undef
    }
    our $unicode_table;
    sub Perlito5::Grammar::String::get_unicode_table {
        !$unicode_table && ($unicode_table = Perlito5::Grammar::Use::slurp_file("unicore/UnicodeData.txt"));
        return $unicode_table
    }
    my %pair = ("{", "}", "(", ")", "[", "]", "<", ">");
    my %escape_sequence = ("a", 7, "b", 8, "e", 27, "f", 12, "n", 10, "r", 13, "t", 9);
    my %hex = map(+($_, 1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F");
    my %octal = map(+($_, 1), 0, 1, 2, 3, 4, 5, 6, 7);
    sub Perlito5::Grammar::String::q_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($delimiter = $pair{$delimiter});
        return Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $delimiter, 0)
    }
    sub Perlito5::Grammar::String::qq_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($delimiter = $pair{$delimiter});
        return Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $delimiter, 1)
    }
    sub Perlito5::Grammar::String::qw_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($delimiter = $pair{$delimiter});
        my $m = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $delimiter, 0);
        if ($m) {;
            $m->{"capture"} = Perlito5::AST::Apply::->new("code", "list:<,>", "arguments", [map(Perlito5::AST::Buf::->new("buf", $_), split(" ", Perlito5::Match::flat($m)->{"buf"}))], "namespace", '')
        }
        return $m
    }
    sub Perlito5::Grammar::String::m_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        my $closing_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter});
        my $interpolate = 2;
        $delimiter eq "'" && ($interpolate = 3);
        my $part1 = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $closing_delimiter, $interpolate);
        $part1 || return $part1;
        my $str_regex = $part1->{"capture"};
        my $p = $part1->{"to"};
        my $modifiers = '';
        my $m = Perlito5::Grammar::ident($str, $p);
        if ($m) {
            $modifiers = Perlito5::Match::flat($m);
            $part1->{"to"} = $m->{"to"}
        }
        $part1->{"capture"} = Perlito5::AST::Apply::->new("code", "p5:m", "arguments", [$str_regex, Perlito5::AST::Buf::->new("buf", $modifiers), Perlito5::AST::Var::SCALAR_ARG()], "namespace", '');
        return $part1
    }
    sub Perlito5::Grammar::String::s_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        my $closing_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter});
        my $interpolate = 2;
        $delimiter eq "'" && ($interpolate = 3);
        my $part1 = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $closing_delimiter, $interpolate);
        $part1 || return $part1;
        my $str_regex = Perlito5::Match::flat($part1);
        my $part2;
        my $m;
        my $p = $part1->{"to"};
        if (exists($pair{$delimiter})) {
            $m = Perlito5::Grammar::Space::opt_ws($str, $p);
            $p = $m->{"to"};
            $delimiter = $str->[$p];
            $open_delimiter = $delimiter;
            $p++;
            $closing_delimiter = $delimiter;
            exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter})
        }
        $part2 = Perlito5::Grammar::String::string_interpolation_parse($str, $p, $open_delimiter, $closing_delimiter, 0);
        $part2 || return $part2;
        my @replace = @{$str}[$p .. ($part2->{"to"}) - 2];
        my $replace;
        $p = $part2->{"to"};
        my $modifiers = '';
        $m = Perlito5::Grammar::ident($str, $p);
        if ($m) {;
            $modifiers = Perlito5::Match::flat($m)
        }
        if ($modifiers =~ m/e/) {
            my $m = Perlito5::Grammar::block(["{", @replace, "}"], 0);
            if (!$m) {;
                Perlito5::Compiler::error("syntax error")
            }
            $replace = Perlito5::Match::flat($m);
            if ($modifiers =~ m/ee/) {;
                $replace = Perlito5::AST::Block::->new("sig", undef, "stmts", [Perlito5::AST::Apply::->new("code", "eval", "arguments", [Perlito5::AST::Apply::->new("code", "do", "arguments", [$replace])], "bareword", '', "namespace", '')])
            }
        }
        else {
            $interpolate = 1;
            $delimiter eq chr(39) && ($interpolate = 3);
            my $m = Perlito5::Grammar::String::string_interpolation_parse([$open_delimiter, @replace, $closing_delimiter], 1, $open_delimiter, $closing_delimiter, $interpolate);
            if (!$m) {;
                Perlito5::Compiler::error("syntax error")
            }
            $replace = Perlito5::Match::flat($m)
        }
        if ($m) {;
            $part2->{"to"} = $m->{"to"}
        }
        $part2->{"capture"} = Perlito5::AST::Apply::->new("code", "p5:s", "arguments", [$str_regex, $replace, Perlito5::AST::Buf::->new("buf", $modifiers), Perlito5::AST::Var::SCALAR_ARG()], "namespace", '');
        return $part2
    }
    sub Perlito5::Grammar::String::qr_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        my $closing_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter});
        my $interpolate = 2;
        $delimiter eq "'" && ($interpolate = 3);
        my $part1 = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $closing_delimiter, $interpolate);
        $part1 || return $part1;
        my $str_regex = $part1->{"capture"};
        my $p = $part1->{"to"};
        my $modifiers = '';
        my $m = Perlito5::Grammar::ident($str, $p);
        if ($m) {
            $modifiers = Perlito5::Match::flat($m);
            $part1->{"to"} = $m->{"to"}
        }
        $part1->{"capture"} = Perlito5::AST::Apply::->new("code", "p5:qr", "arguments", [$str_regex, Perlito5::AST::Buf::->new("buf", $modifiers)], "namespace", '');
        return $part1
    }
    sub Perlito5::Grammar::String::qx_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($delimiter = $pair{$delimiter});
        my $m = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $delimiter, 0);
        if ($m) {;
            $m->{"capture"} = Perlito5::AST::Apply::->new("code", "qx", "arguments", [Perlito5::Match::flat($m)], "namespace", '')
        }
        return $m
    }
    sub Perlito5::Grammar::String::glob_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($delimiter = $pair{$delimiter});
        if ($str->[$pos] eq "<" && $str->[$pos + 1] eq ">" && $str->[$pos + 2] eq ">") {;
            return {"str" => $str, "from" => $pos, "to" => $pos + 3, "capture" => Perlito5::AST::Apply::->new("code", "readline", "arguments", [Perlito5::AST::Apply::->new("code", "<>", "arguments", [], "namespace", '', "bareword", 1)], "namespace", ''), }
        }
        if ($str->[$pos] eq ">") {;
            return {"str" => $str, "from" => $pos, "to" => $pos + 1, "capture" => Perlito5::AST::Apply::->new("code", "readline", "arguments", [], "namespace", ''), }
        }
        my $p = $pos;
        my $sigil = "::";
        if ($str->[$p] eq "\$") {
            $sigil = "\$";
            $p++
        }
        my $m_namespace = Perlito5::Grammar::optional_namespace_before_ident($str, $p);
        my $namespace = Perlito5::Match::flat($m_namespace);
        $p = $m_namespace->{"to"};
        my $m_name = Perlito5::Grammar::ident($str, $p);
        if ($m_name && $str->[$m_name->{"to"}] eq ">") {
            if ($sigil eq "::") {;
                return {"str" => $str, "from" => $pos, "to" => ($m_name->{"to"}) + 1, "capture" => Perlito5::AST::Apply::->new("code", "readline", "arguments", [Perlito5::AST::Apply::->new("code", Perlito5::Match::flat($m_name), "arguments", [], "namespace", $namespace, "bareword", 1)], "namespace", ''), }
            }
            return {"str" => $str, "from" => $pos, "to" => ($m_name->{"to"}) + 1, "capture" => Perlito5::AST::Apply::->new("code", "readline", "arguments", [Perlito5::AST::Var::->new("sigil", $sigil, "name", Perlito5::Match::flat($m_name), "namespace", $namespace)], "namespace", ''), }
        }
        my $m = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $delimiter, 1);
        if ($m) {;
            $m->{"capture"} = Perlito5::AST::Apply::->new("code", "glob", "arguments", [Perlito5::Match::flat($m)], "namespace", '')
        }
        return $m
    }
    sub Perlito5::Grammar::String::tr_quote_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $str->[$pos - 1];
        my $open_delimiter = $delimiter;
        my $closing_delimiter = $delimiter;
        exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter});
        my $interpolate = 2;
        $delimiter eq "'" && ($interpolate = 3);
        my $part1 = Perlito5::Grammar::String::string_interpolation_parse($str, $pos, $open_delimiter, $closing_delimiter, $interpolate);
        $part1 || return $part1;
        my $str_regex = Perlito5::Match::flat($part1);
        my $part2;
        my $m;
        my $p = $part1->{"to"};
        if (exists($pair{$delimiter})) {
            $m = Perlito5::Grammar::Space::opt_ws($str, $p);
            $p = $m->{"to"};
            $delimiter = $str->[$p];
            my $open_delimiter = $delimiter;
            $p++;
            $closing_delimiter = $delimiter;
            exists($pair{$delimiter}) && ($closing_delimiter = $pair{$delimiter});
            $interpolate = 2;
            $delimiter eq "'" && ($interpolate = 3);
            $part2 = Perlito5::Grammar::String::string_interpolation_parse($str, $p, $open_delimiter, $closing_delimiter, $interpolate);
            $part2 || return $part2
        }
        else {
            $part2 = Perlito5::Grammar::String::string_interpolation_parse($str, $p, $open_delimiter, $closing_delimiter, $interpolate);
            $part2 || return $part2
        }
        $p = $part2->{"to"};
        my $modifiers = '';
        $m = Perlito5::Grammar::ident($str, $p);
        if ($m) {
            $modifiers = Perlito5::Match::flat($m);
            $part2->{"to"} = $m->{"to"}
        }
        $part2->{"capture"} = Perlito5::AST::Apply::->new("code", "p5:tr", "arguments", [$str_regex, Perlito5::Match::flat($part2), Perlito5::AST::Buf::->new("buf", $modifiers), Perlito5::AST::Var::SCALAR_ARG()], "namespace", '');
        return $part2
    }
    sub Perlito5::Grammar::String::apply_quote_flags {
        (my $c, my $quote_flags) = @_;
        length($c) || return $c;
        if ($quote_flags->{"l"}) {
            $c = lcfirst($c);
            delete($quote_flags->{"l"})
        }
        if ($quote_flags->{"u"}) {
            $c = ucfirst($c);
            delete($quote_flags->{"u"})
        }
        $quote_flags->{"L"} && ($c = lc($c));
        $quote_flags->{"U"} && ($c = uc($c));
        $quote_flags->{"Q"} && ($c = quotemeta($c));
        return $c
    }
    sub Perlito5::Grammar::String::string_interpolation_parse {
        my $str = $_[0];
        my $pos = $_[1];
        my $open_delimiter = $_[2];
        my $delimiter = $_[3];
        my $interpolate = $_[4];
        my $quote_flags = $_[5] || {};
        my $interpolate_vars = ($interpolate == 1 || $interpolate == 2);
        my $p = $pos;
        my $balanced = $open_delimiter && exists($pair{$open_delimiter});
        my @args;
        my $buf = '';
        my $d1 = substr($delimiter, 0, 1);
        while ($p < @{$str} && !($str->[$p] eq $d1 && join('', @{$str}[$p .. ($p + length($delimiter)) - 1]) eq $delimiter)) {
            my $c = $str->[$p];
            my $c2 = $str->[$p + 1];
            my $m;
            my $more = '';
            if ($c eq "\\" && $c2 eq $delimiter) {
                $p++;
                $c = $c2
            }
            elsif ($balanced && $c eq "\\" && ($c2 eq $open_delimiter || $c2 eq $delimiter)) {
                $p++;
                $c = $c2
            }
            elsif ($balanced && $c eq $open_delimiter) {
                $buf .= $c;
                $p++;
                $m = Perlito5::Grammar::String::string_interpolation_parse($str, $p, $open_delimiter, $delimiter, $interpolate, $quote_flags);
                $more = $delimiter
            }
            elsif ($interpolate_vars && ($c eq "\$" || $c eq "\@")) {
                my $match = Perlito5::Grammar::String::double_quoted_var($str, $p, $delimiter, $interpolate);
                if ($match) {
                    my $ast = $match->{"capture"};
                    if ($quote_flags->{"l"}) {
                        $ast = Perlito5::AST::Apply::->new("namespace", '', "code", "lcfirst", "arguments", [$ast]);
                        delete($quote_flags->{"l"})
                    }
                    if ($quote_flags->{"u"}) {
                        $ast = Perlito5::AST::Apply::->new("namespace", '', "code", "ucfirst", "arguments", [$ast]);
                        delete($quote_flags->{"u"})
                    }
                    $quote_flags->{"L"} && ($ast = Perlito5::AST::Apply::->new("namespace", '', "code", "lc", "arguments", [$ast]));
                    $quote_flags->{"U"} && ($ast = Perlito5::AST::Apply::->new("namespace", '', "code", "uc", "arguments", [$ast]));
                    $quote_flags->{"Q"} && ($ast = Perlito5::AST::Apply::->new("namespace", '', "code", "quotemeta", "arguments", [$ast]));
                    $match->{"capture"} = $ast
                }
                $m = $match
            }
            elsif ($c eq "\\") {
                if ($interpolate) {
                    if ($c2 eq "E") {
                        my $flag_to_reset = $quote_flags->{"last_flag"};
                        if ($flag_to_reset) {
                            delete($quote_flags->{$flag_to_reset});
                            delete($quote_flags->{"last_flag"})
                        }
                        else {;
                            $quote_flags = {}
                        }
                        $p += 1;
                        $c = ''
                    }
                    elsif ($c2 eq "L") {
                        $quote_flags->{$c2} = 1;
                        delete($quote_flags->{"U"});
                        $quote_flags->{"last_flag"} = $c2;
                        $p += 1;
                        $c = ''
                    }
                    elsif ($c2 eq "U") {
                        $quote_flags->{$c2} = 1;
                        delete($quote_flags->{"L"});
                        $quote_flags->{"last_flag"} = $c2;
                        $p += 1;
                        $c = ''
                    }
                    elsif ($c2 eq "Q") {
                        $quote_flags->{$c2} = 1;
                        $quote_flags->{"last_flag"} = $c2;
                        $p += 1;
                        $c = ''
                    }
                    elsif ($c2 eq "l") {
                        $quote_flags->{"u"} || ($quote_flags->{$c2} = 1);
                        $p += 1;
                        $c = ''
                    }
                    elsif ($c2 eq "u") {
                        $quote_flags->{"l"} || ($quote_flags->{$c2} = 1);
                        $p += 1;
                        $c = ''
                    }
                }
                if ($c) {
                    if ($interpolate == 2) {;
                        $m = {"str" => $str, "from" => $p, "to" => $p + 2, "capture" => Perlito5::AST::Buf::->new("buf", ($str->[$p]) . ($str->[$p + 1])), }
                    }
                    elsif ($interpolate == 1) {;
                        $m = Perlito5::Grammar::String::double_quoted_unescape($str, $p)
                    }
                    else {;
                        $m = $c2 eq "\\" ? {"str" => $str, "from" => $p, "to" => $p + 2, "capture" => Perlito5::AST::Buf::->new("buf", "\\"), } : $c2 eq "'" ? {"str" => $str, "from" => $p, "to" => $p + 2, "capture" => Perlito5::AST::Buf::->new("buf", "'"), } : 0
                    }
                }
            }
            if ($m) {
                my $obj = Perlito5::Match::flat($m);
                if (ref($obj) eq "Perlito5::AST::Buf") {
                    $buf .= Perlito5::Grammar::String::apply_quote_flags($obj->{"buf"}, $quote_flags);
                    $obj = undef
                }
                if ($obj) {
                    if (length($buf)) {
                        push(@args, Perlito5::AST::Buf::->new("buf", $buf));
                        $buf = ''
                    }
                    push(@args, $obj)
                }
                $p = $m->{"to"};
                $buf .= $more
            }
            else {
                $p++;
                if ($c eq chr(10) || $c eq chr(13)) {
                    my $m = Perlito5::Grammar::String::here_doc($str, $p);
                    if ($p != $m->{"to"}) {;
                        $p = $m->{"to"}
                    }
                    else {;
                        $buf .= Perlito5::Grammar::String::apply_quote_flags($c, $quote_flags)
                    }
                }
                else {;
                    $buf .= Perlito5::Grammar::String::apply_quote_flags($c, $quote_flags)
                }
            }
        }
        if (length($buf)) {;
            push(@args, Perlito5::AST::Buf::->new("buf", $buf))
        }
        join('', @{$str}[$p .. ($p + length($delimiter)) - 1]) ne $delimiter && Perlito5::Compiler::error("Can't find string terminator '" . $delimiter . "' anywhere before EOF");
        $p += length($delimiter);
        my $ast;
        if (!@args) {;
            $ast = Perlito5::AST::Buf::->new("buf", '')
        }
        elsif (@args == 1 && ref($args[0]) eq "Perlito5::AST::Buf") {;
            $ast = $args[0]
        }
        else {
            @args == 1 && unshift(@args, Perlito5::AST::Buf::->new("buf", ''));
            $ast = Perlito5::AST::Apply::->new("namespace", '', "code", "list:<.>", "arguments", \@args, Perlito5::overloading_flag())
        }
        return {"str" => $str, "from" => $pos, "to" => $p, "capture" => $ast, }
    }
    our @Here_doc;
    sub Perlito5::Grammar::String::here_doc_wanted {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter;
        my $type = "double_quote";
        my $indented = 0;
        my $p = $pos;
        if ($str->[$p] eq "<" && $str->[$p + 1] eq "<") {
            $p += 2;
            my $quote = $str->[$p];
            if ($quote eq "~") {
                $indented = 1;
                $p++;
                $quote = $str->[$p]
            }
            if ($quote eq "'" || $quote eq "\"") {
                $p += 1;
                my $m = Perlito5::Grammar::String::string_interpolation_parse($_[0], $p, $quote, $quote, 0);
                if ($m) {
                    $p = $m->{"to"};
                    $delimiter = Perlito5::Match::flat($m)->{"buf"};
                    $type = $quote eq "'" ? "single_quote" : "double_quote"
                }
            }
            else {
                $quote eq "\\" && ($p += 1);
                my $m = Perlito5::Grammar::ident($str, $p);
                if ($m) {
                    $p = $m->{"to"};
                    $delimiter = Perlito5::Match::flat($m);
                    $type = $quote eq "\\" ? "single_quote" : "double_quote"
                }
                else {
                    $Perlito5::WARNINGS && warn("Use of bare << to mean <<\"\" is deprecated");
                    $delimiter = '';
                    $type = "double_quote"
                }
            }
        }
        if (!defined($delimiter)) {;
            return 0
        }
        my $placeholder = Perlito5::AST::Apply::->new("code", "list:<.>", "namespace", '', "arguments", [Perlito5::AST::Apply::->new("code", "list:<.>", "namespace", '', "arguments", [])]);
        push(@Here_doc, [$type, $placeholder->{"arguments"}->[0]->{"arguments"}, $delimiter, $indented]);
        return {"str" => $str, "from" => $pos, "to" => $p, "capture" => ["term", $placeholder], }
    }
    sub Perlito5::Grammar::String::newline {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = ((do {
            my $tmp314 = $MATCH->{"to"};
            (((("
" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                my $m = $MATCH;
                if (!(("\x{d}" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) {;
                    $MATCH = $m
                }
                1
            }))) || ($MATCH->{"to"} = $tmp314, ((("\x{d}" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                my $m = $MATCH;
                if (!(("
" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1))) {;
                    $MATCH = $m
                }
                1
            })))
        }));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::String::here_doc {
        my $str = $_[0];
        my $pos = $_[1];
        if (!@Here_doc) {;
            return {"str" => $str, "from" => $pos, "to" => $pos, }
        }
        my $p = $pos;
        my $here = shift(@Here_doc);
        my $type = $here->[0];
        my $result = $here->[1];
        my $delimiter = $here->[2];
        my $indented = $here->[3];
        while ($p < @{$str}) {
            my $spaces = '';
            my $p0 = $p;
            if ($indented) {
                while ($p < @{$str}) {
                    $str->[$p] ne " " && $str->[$p] ne "\x{9}" && last;
                    $p++
                }
                $spaces = join('', @{$str}[$p0 .. $p - 1])
            }
            if (join('', @{$str}[$p .. ($p + length($delimiter)) - 1]) eq $delimiter) {
                my $c = $str->[$p + length($delimiter)];
                if ($c eq '' || $c eq " " || $c eq "\x{9}" || $c eq chr(10) || $c eq chr(13)) {
                    my @here_string = split("
", join('', @{$str}[$pos .. $p - 1]), -1);
                    if (length($spaces)) {
                        my $l = length($spaces);
                        for my $i (0 .. $#here_string) {
                            if (substr($here_string[$i], 0, $l) eq $spaces) {;
                                $here_string[$i] = substr($here_string[$i], $l)
                            }
                            else {;
                                Perlito5::Compiler::error("Indentation on line " . $i . " of here-doc doesn't match delimiter")
                            }
                        }
                    }
                    if ($type eq "single_quote") {;
                        push(@{$result}, Perlito5::AST::Buf::->new("buf", join("
", @here_string)))
                    }
                    else {
                        my $m;
                        my $str = [split('', join("
", @here_string, $delimiter . "
"))];
                        $m = Perlito5::Grammar::String::string_interpolation_parse($str, 0, '', "
" . $delimiter . "
", 1);
                        if ($m) {;
                            push(@{$result}, Perlito5::Match::flat($m))
                        }
                        else {;
                            Perlito5::Compiler::error("Can't find string terminator \"" . $delimiter . "\" anywhere before EOF")
                        }
                    }
                    $p += length($delimiter);
                    my $m = Perlito5::Grammar::String::newline($str, $p);
                    if ($p >= @{$str} || $m) {
                        $m && ($p = $m->{"to"});
                        return {"str" => $str, "from" => $pos, "to" => $p - 1, }
                    }
                }
            }
            while ($p < @{$str} && ($str->[$p] ne chr(10) && $str->[$p] ne chr(13))) {;
                $p++
            }
            while ($p < @{$str} && ($str->[$p] eq chr(10) || $str->[$p] eq chr(13))) {;
                $p++
            }
        }
        Perlito5::Compiler::error("Can't find string terminator \"" . $delimiter . "\" anywhere before EOF")
    }
    sub Perlito5::Grammar::String::double_quoted_unescape {
        my $str = $_[0];
        my $pos = $_[1];
        my $c2 = $str->[$pos + 1];
        my $m;
        if (exists($escape_sequence{$c2})) {;
            $m = {"str" => $str, "from" => $pos, "to" => $pos + 2, "capture" => Perlito5::AST::Buf::->new("buf", chr($escape_sequence{$c2})), }
        }
        elsif ($c2 eq "c") {
            my $c3 = (ord(uc($str->[$pos + 2])) - ord("A")) + 1;
            $c3 < 0 && ($c3 = 128 + $c3);
            $m = {"str" => $str, "from" => $pos, "to" => $pos + 3, "capture" => Perlito5::AST::Buf::->new("buf", chr($c3)), }
        }
        elsif ($c2 eq "x") {
            if ($str->[$pos + 2] eq "{") {
                my $p = $pos + 3;
                $p++
                    while $p < @{$str} && $str->[$p] ne "}";
                my $hex_code = join('', @{$str}[$pos + 3 .. $p - 1]);
                $hex_code || ($hex_code = 0);
                my $tmp = oct("0x" . $hex_code);
                $m = {"str" => $str, "from" => $pos, "to" => $p + 1, "capture" => Perlito5::AST::Buf::->new("buf", chr($tmp)), }
            }
            else {
                my $p = $pos + 2;
                $hex{uc($str->[$p])} && $p++;
                $hex{uc($str->[$p])} && $p++;
                my $hex_code = join('', @{$str}[$pos + 2 .. $p - 1]);
                $hex_code || ($hex_code = 0);
                my $tmp = oct("0x" . $hex_code);
                $m = {"str" => $str, "from" => $pos, "to" => $p, "capture" => Perlito5::AST::Buf::->new("buf", chr($tmp)), }
            }
        }
        elsif (exists($octal{$c2})) {
            my $p = $pos + 1;
            $octal{$str->[$p]} && $p++;
            $octal{$str->[$p]} && $p++;
            $octal{$str->[$p]} && $p++;
            my $oct_code = join('', @{$str}[$pos + 1 .. $p - 1]);
            my $tmp = oct($oct_code);
            $m = {"str" => $str, "from" => $pos, "to" => $p, "capture" => Perlito5::AST::Buf::->new("buf", chr($tmp)), }
        }
        elsif ($c2 eq "N") {;
            if ($str->[$pos + 2] eq "{") {
                if ($str->[$pos + 3] eq "U" && $str->[$pos + 4] eq "+") {
                    my $p = $pos + 5;
                    $p++
                        while $p < @{$str} && $str->[$p] ne "}";
                    my $hex_code = join('', @{$str}[$pos + 5 .. $p - 1]);
                    $hex_code || ($hex_code = 0);
                    my $tmp = oct("0x" . $hex_code);
                    $m = {"str" => $str, "from" => $pos, "to" => $p + 1, "capture" => Perlito5::AST::Buf::->new("buf", chr($tmp)), }
                }
                else {
                    my $p = $pos + 3;
                    $p++
                        while $p < @{$str} && $str->[$p] ne "}";
                    my $name = join('', @{$str}[$pos + 3 .. $p - 1]);
                    (my $hex_code) = Perlito5::Grammar::String::get_unicode_table() =~ m/\n([0-9A-Z]+);$name;/;
                    !$hex_code && Perlito5::Compiler::error("Unknown charname '" . $name . "'");
                    my $tmp = oct("0x" . $hex_code);
                    $m = {"str" => $str, "from" => $pos, "to" => $p + 1, "capture" => Perlito5::AST::Buf::->new("buf", chr($tmp)), }
                }
            }
        }
        else {;
            $m = {"str" => $str, "from" => $pos, "to" => $pos + 2, "capture" => Perlito5::AST::Buf::->new("buf", $c2), }
        }
        return $m
    }
    sub Perlito5::Grammar::String::double_quoted_var_with_subscript {
        my $m_var = $_[0];
        my $interpolate = $_[1];
        my $str = $m_var->{"str"};
        my $pos = $m_var->{"to"};
        my $p = $pos;
        my $m_index;
        if ($str->[$p] eq "-" && $str->[$p + 1] eq ">" && $str->[$p + 2] eq "[") {
            $p += 3;
            $m_index = Perlito5::Grammar::Expression::list_parse($str, $p);
            $m_index || Perlito5::Compiler::error("syntax error");
            my $exp = $m_index->{"capture"};
            $p = $m_index->{"to"};
            ($exp eq "*undef*" || $str->[$p] ne "]") && Perlito5::Compiler::error("syntax error");
            $p++;
            $m_index->{"capture"} = Perlito5::AST::Call::->new("method", "postcircumfix:<[ ]>", "invocant", $m_var->{"capture"}, "arguments", $exp);
            $m_index->{"to"} = $p;
            return Perlito5::Grammar::String::double_quoted_var_with_subscript($m_index, $interpolate)
        }
        if ($str->[$p] eq "-" && $str->[$p + 1] eq ">" && $str->[$p + 2] eq "{") {
            $pos += 2;
            $m_index = Perlito5::Grammar::Expression::term_curly($str, $pos);
            $m_index || Perlito5::Compiler::error("syntax error");
            $m_index->{"capture"} = Perlito5::AST::Call::->new("method", "postcircumfix:<{ }>", "invocant", $m_var->{"capture"}, "arguments", Perlito5::Match::flat($m_index)->[2]->[0]);
            return Perlito5::Grammar::String::double_quoted_var_with_subscript($m_index, $interpolate)
        }
        if ($str->[$p] eq "[") {
            if ($interpolate == 2) {
                my $m = Perlito5::Grammar::Number::term_digit($str, $p + 1) || ($str->[$p + 1] eq "-" && Perlito5::Grammar::Number::term_digit($str, $p + 2)) || Perlito5::Grammar::Sigil::term_sigil($str, $p + 1);
                $m || return $m_var;
                $str->[$m->{"to"}] eq "]" || return $m_var
            }
            $p++;
            $m_index = Perlito5::Grammar::Expression::list_parse($str, $p);
            if ($m_index) {
                my $exp = $m_index->{"capture"};
                $p = $m_index->{"to"};
                if ($exp ne "*undef*" && $str->[$p] eq "]") {
                    $p++;
                    my $value = $m_var->{"capture"};
                    if (ref($value) eq "Perlito5::AST::Var") {;
                        $value->{"_real_sigil"} = "\@"
                    }
                    $m_index->{"capture"} = Perlito5::AST::Index::->new("obj", $value, "index_exp", $exp);
                    $m_index->{"to"} = $p;
                    return Perlito5::Grammar::String::double_quoted_var_with_subscript($m_index, $interpolate)
                }
            }
        }
        $m_index = Perlito5::Grammar::Expression::term_curly($str, $pos);
        if ($m_index) {
            my $value = $m_var->{"capture"};
            if (ref($value) eq "Perlito5::AST::Var") {;
                $value->{"_real_sigil"} = "%"
            }
            $m_index->{"capture"} = Perlito5::AST::Lookup::->new("obj", $value, "index_exp", Perlito5::Match::flat($m_index)->[2]->[0]);
            return Perlito5::Grammar::String::double_quoted_var_with_subscript($m_index, $interpolate)
        }
        return $m_var
    }
    sub Perlito5::Grammar::String::double_quoted_var {
        my $str = $_[0];
        my $pos = $_[1];
        my $delimiter = $_[2];
        my $interpolate = $_[3];
        my $c = $str->[$pos];
        my $c2 = $str->[$pos + 1];
        if ($c eq "\$" && $c2 eq ")") {;
            return 0
        }
        elsif ($c eq "\$" && $c2 eq "{") {
            my $m = Perlito5::Grammar::Sigil::term_sigil($str, $pos);
            $m || return $m;
            my $var = Perlito5::Match::flat($m)->[1];
            $m->{"capture"} = $var;
            return $m
        }
        elsif ($c eq "\$" && $c2 eq "\$" && !Perlito5::Grammar::word($str, $pos + 2)) {;
            return {"str" => $str, "capture" => Perlito5::AST::Var::->new("name", "\$", "sigil", "\$", "namespace", ''), "from" => $pos, "to" => $pos + 2, }
        }
        elsif ($c eq "\$" && join('', @{$str}[$pos + 1 .. $pos + length($delimiter)]) ne $delimiter) {
            my $m = Perlito5::Grammar::Sigil::term_sigil($str, $pos);
            $m || return $m;
            $m->{"capture"} = $m->{"capture"}->[1];
            return Perlito5::Grammar::String::double_quoted_var_with_subscript($m, $interpolate)
        }
        elsif ($c eq "\@" && join('', @{$str}[$pos + 1 .. $pos + length($delimiter)]) ne $delimiter && ($c2 lt 0 || $c2 gt 9) && ($c2 ne " ") && ($c2 ne "\x{9}") && ($c2 ne "
")) {
            my $m = Perlito5::Grammar::Sigil::term_sigil($str, $pos);
            $m || return $m;
            $m->{"capture"} = $m->{"capture"}->[1];
            $m = Perlito5::Grammar::String::double_quoted_var_with_subscript($m, $interpolate);
            $m->{"capture"} = Perlito5::AST::Apply::->new("code", "join", "arguments", [Perlito5::AST::Var::->new("name", "\"", "sigil", "\$", "namespace", ''), $m->{"capture"}], "namespace", '');
            return $m
        }
        return 0
    }
    Perlito5::Grammar::Precedence::add_term("'", \&term_q_quote);
    Perlito5::Grammar::Precedence::add_term("\"", \&term_qq_quote);
    Perlito5::Grammar::Precedence::add_term("/", \&term_m_quote);
    Perlito5::Grammar::Precedence::add_term("<", \&term_glob);
    Perlito5::Grammar::Precedence::add_term("<<>>", \&term_glob);
    Perlito5::Grammar::Precedence::add_term("<<", \&here_doc_wanted);
    Perlito5::Grammar::Precedence::add_term("`", \&term_qx);
    Perlito5::Grammar::Precedence::add_term("m", \&term_m_quote);
    Perlito5::Grammar::Precedence::add_term("q", \&term_q_quote);
    Perlito5::Grammar::Precedence::add_term("qq", \&term_qq_quote);
    Perlito5::Grammar::Precedence::add_term("qw", \&term_qw_quote);
    Perlito5::Grammar::Precedence::add_term("qx", \&term_qx);
    Perlito5::Grammar::Precedence::add_term("qr", \&term_qr_quote);
    Perlito5::Grammar::Precedence::add_term("s", \&term_s_quote);
    Perlito5::Grammar::Precedence::add_term("tr", \&term_tr_quote);
    Perlito5::Grammar::Precedence::add_term("y", \&term_tr_quote);
    1
}
;1
