-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.pl
executable file
·100 lines (77 loc) · 2.04 KB
/
Parser.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/perl
package Parser;
require Scanner;
use strict;
use warnings;
# Forward declarations:
sub Error;
sub Term;
sub Power;
sub Factor;
sub Expr {
my $INPUT = shift;
&Term($INPUT);
my ($token, $value, $lineno) = &Scanner::GetToken($INPUT);
while ($token eq "PLUS" || $token eq "MINUS") {
&Term($INPUT);
($token, $value, $lineno) = &Scanner::GetToken($INPUT);
}
&Scanner::UngetToken($token);
}
sub Term {
my $INPUT = shift;
&Power($INPUT);
my ($token, $value, $lineno) = &Scanner::GetToken($INPUT);
while ($token eq "TIMES" || $token eq "DIVIDED_BY") {
&Power($INPUT);
($token, $value, $lineno) = &Scanner::GetToken($INPUT);
}
&Scanner::UngetToken($token);
}
sub Power {
my $INPUT = shift;
&Factor($INPUT);
my ($token, $value, $lineno) = &Scanner::GetToken($INPUT);
if ($token ne "POWER") {
&Scanner::UngetToken($token);
} else {
&Power($INPUT);
}
}
sub Factor {
my $INPUT = shift;
my ($token, $value, $lineno) = &Scanner::GetToken($INPUT);
if ($token eq "NUMBER") {
; # Intentionally empty!
} elsif ($token eq "IDENT") {
; # Intentionally empty!
} elsif ($token eq "OPEN_PAREN") {
&Expr($INPUT);
($token, $value, $lineno) = &Scanner::GetToken($INPUT);
$token eq "CLOSE_PAREN" || &Error("Expected ')' after expression on line $lineno, instead found $token!");
} elsif ($token eq "PLUS" || $token eq "MINUS") {
&Factor($INPUT);
} else {
&Error("Unexpected token $token($value) on line $lineno while parsing a factor!");
}
}
sub Usage() {
print "usage: $0 input_filename\n";
exit 1;
}
sub Error() {
my $msg = shift;
print "$0: $msg\n";
exit 1;
}
sub main() {
$#ARGV == 0 || Usage();
open(my $INPUT, "<", $ARGV[0]) || &Error("Can't open \"$ARGV[0]\" for reading ($!)!");
&Expr($INPUT);
my ($token, $value, $lineno) = &Scanner::GetToken($INPUT);
if ($token ne "END_OF_INPUT") {
&Error("Unexpected token $token($value) after end of expression on line $lineno: $token!");
}
close($INPUT);
}
&main();