first commit

This commit is contained in:
douboer
2025-09-17 16:08:16 +08:00
parent 9395faa6b2
commit 3ff47c11d5
1318 changed files with 117477 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
###
### calculator
###
## Chapter 8 section 4.6
use Parser ':all';
use Lexer ':all';
my $input = allinput(\*STDIN);
my $lexer = iterator_to_stream(
make_lexer($input,
['TERMINATOR', qr/;\n*|\n+/ ],
['INT', qr/\d+/ ],
['PRINT', qr/\bprint\b/ ],
['IDENTIFIER', qr|[A-Za-z_]\w*| ],
['OP', qr#\*\*|[-=+*/()]# ],
['WHITESPACE', qr/\s+/, sub { "" } ],
)
);
## Chapter 8 section 4.6
my %VAR;
my ($base, $expression, $factor, $program, $statement, $term);
$Base = parser { $base->(@_) };
$Expression = parser { $expression->(@_) };
$Factor = parser { $factor->(@_) };
$Program = parser { $program->(@_) };
$Statement = parser { $statement->(@_) };
$Term = parser { $term->(@_) };
$program = concatenate(star($Statement), \&End_of_Input);
$statement = alternate(T(concatenate(lookfor('PRINT'),
$Expression,
lookfor('TERMINATOR')),
sub { print ">> $_[1]\n" }),
T(concatenate(lookfor('IDENTIFIER'),
lookfor(['OP', '=']),
$Expression,
lookfor('TERMINATOR')
),
sub { $VAR{$_[0]} = $_[2] }),
);
$expression =
operator($Term, [lookfor(['OP', '+']), sub { $_[0] + $_[1] }],
[lookfor(['OP', '-']), sub { $_[0] - $_[1] }]);
$term =
operator($Factor, [lookfor(['OP', '*']), sub { $_[0] * $_[1] }],
[lookfor(['OP', '/']), sub { $_[0] / $_[1] }]);
$factor = T(concatenate($Base,
alternate(T(concatenate(lookfor(['OP', '**']),
$Factor),
sub { $_[1] }),
T(\&nothing, sub { 1 }))),
sub { $_[0] ** $_[1] });
$base = alternate(lookfor('INT'),
lookfor('IDENTIFIER',
sub { $VAR{$_[0][1]} || 0 }),
T(concatenate(lookfor(['OP', '(']),
$Expression,
lookfor(['OP', ')'])),
sub { $_[1] })
);
$program->($lexer);