Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 363 lines (318 sloc) 8.806 kb
9cbdcbc Patrick R. Michaud 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
15 adverbs['grammar'] = 'PGE::Regex'
16 adverbs_2:
17
18 .local string target
19 target = adverbs['target']
20
21 .local pmc match
22 $P0 = find_global "PGE::Regex", "p5regex"
23 match = $P0(source)
24 if target != 'parse' goto check
25 .return (match)
26
27 check:
28 unless match goto check_1
29 $S0 = source
30 $S1 = match
31 if $S0 == $S1 goto analyze
32 check_1:
33 null $P0
34 .return ($P0)
35
36 analyze:
37 .local pmc exp, pad
38 exp = match['expr']
39 pad = new .Hash
40 pad['subpats'] = 0
41 exp = exp.'p5analyze'(pad)
42 if target != 'exp' goto pir
43 .return (exp)
44
45 pir:
46 .local pmc code
47 code = exp.'root_pir'(adverbs :flat :named)
48 if target != 'PIR' goto bytecode
49 .return (code)
50
51 bytecode:
52 $P0 = compreg 'PIR'
53 $P1 = $P0(code)
54 .return ($P1)
55 .end
56
57
58 .namespace [ "PGE::Regex" ]
59
60 .sub "p5regex"
61 .param pmc mob
62 .local pmc optable
63 optable = find_global "PGE::P5Regex", "$optable"
64 $P0 = optable."parse"(mob)
65 .return ($P0)
66 .end
67
68
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
69 .include "cclass.pasm"
70
71 .const int PGE_INF = 2147483647
72
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
73 .namespace [ "PGE::P5Regex" ]
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
74
75 .sub "__onload" :load
76 .local pmc optable
77
78 $I0 = find_type "PGE::OPTable"
79 optable = new $I0
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
80 store_global "PGE::P5Regex", "$optable", optable
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
81
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
82 $P0 = find_global "PGE::P5Regex", "parse_lit"
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
83 optable.addtok("term:", "", "nows", $P0)
84 optable.addtok("term:\\b", "term:", "nows", "PGE::Exp::Anchor")
85 optable.addtok("term:\\B", "term:", "nows", "PGE::Exp::Anchor")
86 optable.addtok("term:^", "term:", "nows", "PGE::Exp::Anchor")
87 optable.addtok("term:$", "term:", "nows", "PGE::Exp::Anchor")
88
89 optable.addtok("term:\\d", "term:", "nows", "PGE::Exp::CCShortcut")
90 optable.addtok("term:\\D", "term:", "nows", "PGE::Exp::CCShortcut")
91 optable.addtok("term:\\s", "term:", "nows", "PGE::Exp::CCShortcut")
92 optable.addtok("term:\\S", "term:", "nows", "PGE::Exp::CCShortcut")
93 optable.addtok("term:\\w", "term:", "nows", "PGE::Exp::CCShortcut")
94 optable.addtok("term:\\W", "term:", "nows", "PGE::Exp::CCShortcut")
95
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
96 optable.addtok("circumfix:( )", "term:", "nows,nullterm", 'PGE::Exp::CGroup')
97 optable.addtok("circumfix:(?: )", "term:", "nows,nullterm", 'PGE::Exp::Group')
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
98
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
99 $P0 = find_global "PGE::P5Regex", "parse_enumclass"
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
100 optable.addtok("term:[", "", "nows", $P0)
101 optable.addtok("term:.", "", "nows", $P0)
102
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
103 $P0 = find_global "PGE::P5Regex", "parse_quant"
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
104 optable.addtok("postfix:*", "<term:", "left,nows", $P0)
105 optable.addtok("postfix:+", "postfix:*", "left,nows", $P0)
106 optable.addtok("postfix:?", "postfix:*", "left,nows", $P0)
107 optable.addtok("postfix:{", "postfix:*", "left,nows", $P0)
108
109 optable.addtok("infix:", "<postfix:*", "right,nows", "PGE::Exp::Concat")
110 optable.addtok("infix:|", "<infix:", "left,nows", "PGE::Exp::Alt")
111
112 optable.addtok("close:}", "<infix:|", "nows") # XXX: hack
113 optable.addtok("close:]", "close:}", "nows") # XXX: hack
114
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
115 $P0 = find_global "PGE::P5Regex", "compile_p5regex"
116 compreg "PGE::P5Regex", $P0
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
117 .end
118
119
120 .sub "parse_lit"
121 .param pmc mob
122 .local pmc newfrom
123 .local string target
124 .local int pos, lastpos
125 .local int litstart, litlen
126 .local string initchar
127 newfrom = find_global "PGE::Match", "newfrom"
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
128 (mob, target, $P0, $P1) = newfrom(mob, 0, "PGE::Exp::Literal")
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
129 pos = $P0
130 lastpos = length target
131 initchar = substr target, pos, 1
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
132 if initchar == ')' goto end
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
133 inc pos
134 if initchar != "\\" goto term_literal
135
136 term_backslash:
137 initchar = substr target, pos, 1
138 inc pos
139 $I0 = index "nrteab", initchar
140 if $I0 < 0 goto term_literal
141 initchar = substr "\n\r\t\e\a\b", $I0, 1
142
143 term_literal:
144 litstart = pos
145 litlen = 0
146 term_literal_loop:
147 if pos >= lastpos goto term_literal_end
148 $S0 = substr target, pos, 1
149 $I0 = index "[](){}*?+\\|^$.", $S0
150 if $I0 >= 0 goto term_literal_end
151 inc pos
152 inc litlen
153 goto term_literal_loop
154 term_literal_end:
155 if litlen < 1 goto term_literal_one
156 dec pos
157 term_literal_one:
158 $I0 = pos - litstart
159 $S0 = substr target, litstart, $I0
160 $S0 = concat initchar, $S0
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
161 mob.set_value($S0)
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
162 goto end
163 end:
56a089a Patrick R. Michaud Converted PGE's internal object attributes to use updated sigils and
pmichaud authored
164 $P0 = getattribute mob, "PGE::Match\x0$.pos"
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
165 $P0 = pos
166 .return (mob)
167 .end
168
169 .sub "parse_quant"
170 .param pmc mob
171 .local string target
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
172 .local int min, max, backtrack
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
173 .local int pos, lastpos
174 .local pmc mfrom, mpos
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
175 .local string key
176 key = mob['KEY']
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
177 $P0 = find_global "PGE::Match", "newfrom"
178 (mob, target, mfrom, mpos) = $P0(mob, 0, "PGE::Exp::Quant")
179 pos = mfrom
180 lastpos = length target
181 min = 0
182 max = PGE_INF
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
183 backtrack = 0
184 if key == '{' goto quant_range
185 if key != '+' goto quant_max
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
186 min = 1
187 quant_max:
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
188 if key != "?" goto quant_lazy
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
189 max = 1
190 goto quant_lazy
191 quant_range:
192 $I1 = find_not_cclass .CCLASS_NUMERIC, target, pos, lastpos
193 if $I1 <= pos goto quant_range_max
194 $S0 = substr target, pos
195 min = $S0
196 max = $S0
197 pos = $I1
198 quant_range_max:
199 $S0 = substr target, pos, 1
200 if $S0 != "," goto quant_range_end
201 inc pos
202 max = PGE_INF
203 $I1 = find_not_cclass .CCLASS_NUMERIC, target, pos, lastpos
204 if $I1 <= pos goto quant_range_end
205 $S0 = substr target, pos
206 max = $S0
207 pos = $I1
208 quant_range_end:
209 $S0 = substr target, pos, 1
210 if $S0 != "}" goto err_range
211 inc pos
212 quant_lazy:
213 $S0 = substr target, pos, 1
214 if $S0 != "?" goto end
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
215 backtrack = PGE_BACKTRACK_EAGER
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
216 inc pos
217 end:
218 mob["min"] = min
219 mob["max"] = max
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
220 mob["backtrack"] = backtrack
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
221 mpos = pos
222 .return (mob)
223 err_range:
224 parse_error(mob, pos, "Error in quantified range")
225 .end
226
227
228 .sub parse_group
229 .param pmc mob
230 .local string target
231 .local pmc mfrom, mpos
232 .local int pos, lastpos
233 $P0 = find_global "PGE::Match", "newfrom"
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
234 (mob, target, mfrom, mpos) = $P0(mob, 0, "PGE::Exp::CGroup")
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
235 pos = mfrom
236 inc pos
237 $S0 = substr target, pos, 2
238 if $S0 == "?:" goto nocapture
239 goto end
240 nocapture:
241 pos += 2
242 end:
243 mpos = pos
244 .return (mob)
245 .end
246
247 .sub "parse_enumclass"
248 .param pmc mob
249 .local string target
250 .local pmc mfrom, mpos
251 .local int pos, lastpos
252 .local int isrange
253 .local string charlist
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
254 .local string key
255 key = mob['KEY']
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
256 $P0 = find_global "PGE::Match", "newfrom"
257 (mob, target, mfrom, mpos) = $P0(mob, 0, "PGE::Exp::EnumCharList")
258 pos = mfrom
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
259 if key == '.' goto dot
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
260 lastpos = length target
261 charlist = ""
262 mob["isnegated"] = 0
263 isrange = 0
264 $S0 = substr target, pos, 1
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
265 if $S0 != "^" goto scan_first
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
266 mob["isnegated"] = 1
267 inc pos
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
268 scan_first:
269 if pos >= lastpos goto err_close
270 $S0 = substr target, pos, 1
271 inc pos
272 if $S0 == "\\" goto backslash
273 goto addchar
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
274 scan:
275 if pos >= lastpos goto err_close
276 $S0 = substr target, pos, 1
277 inc pos
278 if $S0 == "]" goto endclass
279 if $S0 == "-" goto hyphenrange
280 if $S0 != "\\" goto addchar
281 backslash:
282 $S0 = substr target, pos, 1
283 inc pos
284 $I0 = index "nrtfae0b", $S0
285 if $I0 == -1 goto addchar
286 $S0 = substr "\n\r\t\f\a\e\0\b", $I0, 1
287 addchar:
288 if isrange goto addrange
289 charlist .= $S0
290 goto scan
291 addrange:
292 isrange = 0
293 $I2 = ord charlist, -1
294 $I0 = ord $S0
295 addrange_1:
296 inc $I2
297 if $I2 > $I0 goto scan
298 $S1 = chr $I2
299 charlist .= $S1
300 goto addrange_1
301 hyphenrange:
302 if isrange goto addrange
303 isrange = 1
304 goto scan
305 endclass:
306 if isrange == 0 goto end
307 charlist .= "-"
308 goto end
309 dot:
310 charlist = "\n"
311 mob["isnegated"] = 1
312 end:
313 mpos = pos
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
314 mob.set_value(charlist)
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
315 .return (mob)
316
317 err_close:
318 parse_error(mob, pos, "No closing ']' for enumerated character list")
319 .end
320
321
322 .namespace [ "PGE::Exp" ]
323
324 .sub "p5analyze" :method
325 .param pmc pad
326 .local pmc exp
327 $I0 = 0
328 loop:
329 $I1 = defined self[$I0]
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
330 if $I1 == 0 goto end
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
331 $P0 = self[$I0]
332 $P0 = $P0."p5analyze"(pad)
333 self[$I0] = $P0
334 inc $I0
335 goto loop
336 end:
337 .return (self)
338 .end
339
9cbdcbc Patrick R. Michaud Merge pge-pm branch with updated PGE into trunk.
pmichaud authored
340 .namespace [ "PGE::Exp::CGroup" ]
c346e6b Patrick R. Michaud * Added initial version of compreg "PGE::P5Regexp"
pmichaud authored
341
342 .sub "p5analyze" :method
343 .param pmc pad
344 .local pmc exp
345
346 self["iscapture"] = 0
347 if self != "(" goto end
348 self["iscapture"] = 1
349 self["isscope"] = 0
350 self["isarray"] = 0
351 $I0 = pad["subpats"]
352 self["cname"] = $I0
353 inc $I0
354 pad["subpats"] = $I0
355 end:
356 exp = self[0]
357 exp = exp."p5analyze"(pad)
358 self[0] = exp
359 .return (self)
360 .end
361
362
Something went wrong with that request. Please try again.