Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 380 lines (336 sloc) 9.669 kb
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
1
2
3 .namespace [ "PGE::P5Regex" ]
4
5 .sub "compile_p5regex"
6 .param pmc source
7 .param pmc adverbs :slurpy :named
8
9 $I0 = exists adverbs['name']
10 if $I0 goto adverbs_1
11 adverbs['name'] = '_p5regex'
12 adverbs_1:
13 $I0 = exists adverbs['grammar']
14 if $I0 goto adverbs_2
1c757c9 @pmichaud [PGE]:
pmichaud authored
15 adverbs['grammar'] = 'PGE::Grammar'
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
16 adverbs_2:
17
18 .local string target
19 target = adverbs['target']
e1f7b0c @pmichaud [PGE]:
pmichaud authored
20 target = downcase target
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
21
22 .local pmc match
e1f7b0c @pmichaud [PGE]:
pmichaud authored
23 $P0 = get_global "p5regex"
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
24 match = $P0(source)
25 if target != 'parse' goto check
26 .return (match)
27
28 check:
29 unless match goto check_1
30 $S0 = source
31 $S1 = match
32 if $S0 == $S1 goto analyze
33 check_1:
34 null $P0
35 .return ($P0)
36
37 analyze:
38 .local pmc exp, pad
39 exp = match['expr']
b3ef02f @pmichaud [pge]:
pmichaud authored
40 pad = new 'Hash'
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
41 pad['subpats'] = 0
42 exp = exp.'p5analyze'(pad)
e1f7b0c @pmichaud [PGE]:
pmichaud authored
43 .return exp.'compile'(adverbs :flat :named)
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
44 .end
45
46
47 .sub "p5regex"
48 .param pmc mob
49 .local pmc optable
a96d265 @chipdude Always enclose namespace names in brackets for new pdd21 opcodes.
chipdude authored
50 optable = get_hll_global ["PGE::P5Regex"], "$optable"
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
51 $P0 = optable."parse"(mob)
52 .return ($P0)
53 .end
54
55
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
56 .include "cclass.pasm"
57
58 .const int PGE_INF = 2147483647
59
60 .sub "__onload" :load
61 .local pmc optable
62
3507247 @pmichaud [pge]: Remove find_type call from P5Regex.pir
pmichaud authored
63 optable = new 'PGE::OPTable'
a96d265 @chipdude Always enclose namespace names in brackets for new pdd21 opcodes.
chipdude authored
64 set_hll_global ["PGE::P5Regex"], "$optable", optable
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
65
a96d265 @chipdude Always enclose namespace names in brackets for new pdd21 opcodes.
chipdude authored
66 $P0 = get_hll_global ["PGE::P5Regex"], "parse_lit"
0700c33 @particle [PGE]: convert deprecated 'addtok' calls to 'newtok'
particle authored
67 optable.newtok('term:', 'precedence'=>'=', 'nows'=>1, 'parsed'=>$P0)
68
c82c9aa @pmichaud [pge]:
pmichaud authored
69 optable.newtok('term:\b', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::Anchor')
70 optable.newtok('term:\B', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::Anchor')
0700c33 @particle [PGE]: convert deprecated 'addtok' calls to 'newtok'
particle authored
71 optable.newtok('term:^', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::Anchor')
72 optable.newtok('term:$', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::Anchor')
73
c82c9aa @pmichaud [pge]:
pmichaud authored
74 optable.newtok('term:\d', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
75 optable.newtok('term:\D', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
76 optable.newtok('term:\s', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
77 optable.newtok('term:\S', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
78 optable.newtok('term:\w', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
79 optable.newtok('term:\W', 'equiv'=>'term:', 'nows'=>1, 'match'=>'PGE::Exp::CCShortcut')
0700c33 @particle [PGE]: convert deprecated 'addtok' calls to 'newtok'
particle authored
80
81 optable.newtok('circumfix:( )', 'equiv'=>'term:', 'nows'=>1, 'nullterm'=>1, 'match'=>'PGE::Exp::CGroup')
82 optable.newtok('circumfix:(?: )', 'equiv'=>'term:', 'nows'=>1, 'nullterm'=>1, 'match'=>'PGE::Exp::Group')
83
84 $P0 = get_hll_global ['PGE::P5Regex'], 'parse_enumclass'
85 optable.newtok('term:[', 'precedence'=>'=', 'nows'=>1, 'parsed'=>$P0)
86 optable.newtok('term:.', 'precedence'=>'=', 'nows'=>1, 'parsed'=>$P0)
87
88 $P0 = get_hll_global ['PGE::P5Regex'], 'parse_quant'
404a2a7 [callin convs] attempt to fix t/op/calling_95
Leopold Toetsch authored
89 optable.newtok('postfix:*', 'looser'=>'term:', 'left'=>1, 'nows'=>1, 'parsed'=>$P0)
0700c33 @particle [PGE]: convert deprecated 'addtok' calls to 'newtok'
particle authored
90 optable.newtok('postfix:+', 'equiv'=>'postfix:*', 'left'=>1, 'nows'=>1, 'parsed'=>$P0)
91 optable.newtok('postfix:?', 'equiv'=>'postfix:*', 'left'=>1, 'nows'=>1, 'parsed'=>$P0)
92 optable.newtok('postfix:{', 'equiv'=>'postfix:*', 'left'=>1, 'nows'=>1, 'parsed'=>$P0)
93
94 optable.newtok('infix:', 'looser'=>'postfix:*', 'right'=>1, 'nows'=>1, 'match'=>'PGE::Exp::Concat')
95 optable.newtok('infix:|', 'looser'=>'infix:', 'left'=>1, 'nows'=>1, 'match'=>'PGE::Exp::Alt')
96
97 optable.newtok('close:}', 'looser'=>'infix:|', 'nows'=>1) # XXX: hack
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
98
a96d265 @chipdude Always enclose namespace names in brackets for new pdd21 opcodes.
chipdude authored
99 $P0 = get_hll_global ["PGE::P5Regex"], "compile_p5regex"
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
100 compreg "PGE::P5Regex", $P0
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
101 .end
102
103
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
104 .sub 'parse_error'
105 .param pmc mob
106 .param int pos
107 .param string message
abb2d74 @particle [pge]: p5regex compiler now throws exception upon parse error
particle authored
108 $P0 = getattribute mob, '$.pos'
109 $P0 = pos
b3ef02f @pmichaud [pge]:
pmichaud authored
110 $P0 = new 'Exception'
abb2d74 @particle [pge]: p5regex compiler now throws exception upon parse error
particle authored
111 $S0 = 'p5regex parse error: '
112 $S0 .= message
113 $S0 .= ' at offset '
114 $S1 = pos
115 $S0 .= $S1
116 $S0 .= ", found '"
117 $P1 = getattribute mob, '$.target'
118 $S1 = $P1
119 $S1 = substr $S1, pos, 1
120 $S0 .= $S1
121 $S0 .= "'"
122 $P0['_message'] = $S0
123 throw $P0
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
124 .return ()
125 .end
126
127
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
128 .sub "parse_lit"
129 .param pmc mob
130 .local string target
131 .local int pos, lastpos
132 .local int litstart, litlen
133 .local string initchar
281fd4b @pmichaud [pge]:
pmichaud authored
134 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Literal')
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
135 lastpos = length target
136 initchar = substr target, pos, 1
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
137 unless initchar == '*' goto initchar_ok
138 parse_error(mob, pos, "Quantifier follows nothing")
139
140 initchar_ok:
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
141 if initchar == ')' goto end
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
142 inc pos
143 if initchar != "\\" goto term_literal
144 term_backslash:
145 initchar = substr target, pos, 1
146 inc pos
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
147 if pos <= lastpos goto term_backslash_ok
148 parse_error(mob, pos, "Search pattern not terminated")
149 term_backslash_ok:
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
150 $I0 = index "nrteab", initchar
151 if $I0 < 0 goto term_literal
152 initchar = substr "\n\r\t\e\a\b", $I0, 1
153 term_literal:
154 litstart = pos
155 litlen = 0
156 term_literal_loop:
157 if pos >= lastpos goto term_literal_end
158 $S0 = substr target, pos, 1
159 $I0 = index "[](){}*?+\\|^$.", $S0
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
160 # if not in circumfix:( ) throw error on end paren
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
161 if $I0 >= 0 goto term_literal_end
162 inc pos
163 inc litlen
164 goto term_literal_loop
165 term_literal_end:
166 if litlen < 1 goto term_literal_one
167 dec pos
168 term_literal_one:
169 $I0 = pos - litstart
170 $S0 = substr target, litstart, $I0
171 $S0 = concat initchar, $S0
19472de @pmichaud Change 'value' method to 'result_object' method, to address
pmichaud authored
172 mob.'result_object'($S0)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
173 goto end
174 end:
281fd4b @pmichaud [pge]:
pmichaud authored
175 mob.'to'(pos)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
176 .return (mob)
177 .end
178
179 .sub "parse_quant"
180 .param pmc mob
181 .local string target
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
182 .local int min, max, backtrack
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
183 .local int pos, lastpos
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
184 .local string key
185 key = mob['KEY']
281fd4b @pmichaud [pge]:
pmichaud authored
186 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Quant')
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
187 lastpos = length target
188 min = 0
189 max = PGE_INF
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
190 backtrack = 0
191 if key == '{' goto quant_range
192 if key != '+' goto quant_max
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
193 min = 1
194 quant_max:
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
195 if key != "?" goto quant_lazy
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
196 max = 1
197 goto quant_lazy
198 quant_range:
199 $I1 = find_not_cclass .CCLASS_NUMERIC, target, pos, lastpos
200 if $I1 <= pos goto quant_range_max
201 $S0 = substr target, pos
202 min = $S0
203 max = $S0
204 pos = $I1
205 quant_range_max:
206 $S0 = substr target, pos, 1
207 if $S0 != "," goto quant_range_end
208 inc pos
209 max = PGE_INF
210 $I1 = find_not_cclass .CCLASS_NUMERIC, target, pos, lastpos
211 if $I1 <= pos goto quant_range_end
212 $S0 = substr target, pos
213 max = $S0
214 pos = $I1
215 quant_range_end:
216 $S0 = substr target, pos, 1
217 if $S0 != "}" goto err_range
218 inc pos
219 quant_lazy:
220 $S0 = substr target, pos, 1
221 if $S0 != "?" goto end
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
222 backtrack = PGE_BACKTRACK_EAGER
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
223 inc pos
224 end:
225 mob["min"] = min
226 mob["max"] = max
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
227 mob["backtrack"] = backtrack
281fd4b @pmichaud [pge]:
pmichaud authored
228 mob.'to'(pos)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
229 .return (mob)
230 err_range:
231 parse_error(mob, pos, "Error in quantified range")
232 .end
233
234
235 .sub parse_group
236 .param pmc mob
237 .local string target
238 .local int pos, lastpos
281fd4b @pmichaud [pge]:
pmichaud authored
239 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::CGroup')
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
240 inc pos
241 $S0 = substr target, pos, 2
242 if $S0 == "?:" goto nocapture
243 goto end
244 nocapture:
245 pos += 2
246 end:
281fd4b @pmichaud [pge]:
pmichaud authored
247 mob.'to'(pos)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
248 .return (mob)
249 .end
250
251 .sub "parse_enumclass"
252 .param pmc mob
253 .local string target
254 .local int pos, lastpos
255 .local int isrange
256 .local string charlist
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
257 .local string key
258 key = mob['KEY']
281fd4b @pmichaud [pge]:
pmichaud authored
259 (mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::EnumCharList')
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
260 if key == '.' goto dot
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
261 lastpos = length target
262 charlist = ""
263 mob["isnegated"] = 0
264 isrange = 0
265 $S0 = substr target, pos, 1
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
266 if $S0 != "^" goto scan_first
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
267 mob["isnegated"] = 1
268 inc pos
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
269 scan_first:
270 if pos >= lastpos goto err_close
271 $S0 = substr target, pos, 1
272 inc pos
273 if $S0 == "\\" goto backslash
274 goto addchar
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
275 scan:
276 if pos >= lastpos goto err_close
277 $S0 = substr target, pos, 1
278 inc pos
279 if $S0 == "]" goto endclass
280 if $S0 == "-" goto hyphenrange
281 if $S0 != "\\" goto addchar
282 backslash:
283 $S0 = substr target, pos, 1
284 inc pos
285 $I0 = index "nrtfae0b", $S0
286 if $I0 == -1 goto addchar
287 $S0 = substr "\n\r\t\f\a\e\0\b", $I0, 1
288 addchar:
289 if isrange goto addrange
290 charlist .= $S0
291 goto scan
292 addrange:
293 isrange = 0
294 $I2 = ord charlist, -1
295 $I0 = ord $S0
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
296 if $I0 < $I2 goto err_range
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
297 addrange_1:
298 inc $I2
299 if $I2 > $I0 goto scan
300 $S1 = chr $I2
301 charlist .= $S1
302 goto addrange_1
303 hyphenrange:
304 if isrange goto addrange
305 isrange = 1
306 goto scan
307 endclass:
308 if isrange == 0 goto end
309 charlist .= "-"
310 goto end
311 dot:
312 charlist = "\n"
313 mob["isnegated"] = 1
314 end:
281fd4b @pmichaud [pge]:
pmichaud authored
315 mob.'to'(pos)
19472de @pmichaud Change 'value' method to 'result_object' method, to address
pmichaud authored
316 mob.'result_object'(charlist)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
317 .return (mob)
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
318
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
319 err_close:
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
320 parse_error(mob, pos, "Unmatched [")
321 err_range:
322 $S0 = 'Invalid [] range "'
323 $S1 = chr $I2
324 $S0 .= $S1
325 $S0 .= '-'
326 $S1 = chr $I0
327 $S0 .= $S1
328 $S0 .= '"'
329 parse_error(mob, pos, $S0)
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
330 .end
1af8ba3 @particle [PGE]: #40106: [PATCH] 15 more tests work for PGE::P5Regex
particle authored
331
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
332
333 .namespace [ "PGE::Exp" ]
334
335 .sub "p5analyze" :method
336 .param pmc pad
337 .local pmc exp
338 $I0 = 0
339 loop:
340 $I1 = defined self[$I0]
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
341 if $I1 == 0 goto end
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
342 $P0 = self[$I0]
343 $P0 = $P0."p5analyze"(pad)
344 self[$I0] = $P0
345 inc $I0
346 goto loop
347 end:
348 .return (self)
349 .end
350
9cbdcbc @pmichaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
351 .namespace [ "PGE::Exp::CGroup" ]
c346e6b @pmichaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
352
353 .sub "p5analyze" :method
354 .param pmc pad
355 .local pmc exp
356
357 self["iscapture"] = 0
358 if self != "(" goto end
359 self["iscapture"] = 1
360 self["isscope"] = 0
361 self["isarray"] = 0
362 $I0 = pad["subpats"]
363 self["cname"] = $I0
364 inc $I0
365 pad["subpats"] = $I0
366 end:
367 exp = self[0]
368 exp = exp."p5analyze"(pad)
369 self[0] = exp
370 .return (self)
371 .end
372
373
99869c4 @paultcochrane [pge] Added pir coda as per coding standards (part 5)
paultcochrane authored
374
375 # Local Variables:
376 # mode: pir
377 # fill-column: 100
378 # End:
379 # vim: expandtab shiftwidth=4:
Something went wrong with that request. Please try again.