| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Language::Expr::Parser; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $DATE = '2016-07-03'; # DATE |
|
4
|
|
|
|
|
|
|
our $VERSION = '0.29'; # VERSION |
|
5
|
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
65
|
use 5.010001; |
|
|
5
|
|
|
|
|
11
|
|
|
7
|
|
|
|
|
|
|
# now can't compile with this on? |
|
8
|
|
|
|
|
|
|
#use strict; |
|
9
|
|
|
|
|
|
|
#use warnings; |
|
10
|
|
|
|
|
|
|
|
|
11
|
5
|
|
|
5
|
|
5310
|
use Regexp::Grammars; |
|
|
5
|
|
|
|
|
95160
|
|
|
|
5
|
|
|
|
|
38
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
require Exporter; |
|
14
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
|
15
|
|
|
|
|
|
|
our @EXPORT_OK = qw(parse_expr); |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $MAX_LEVELS = 3; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# WARN: this is not thread-safe!? |
|
20
|
|
|
|
|
|
|
our $obj; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub parse_expr { |
|
23
|
398
|
|
|
398
|
1
|
462
|
my ($str, $obj_arg, $level) = @_; |
|
24
|
|
|
|
|
|
|
|
|
25
|
398
|
|
50
|
|
|
1552
|
$level //= 0; |
|
26
|
398
|
50
|
|
|
|
731
|
die "Recursion level ($level) too deep (max $MAX_LEVELS)" if $level >= $MAX_LEVELS; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# WARN: this is not thread-safe!? |
|
29
|
398
|
|
|
|
|
637
|
local $subexpr_stack = []; |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# create not just 1 but 0..$MAX_LEVELS-1 of grammar objects, each |
|
32
|
|
|
|
|
|
|
# for each recursion level (e.g. for map/grep/usort), fearing that |
|
33
|
|
|
|
|
|
|
# the grammar is not reentrant. but currently no luck yet, still |
|
34
|
|
|
|
|
|
|
# results in segfault/bus error. |
|
35
|
|
|
|
|
|
|
|
|
36
|
398
|
|
|
|
|
465
|
state $grammars = [ map { qr{ |
|
37
|
|
|
|
|
|
|
^\s*<answer>\s*$ |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
<rule: answer> |
|
40
|
|
|
|
|
|
|
<MATCH=or_xor> |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# precedence level: left => |
|
43
|
|
|
|
|
|
|
<rule: pair> |
|
44
|
|
|
|
|
|
|
<key=(\w++)> =\> <value=answer> |
|
45
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_pair_simple(match=>\%MATCH) }) |
|
46
|
|
|
|
|
|
|
| <key=squotestr> =\> <value=answer> |
|
47
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_pair_string(match=>\%MATCH) }) |
|
48
|
|
|
|
|
|
|
| <key=dquotestr> =\> <value=answer> |
|
49
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_pair_string(match=>\%MATCH) }) |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# precedence level: left || // ^^ |
|
52
|
|
|
|
|
|
|
<rule: or_xor> |
|
53
|
|
|
|
|
|
|
<[operand=ternary]> ** <[op=(\|\||//|\^\^)]> |
|
54
|
|
|
|
|
|
|
(?{ |
|
55
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
56
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_or_xor(match=>\%MATCH); |
|
57
|
|
|
|
|
|
|
} else { |
|
58
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
}) |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# precedence level: right ?: |
|
63
|
|
|
|
|
|
|
<rule: ternary> |
|
64
|
|
|
|
|
|
|
<[operand=and]> ** <[op=(\?|:)]> |
|
65
|
|
|
|
|
|
|
(?{ |
|
66
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
67
|
0
|
0
|
0
|
|
|
0
|
unless (@{ $MATCH{op} } == 2 && |
|
|
0
|
|
0
|
|
|
0
|
|
|
68
|
|
|
|
|
|
|
$MATCH{op}[0] eq '?' && |
|
69
|
|
|
|
|
|
|
$MATCH{op}[1] eq ':') { |
|
70
|
0
|
|
|
|
|
0
|
die "Invalid syntax for ternary, please use X ? Y : Z syntax"; |
|
71
|
|
|
|
|
|
|
} |
|
72
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_ternary(match=>\%MATCH); |
|
73
|
|
|
|
|
|
|
} else { |
|
74
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
}) |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# precedence level: left && |
|
79
|
|
|
|
|
|
|
<rule: and> |
|
80
|
|
|
|
|
|
|
<[operand=bit_or_xor]> ** <[op=(&&)]> |
|
81
|
|
|
|
|
|
|
(?{ |
|
82
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
83
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_and(match=>\%MATCH); |
|
84
|
|
|
|
|
|
|
} else { |
|
85
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
}) |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# precedence level: left | ^ |
|
90
|
|
|
|
|
|
|
<rule: bit_or_xor> |
|
91
|
|
|
|
|
|
|
<[operand=bit_and]> ** <[op=(\||\^)]> |
|
92
|
|
|
|
|
|
|
(?{ |
|
93
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
94
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_bit_or_xor(match=>\%MATCH); |
|
95
|
|
|
|
|
|
|
} else { |
|
96
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
}) |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# precedence level: left & |
|
101
|
|
|
|
|
|
|
<rule: bit_and> |
|
102
|
|
|
|
|
|
|
<[operand=comparison3]> ** <[op=(&)]> |
|
103
|
|
|
|
|
|
|
(?{ |
|
104
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
105
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_bit_and(match=>\%MATCH); |
|
106
|
|
|
|
|
|
|
} else { |
|
107
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
}) |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# NOTE: \x3c = "<", \x3e = ">" |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# precedence level: nonassoc (currently the grammar says assoc) <=> cmp |
|
114
|
|
|
|
|
|
|
<rule: comparison3> |
|
115
|
|
|
|
|
|
|
<[operand=comparison]> ** <[op=(\x3c=\x3e|cmp)]> |
|
116
|
|
|
|
|
|
|
(?{ |
|
117
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
118
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_comparison3(match=>\%MATCH); |
|
119
|
|
|
|
|
|
|
} else { |
|
120
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
}) |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# precedence level: left == != eq ne < > <= >= ge gt le lt |
|
125
|
|
|
|
|
|
|
<rule: comparison> |
|
126
|
|
|
|
|
|
|
<[operand=bit_shift]> ** <[op=(==|!=|eq|ne|\x3c=?|\x3e=?|lt|gt|le|ge)]> |
|
127
|
|
|
|
|
|
|
(?{ |
|
128
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
129
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_comparison(match=>\%MATCH); |
|
130
|
|
|
|
|
|
|
} else { |
|
131
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
}) |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# precedence level: left << >> |
|
136
|
|
|
|
|
|
|
<rule: bit_shift> |
|
137
|
|
|
|
|
|
|
<[operand=add]> ** <[op=(\x3c\x3c|\x3e\x3e)]> |
|
138
|
|
|
|
|
|
|
(?{ |
|
139
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
140
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_bit_shift(match=>\%MATCH); |
|
141
|
|
|
|
|
|
|
} else { |
|
142
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
}) |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# precedence level: left + - . |
|
147
|
|
|
|
|
|
|
<rule: add> |
|
148
|
|
|
|
|
|
|
<[operand=mult]> ** <[op=(\+|-|\.)]> |
|
149
|
|
|
|
|
|
|
(?{ |
|
150
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
151
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_add(match=>\%MATCH); |
|
152
|
|
|
|
|
|
|
} else { |
|
153
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
}) |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# precedence level: left * / % x |
|
158
|
|
|
|
|
|
|
<rule: mult> |
|
159
|
|
|
|
|
|
|
<[operand=unary]> ** <[op=(\*|/|%|x)]> |
|
160
|
|
|
|
|
|
|
(?{ |
|
161
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
162
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_mult(match=>\%MATCH); |
|
163
|
|
|
|
|
|
|
} else { |
|
164
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
}) |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
# precedence level: right ! ~ unary+ unary- |
|
169
|
|
|
|
|
|
|
<rule: unary> |
|
170
|
|
|
|
|
|
|
<[op=(!|~|\+|-)]>* <operand=power> |
|
171
|
|
|
|
|
|
|
(?{ |
|
172
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
173
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_unary(match=>\%MATCH); |
|
174
|
|
|
|
|
|
|
} else { |
|
175
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}; |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
}) |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# precedence level: right ** |
|
180
|
|
|
|
|
|
|
<rule: power> |
|
181
|
|
|
|
|
|
|
<[operand=subscripting]> ** <[op=(\*\*)]> |
|
182
|
|
|
|
|
|
|
(?{ |
|
183
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{op} && @{ $MATCH{op} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
184
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_power(match=>\%MATCH); |
|
185
|
|
|
|
|
|
|
} else { |
|
186
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}[0]; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
}) |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# precedence level: left hash[s], array[i] |
|
191
|
|
|
|
|
|
|
<rule: subscripting> |
|
192
|
|
|
|
|
|
|
<operand=var0> <[subscript]>* |
|
193
|
|
|
|
|
|
|
(?{ |
|
194
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{subscript} && @{ $MATCH{subscript} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
195
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_subscripting_var(match=>\%MATCH); |
|
196
|
|
|
|
|
|
|
} else { |
|
197
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}; |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
}) |
|
200
|
|
|
|
|
|
|
| <operand=term> <[subscript]>* |
|
201
|
|
|
|
|
|
|
(?{ |
|
202
|
0
|
0
|
0
|
|
|
0
|
if ($MATCH{subscript} && @{ $MATCH{subscript} }) { |
|
|
0
|
|
|
|
|
0
|
|
|
203
|
0
|
|
|
|
|
0
|
$MATCH = $obj->rule_subscripting_expr(match=>\%MATCH); |
|
204
|
|
|
|
|
|
|
} else { |
|
205
|
0
|
|
|
|
|
0
|
$MATCH = $MATCH{operand}; |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
}) |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
<rule: subscript> |
|
210
|
|
|
|
|
|
|
\[ <MATCH=term> \] |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# precedence level: left term (variable, str/num literals, func(), (paren)) |
|
213
|
|
|
|
|
|
|
<rule: term> |
|
214
|
|
|
|
|
|
|
<MATCH=func> |
|
215
|
|
|
|
|
|
|
| <MATCH=var0> |
|
216
|
|
|
|
|
|
|
| <MATCH=str0> |
|
217
|
|
|
|
|
|
|
| <MATCH=undef> |
|
218
|
|
|
|
|
|
|
| <MATCH=num0> |
|
219
|
|
|
|
|
|
|
| <MATCH=bool0> |
|
220
|
|
|
|
|
|
|
| <MATCH=array> |
|
221
|
|
|
|
|
|
|
| <MATCH=hash> |
|
222
|
|
|
|
|
|
|
| \( <answer> \) |
|
223
|
0
|
|
0
|
|
|
0
|
(?{ $MATCH = $obj->rule_parenthesis(match=>\%MATCH) // $MATCH{answer} }) |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
<rule: array> |
|
226
|
|
|
|
|
|
|
\[ \] |
|
227
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_array(match=>{element=>[]}) }) |
|
228
|
|
|
|
|
|
|
| \[ <[element=answer]> ** (,) \] |
|
229
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_array(match=>\%MATCH) }) |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
<rule: hash> |
|
232
|
|
|
|
|
|
|
\{ \} |
|
233
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_hash(match=>{pair=>[]}) }) |
|
234
|
|
|
|
|
|
|
| \{ <[pair]> ** (,) \} |
|
235
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_hash(match=>\%MATCH) }) |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
<token: undef> |
|
238
|
|
|
|
|
|
|
undef |
|
239
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_undef() }) |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
<token: bool0> |
|
242
|
|
|
|
|
|
|
<bool=(true|false)> |
|
243
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_bool(match=>\%MATCH) }) |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
<token: num0> |
|
246
|
|
|
|
|
|
|
<sign0a=([+-]?+)> 0x <num0a=([0-9A-Fa-f]++)> |
|
247
|
|
|
|
|
|
|
(?{ $MATCH = $obj->rule_num(match=>{num=> |
|
248
|
0
|
0
|
|
|
|
0
|
($MATCH{sign0a} eq '-' ? -1:1) * hex($MATCH{num0a})}) }) |
|
249
|
|
|
|
|
|
|
| <sign0b=([+-]?+)> 0o <num0b=([0-7]++)> |
|
250
|
|
|
|
|
|
|
(?{ $MATCH = $obj->rule_num(match=>{num=> |
|
251
|
0
|
0
|
|
|
|
0
|
($MATCH{sign0b} eq '-' ? -1:1) * oct($MATCH{num0b})}) }) |
|
252
|
|
|
|
|
|
|
| <sign0c=([+-]?+)> 0b <num0c=([0-1]++)> |
|
253
|
|
|
|
|
|
|
(?{ $MATCH = $obj->rule_num(match=>{num=> |
|
254
|
0
|
0
|
|
|
|
0
|
($MATCH{sign0c} eq '-' ? -1:1) * oct("0b".$MATCH{num0c})}) }) |
|
255
|
|
|
|
|
|
|
| <num0c=( [+-]?\d++(?:\.\d++)?+ | inf | nan)> |
|
256
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_num(match=>{num=>$MATCH{num0c}}) }) |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
<rule: str0> |
|
259
|
|
|
|
|
|
|
<MATCH=squotestr> |
|
260
|
|
|
|
|
|
|
| <MATCH=dquotestr> |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
<token: squotestr> |
|
263
|
|
|
|
|
|
|
'<[part=(\\\\|\\'|\\|[^\\']++)]>*' |
|
264
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_squotestr(match=>\%MATCH) }) |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
<token: dquotestr> |
|
267
|
|
|
|
|
|
|
"<[part=([^"\044\\]++|\$\.\.?|\$\w+|\$\{[^\}]+\}|\\\\|\\'|\\"|\\[tnrfbae\$]|\\[0-7]{1,3}|\\x[0-9A-Fa-f]{1,2}|\\x\{[0-9A-Fa-f]{1,4}\}|\\)]>*" |
|
268
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_dquotestr(match=>\%MATCH) }) |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
<rule: var0> |
|
271
|
|
|
|
|
|
|
\$ <var=(\w++(?:::\w+)*+)> |
|
272
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_var(match=>\%MATCH) }) |
|
273
|
|
|
|
|
|
|
| \$ \{ <var=([^\}]++)> \} |
|
274
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_var(match=>\%MATCH) }) |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
<rule: func> |
|
277
|
|
|
|
|
|
|
<func_name=([A-Za-z_]\w*+)> \( \) |
|
278
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_func(match=>{func_name=>$MATCH{func_name}, args=>[]}) }) |
|
279
|
0
|
|
|
|
|
0
|
| <func_name=(map|grep|usort)> \( \{ <expr=answer> \} (?{ push @$subexpr_stack, $CONTEXT }), <input_array=answer> \) |
|
280
|
0
|
|
|
|
|
0
|
(?{ my $meth = "rule_func_$MATCH{func_name}"; |
|
281
|
0
|
|
|
|
|
0
|
$MATCH = $obj->$meth(match=>{expr=>pop(@$subexpr_stack), array=>$MATCH{input_array}}) }) |
|
282
|
|
|
|
|
|
|
| <func_name=([A-Za-z_]\w*+)> \( <[args=answer]> ** (,) \) |
|
283
|
0
|
|
|
|
|
0
|
(?{ $MATCH = $obj->rule_func(match=>\%MATCH) }) |
|
284
|
|
|
|
|
|
|
|
|
285
|
15
|
|
|
|
|
145
|
}xms } 0..($MAX_LEVELS-1)]; |
|
286
|
|
|
|
|
|
|
|
|
287
|
398
|
|
|
|
|
447
|
$obj = $obj_arg; |
|
288
|
398
|
|
|
|
|
1054
|
$obj_arg->expr_preprocess(string_ref => \$str, level => $level); |
|
289
|
|
|
|
|
|
|
#print "DEBUG: Parsing expression `$str` with grammars->[$level] ...\n"; |
|
290
|
398
|
100
|
|
|
|
12506
|
die "Invalid syntax in expression `$str`" unless $str =~ $grammars->[$level]; |
|
291
|
338
|
|
|
|
|
1393
|
$obj_arg->expr_postprocess(result => $/{answer}); |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
1; |
|
295
|
|
|
|
|
|
|
# ABSTRACT: Parse Language::Expr expression |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
__END__ |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=pod |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=encoding UTF-8 |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head1 NAME |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Language::Expr::Parser - Parse Language::Expr expression |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=head1 VERSION |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
This document describes version 0.29 of Language::Expr::Parser (from Perl distribution Language-Expr), released on 2016-07-03. |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=head1 KNOWN BUGS |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=over 4 |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item * Ternary operator is not chainable yet. |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=back |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=head1 METHODS |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head2 parse_expr($str, $obj) |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
Parse expression in $str. Will call various rule_*() methods in $obj. |
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head1 HOMEPAGE |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Please visit the project's homepage at L<https://metacpan.org/release/Language-Expr>. |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head1 SOURCE |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
Source repository is at L<https://github.com/sharyanto/perl-Language-Expr>. |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head1 BUGS |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Language-Expr> |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
When submitting a bug or request, please include a test-file or a |
|
338
|
|
|
|
|
|
|
patch to an existing test-file that illustrates the bug or desired |
|
339
|
|
|
|
|
|
|
feature. |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=head1 AUTHOR |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
perlancar <perlancar@cpan.org> |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
This software is copyright (c) 2016 by perlancar@cpan.org. |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
|
350
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=cut |