line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Language::Expr::Parser; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $DATE = '2016-07-01'; # DATE |
4
|
|
|
|
|
|
|
our $VERSION = '0.28'; # VERSION |
5
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
64
|
use 5.010001; |
|
5
|
|
|
|
|
10
|
|
7
|
|
|
|
|
|
|
# now can't compile with this on? |
8
|
|
|
|
|
|
|
#use strict; |
9
|
|
|
|
|
|
|
#use warnings; |
10
|
|
|
|
|
|
|
|
11
|
5
|
|
|
5
|
|
5279
|
use Regexp::Grammars; |
|
5
|
|
|
|
|
87456
|
|
|
5
|
|
|
|
|
34
|
|
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
|
439
|
my ($str, $obj_arg, $level) = @_; |
24
|
|
|
|
|
|
|
|
25
|
398
|
|
50
|
|
|
1317
|
$level //= 0; |
26
|
398
|
50
|
|
|
|
688
|
die "Recursion level ($level) too deep (max $MAX_LEVELS)" if $level >= $MAX_LEVELS; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# WARN: this is not thread-safe!? |
29
|
398
|
|
|
|
|
557
|
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
|
|
|
|
|
436
|
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
|
|
|
|
|
104
|
}xms } 0..($MAX_LEVELS-1)]; |
286
|
|
|
|
|
|
|
|
287
|
398
|
|
|
|
|
329
|
$obj = $obj_arg; |
288
|
398
|
|
|
|
|
951
|
$obj_arg->expr_preprocess(string_ref => \$str, level => $level); |
289
|
|
|
|
|
|
|
#print "DEBUG: Parsing expression `$str` with grammars->[$level] ...\n"; |
290
|
398
|
100
|
|
|
|
11615
|
die "Invalid syntax in expression `$str`" unless $str =~ $grammars->[$level]; |
291
|
338
|
|
|
|
|
1194
|
$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.28 of Language::Expr::Parser (from Perl distribution Language-Expr), released on 2016-07-01. |
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/perlancar/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 |