Skip to content
This repository was archived by the owner on Mar 22, 2024. It is now read-only.

Commit 2366311

Browse files
committed
impl opinfo literal
1 parent c4f10ed commit 2366311

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

src/engine.rs

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,17 @@ impl<S: StrDrive> State<S> {
256256
/* <length> <skip> <prefix data> <overlap data> */
257257
let len = ctx.peek_code(req, 5) as usize;
258258
let skip = ctx.peek_code(req, 6) as usize;
259-
let prefix = &ctx.pattern(req)[7..];
260-
let overlap = &prefix[len - 1..];
259+
let prefix = &ctx.pattern(req)[7..7 + len];
260+
let overlap = &ctx.pattern(req)[7 + len - 1..7 + len * 2];
261261

262262
if len == 1 {
263263
// pattern starts with a literal character
264-
ctx.skip_code_from(req, 1);
265264
let c = prefix[0];
265+
266+
// code_position ready for tail match
267+
ctx.skip_code_from(req, 1);
268+
ctx.skip_code(2 * skip);
269+
266270
req.must_advance = false;
267271

268272
while !ctx.at_end(req) {
@@ -275,9 +279,8 @@ impl<S: StrDrive> State<S> {
275279
}
276280

277281
req.start = ctx.string_position;
278-
self.reset(req.start);
279-
// self.start = ctx.string_position;
280-
self.string_position += skip;
282+
self.start = ctx.string_position;
283+
self.string_position = ctx.string_position + skip;
281284

282285
// literal only
283286
if flags.contains(SreInfo::LITERAL) {
@@ -287,7 +290,6 @@ impl<S: StrDrive> State<S> {
287290

288291
let mut next_ctx = ctx;
289292
next_ctx.skip_char(req, skip);
290-
next_ctx.skip_code(2 * skip);
291293

292294
self.context_stack.push(next_ctx);
293295
self._match(req);
@@ -297,6 +299,71 @@ impl<S: StrDrive> State<S> {
297299
}
298300

299301
ctx.skip_char(req, 1);
302+
self.marks.clear();
303+
}
304+
return;
305+
} else if len > 1 {
306+
// code_position ready for tail match
307+
ctx.skip_code_from(req, 1);
308+
ctx.skip_code(2 * skip);
309+
310+
req.must_advance = false;
311+
312+
while !ctx.at_end(req) {
313+
let c = prefix[0];
314+
while ctx.peek_char(req) != c {
315+
ctx.skip_char(req, 1);
316+
if ctx.at_end(req) {
317+
return;
318+
}
319+
}
320+
ctx.skip_char(req, 1);
321+
if ctx.at_end(req) {
322+
return;
323+
}
324+
325+
let mut i = 1;
326+
loop {
327+
if ctx.peek_char(req) == prefix[i] {
328+
i += 1;
329+
if i != len {
330+
ctx.skip_char(req, 1);
331+
if ctx.at_end(req) {
332+
return;
333+
}
334+
continue;
335+
}
336+
337+
req.start = ctx.string_position - (len - 1);
338+
self.start = req.start;
339+
self.string_position = self.start + skip;
340+
341+
if flags.contains(SreInfo::LITERAL) {
342+
self.has_matched = true;
343+
return;
344+
}
345+
346+
let mut next_ctx = ctx;
347+
// next_ctx.skip_char(req, 1);
348+
next_ctx.string_position = self.string_position;
349+
next_ctx.string_offset = req.string.offset(0, self.string_position);
350+
self.context_stack.push(next_ctx);
351+
self._match(req);
352+
if self.has_matched {
353+
return;
354+
}
355+
356+
ctx.skip_char(req, 1);
357+
if ctx.at_end(req) {
358+
return;
359+
}
360+
self.marks.clear();
361+
}
362+
i = overlap[i] as usize;
363+
if i == 0 {
364+
break;
365+
}
366+
}
300367
}
301368
return;
302369
}

tests/tests.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,25 @@ fn test_info_single2() {
105105
state.search(req);
106106
assert!(state.has_matched);
107107
}
108+
109+
#[test]
110+
fn test_info_literal() {
111+
// pattern p = re.compile(r'ababc+')
112+
// START GENERATED by generate_tests.py
113+
#[rustfmt::skip] let p = Pattern { code: &[15, 14, 1, 5, 4294967295, 4, 4, 97, 98, 97, 98, 0, 0, 1, 2, 17, 97, 17, 98, 17, 97, 17, 98, 25, 6, 1, 4294967295, 17, 99, 1, 1] };
114+
// END GENERATED
115+
let (req, mut state) = p.state("!ababc");
116+
state.search(req);
117+
assert!(state.has_matched);
118+
}
119+
120+
#[test]
121+
fn test_info_literal2() {
122+
// pattern p = re.compile(r'(python)\1')
123+
// START GENERATED by generate_tests.py
124+
#[rustfmt::skip] let p = Pattern { code: &[15, 18, 1, 12, 12, 6, 0, 112, 121, 116, 104, 111, 110, 0, 0, 0, 0, 0, 0, 18, 0, 17, 112, 17, 121, 17, 116, 17, 104, 17, 111, 17, 110, 18, 1, 12, 0, 1] };
125+
// END GENERATED
126+
let (req, mut state) = p.state("pythonpython");
127+
state.search(req);
128+
assert!(state.has_matched);
129+
}

0 commit comments

Comments
 (0)