# Do not edit this file - Generated by Perlito5 9.011
{
    package main;
    package Perlito5::Grammar::Number;
    use strict;
    use Perlito5::Grammar::Precedence;
    sub Perlito5::Grammar::Number::term_digit {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((do {
            my $pos1 = $MATCH->{'to'};
            (do {
                ((do {
                    my $m2 = Perlito5::Grammar::Number::val_octal($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        $MATCH->{'Perlito5::Grammar::Number::val_octal'} = $m2;
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    $MATCH->{'str'} = $str;
                    $MATCH->{'capture'} = ['term', Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::Number::val_octal'})];
                    1
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ((do {
                    my $m2 = Perlito5::Grammar::Number::val_vstring($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        $MATCH->{'Perlito5::Grammar::Number::val_vstring'} = $m2;
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    $MATCH->{'str'} = $str;
                    $MATCH->{'capture'} = ['term', Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::Number::val_vstring'})];
                    1
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ((do {
                    my $m2 = Perlito5::Grammar::Number::val_num($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        $MATCH->{'Perlito5::Grammar::Number::val_num'} = $m2;
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    $MATCH->{'str'} = $str;
                    $MATCH->{'capture'} = ['term', Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::Number::val_num'})];
                    1
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ((do {
                    my $m2 = Perlito5::Grammar::Number::val_int($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        $MATCH->{'Perlito5::Grammar::Number::val_int'} = $m2;
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    $MATCH->{'str'} = $str;
                    $MATCH->{'capture'} = ['term', Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::Number::val_int'})];
                    1
                }))
            })
        }));
        $tmp ? $MATCH : 0
    }
    Perlito5::Grammar::Precedence::add_term($_ => \&term_digit)
        for '.', 0 .. 9;
    sub Perlito5::Grammar::Number::digit {
        substr($_[0], $_[1], 1) =~ m!\d! ? {'str' => $_[0], 'from' => $_[1], 'to' => $_[1] + 1} : 0
    }
    sub Perlito5::Grammar::Number::exponent {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((do {
            my $pos1 = $MATCH->{'to'};
            (do {
                ('e' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ('E' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
            })
        }) && (do {
            my $pos1 = $MATCH->{'to'};
            (do {
                ('+' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ('-' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                1
            })
        }) && (do {
            my $last_match_null = 0;
            my $m = $MATCH;
            my $to = $MATCH->{'to'};
            my $count = 0;
            while ((do {
                my $pos1 = $MATCH->{'to'};
                (do {
                    ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                }) || (do {
                    $MATCH->{'to'} = $pos1;
                    (do {
                        my $m2 = digit($str, $MATCH->{'to'});
                        if ($m2) {
                            $MATCH->{'to'} = $m2->{'to'};
                            1
                        }
                        else {
                            0
                        }
                    })
                })
            }) && ($last_match_null < 2)) {
                if ($to == $MATCH->{'to'}) {
                    $last_match_null = $last_match_null + 1
                }
                else {
                    $last_match_null = 0
                }
                $m = $MATCH;
                $to = $MATCH->{'to'};
                $count = $count + 1
            }
            $MATCH = $m;
            $MATCH->{'to'} = $to;
            $count > 0
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::val_num {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((do {
            my $pos1 = $MATCH->{'to'};
            (do {
                (('.' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
                    my $m2 = digit($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    my $last_match_null = 0;
                    my $m = $MATCH;
                    my $to = $MATCH->{'to'};
                    while ((do {
                        my $pos1 = $MATCH->{'to'};
                        (do {
                            ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        }) || (do {
                            $MATCH->{'to'} = $pos1;
                            (do {
                                my $m2 = digit($str, $MATCH->{'to'});
                                if ($m2) {
                                    $MATCH->{'to'} = $m2->{'to'};
                                    1
                                }
                                else {
                                    0
                                }
                            })
                        })
                    }) && ($last_match_null < 2)) {
                        if ($to == $MATCH->{'to'}) {
                            $last_match_null = $last_match_null + 1
                        }
                        else {
                            $last_match_null = 0
                        }
                        $m = $MATCH;
                        $to = $MATCH->{'to'}
                    }
                    $MATCH = $m;
                    $MATCH->{'to'} = $to;
                    1
                }) && (do {
                    my $m = $MATCH;
                    if (!(do {
                        my $m2 = exponent($str, $MATCH->{'to'});
                        if ($m2) {
                            $MATCH->{'to'} = $m2->{'to'};
                            1
                        }
                        else {
                            0
                        }
                    })) {
                        $MATCH = $m
                    }
                    1
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ((do {
                    my $m2 = digit($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    my $last_match_null = 0;
                    my $m = $MATCH;
                    my $to = $MATCH->{'to'};
                    while ((do {
                        my $pos1 = $MATCH->{'to'};
                        (do {
                            ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        }) || (do {
                            $MATCH->{'to'} = $pos1;
                            (do {
                                my $m2 = digit($str, $MATCH->{'to'});
                                if ($m2) {
                                    $MATCH->{'to'} = $m2->{'to'};
                                    1
                                }
                                else {
                                    0
                                }
                            })
                        })
                    }) && ($last_match_null < 2)) {
                        if ($to == $MATCH->{'to'}) {
                            $last_match_null = $last_match_null + 1
                        }
                        else {
                            $last_match_null = 0
                        }
                        $m = $MATCH;
                        $to = $MATCH->{'to'}
                    }
                    $MATCH = $m;
                    $MATCH->{'to'} = $to;
                    1
                }) && (do {
                    my $pos1 = $MATCH->{'to'};
                    (do {
                        (do {
                            my $m2 = exponent($str, $MATCH->{'to'});
                            if ($m2) {
                                $MATCH->{'to'} = $m2->{'to'};
                                1
                            }
                            else {
                                0
                            }
                        })
                    }) || (do {
                        $MATCH->{'to'} = $pos1;
                        (('.' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
                            my $tmp = $MATCH;
                            $MATCH = {'str' => $str, 'from' => $tmp->{'to'}, 'to' => $tmp->{'to'}};
                            my $res = ('.' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}));
                            $MATCH = $tmp;
                            $res ? 0 : 1
                        }) && (do {
                            my $last_match_null = 0;
                            my $m = $MATCH;
                            my $to = $MATCH->{'to'};
                            while ((do {
                                my $pos1 = $MATCH->{'to'};
                                (do {
                                    ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                                }) || (do {
                                    $MATCH->{'to'} = $pos1;
                                    (do {
                                        my $m2 = digit($str, $MATCH->{'to'});
                                        if ($m2) {
                                            $MATCH->{'to'} = $m2->{'to'};
                                            1
                                        }
                                        else {
                                            0
                                        }
                                    })
                                })
                            }) && ($last_match_null < 2)) {
                                if ($to == $MATCH->{'to'}) {
                                    $last_match_null = $last_match_null + 1
                                }
                                else {
                                    $last_match_null = 0
                                }
                                $m = $MATCH;
                                $to = $MATCH->{'to'}
                            }
                            $MATCH = $m;
                            $MATCH->{'to'} = $to;
                            1
                        }) && (do {
                            my $m = $MATCH;
                            if (!(do {
                                my $m2 = exponent($str, $MATCH->{'to'});
                                if ($m2) {
                                    $MATCH->{'to'} = $m2->{'to'};
                                    1
                                }
                                else {
                                    0
                                }
                            })) {
                                $MATCH = $m
                            }
                            1
                        }))
                    })
                }))
            })
        }) && (do {
            $MATCH->{'str'} = $str;
            my $s = Perlito5::Match::flat($MATCH);
            $s =~ s!_!!g;
            $MATCH->{'capture'} = Perlito5::AST::Num::->new('num' => $s);
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::digits {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((do {
            my $last_match_null = 0;
            my $m = $MATCH;
            my $to = $MATCH->{'to'};
            my $count = 0;
            while ((do {
                my $m2 = digit($str, $MATCH->{'to'});
                if ($m2) {
                    $MATCH->{'to'} = $m2->{'to'};
                    1
                }
                else {
                    0
                }
            }) && ($last_match_null < 2)) {
                if ($to == $MATCH->{'to'}) {
                    $last_match_null = $last_match_null + 1
                }
                else {
                    $last_match_null = 0
                }
                $m = $MATCH;
                $to = $MATCH->{'to'};
                $count = $count + 1
            }
            $MATCH = $m;
            $MATCH->{'to'} = $to;
            $count > 0
        }));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::digits_underscore {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((do {
            my $m2 = digit($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        }) && (do {
            my $last_match_null = 0;
            my $m = $MATCH;
            my $to = $MATCH->{'to'};
            while ((do {
                my $pos1 = $MATCH->{'to'};
                (do {
                    ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                }) || (do {
                    $MATCH->{'to'} = $pos1;
                    (do {
                        my $m2 = digit($str, $MATCH->{'to'});
                        if ($m2) {
                            $MATCH->{'to'} = $m2->{'to'};
                            1
                        }
                        else {
                            0
                        }
                    })
                })
            }) && ($last_match_null < 2)) {
                if ($to == $MATCH->{'to'}) {
                    $last_match_null = $last_match_null + 1
                }
                else {
                    $last_match_null = 0
                }
                $m = $MATCH;
                $to = $MATCH->{'to'}
            }
            $MATCH = $m;
            $MATCH->{'to'} = $to;
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::val_octal {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((0 eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
            my $pos1 = $MATCH->{'to'};
            (do {
                ((do {
                    my $pos1 = $MATCH->{'to'};
                    (do {
                        ('x' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                    }) || (do {
                        $MATCH->{'to'} = $pos1;
                        ('X' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                    })
                }) && (do {
                    my $last_match_null = 0;
                    my $m = $MATCH;
                    my $to = $MATCH->{'to'};
                    my $count = 0;
                    while ((do {
                        my $m2 = Perlito5::Grammar::word($str, $MATCH->{'to'});
                        if ($m2) {
                            $MATCH->{'to'} = $m2->{'to'};
                            1
                        }
                        else {
                            0
                        }
                    }) && ($last_match_null < 2)) {
                        if ($to == $MATCH->{'to'}) {
                            $last_match_null = $last_match_null + 1
                        }
                        else {
                            $last_match_null = 0
                        }
                        $m = $MATCH;
                        $to = $MATCH->{'to'};
                        $count = $count + 1
                    }
                    $MATCH = $m;
                    $MATCH->{'to'} = $to;
                    $count > 0
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                ((do {
                    my $pos1 = $MATCH->{'to'};
                    (do {
                        ('b' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                    }) || (do {
                        $MATCH->{'to'} = $pos1;
                        ('B' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                    })
                }) && (do {
                    my $last_match_null = 0;
                    my $m = $MATCH;
                    my $to = $MATCH->{'to'};
                    my $count = 0;
                    while ((do {
                        my $pos1 = $MATCH->{'to'};
                        (do {
                            ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        }) || (do {
                            $MATCH->{'to'} = $pos1;
                            (0 eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        }) || (do {
                            $MATCH->{'to'} = $pos1;
                            (1 eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        })
                    }) && ($last_match_null < 2)) {
                        if ($to == $MATCH->{'to'}) {
                            $last_match_null = $last_match_null + 1
                        }
                        else {
                            $last_match_null = 0
                        }
                        $m = $MATCH;
                        $to = $MATCH->{'to'};
                        $count = $count + 1
                    }
                    $MATCH = $m;
                    $MATCH->{'to'} = $to;
                    $count > 0
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                (do {
                    my $last_match_null = 0;
                    my $m = $MATCH;
                    my $to = $MATCH->{'to'};
                    my $count = 0;
                    while ((do {
                        my $pos1 = $MATCH->{'to'};
                        (do {
                            ('_' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'}))
                        }) || (do {
                            $MATCH->{'to'} = $pos1;
                            (do {
                                my $m2 = digit($str, $MATCH->{'to'});
                                if ($m2) {
                                    $MATCH->{'to'} = $m2->{'to'};
                                    1
                                }
                                else {
                                    0
                                }
                            })
                        })
                    }) && ($last_match_null < 2)) {
                        if ($to == $MATCH->{'to'}) {
                            $last_match_null = $last_match_null + 1
                        }
                        else {
                            $last_match_null = 0
                        }
                        $m = $MATCH;
                        $to = $MATCH->{'to'};
                        $count = $count + 1
                    }
                    $MATCH = $m;
                    $MATCH->{'to'} = $to;
                    $count > 0
                })
            })
        }) && (do {
            $MATCH->{'str'} = $str;
            $MATCH->{'capture'} = Perlito5::AST::Int::->new('int' => oct(lc(Perlito5::Match::flat($MATCH))));
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::val_int {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((do {
            my $m2 = digits_underscore($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        }) && (do {
            $MATCH->{'str'} = $str;
            my $s = Perlito5::Match::flat($MATCH);
            $s =~ s!_!!g;
            $MATCH->{'capture'} = Perlito5::AST::Int::->new('int' => $s);
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::val_vstring {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = (((do {
            my $m2 = val_int($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                $MATCH->{'val_int'} = $m2;
                1
            }
            else {
                0
            }
        }) && (do {
            my $last_match_null = 0;
            my $m = $MATCH;
            my $to = $MATCH->{'to'};
            my $count = 0;
            while ((('.' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
                my $m2 = digits_underscore($str, $MATCH->{'to'});
                if ($m2) {
                    $MATCH->{'to'} = $m2->{'to'};
                    if (exists($MATCH->{'digits_underscore'})) {
                        push(@{$MATCH->{'digits_underscore'}}, $m2)
                    }
                    else {
                        $MATCH->{'digits_underscore'} = [$m2]
                    }
                    1
                }
                else {
                    0
                }
            })) && ($last_match_null < 2)) {
                if ($to == $MATCH->{'to'}) {
                    $last_match_null = $last_match_null + 1
                }
                else {
                    $last_match_null = 0
                }
                $m = $MATCH;
                $to = $MATCH->{'to'};
                $count = $count + 1
            }
            $MATCH = $m;
            $MATCH->{'to'} = $to;
            $count > 0
        }) && (do {
            $MATCH->{'str'} = $str;
            my @parts = map {
                Perlito5::Match::flat($_)
            } @{$MATCH->{'digits_underscore'}};
            @parts < 2 && return ;
            $MATCH->{'capture'} = Perlito5::AST::Buf::->new('buf' => join('', map {
                chr($_)
            } $MATCH->{'val_int'}->{'capture'}->{'int'}, @parts));
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Number::val_version {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((('v' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
            my $m2 = val_int($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                $MATCH->{'val_int'} = $m2;
                1
            }
            else {
                0
            }
        }) && (do {
            my $last_match_null = 0;
            my $m = $MATCH;
            my $to = $MATCH->{'to'};
            while ((('.' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
                my $m2 = digits_underscore($str, $MATCH->{'to'});
                if ($m2) {
                    $MATCH->{'to'} = $m2->{'to'};
                    if (exists($MATCH->{'digits_underscore'})) {
                        push(@{$MATCH->{'digits_underscore'}}, $m2)
                    }
                    else {
                        $MATCH->{'digits_underscore'} = [$m2]
                    }
                    1
                }
                else {
                    0
                }
            })) && ($last_match_null < 2)) {
                if ($to == $MATCH->{'to'}) {
                    $last_match_null = $last_match_null + 1
                }
                else {
                    $last_match_null = 0
                }
                $m = $MATCH;
                $to = $MATCH->{'to'}
            }
            $MATCH = $m;
            $MATCH->{'to'} = $to;
            1
        }) && (do {
            $MATCH->{'str'} = $str;
            my @parts = map {
                Perlito5::Match::flat($_)
            } @{$MATCH->{'digits_underscore'}};
            $MATCH->{'capture'} = Perlito5::AST::Buf::->new('buf' => join('', map {
                chr($_)
            } $MATCH->{'val_int'}->{'capture'}->{'int'}, @parts));
            1
        })));
        $tmp ? $MATCH : 0
    }
    1
}
;1
