first commit
This commit is contained in:
71
perl/Examples/Chap8/calculator
Normal file
71
perl/Examples/Chap8/calculator
Normal 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(\¬hing, 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);
|
||||
Reference in New Issue
Block a user