Skip to content

Commit 87bc27e

Browse files
committed
Fixes #153.
The zero-or-one alternation (i.e., `?`) was not being patched correctly. It was erroneously assuming that one of its holes always pointed to a subsequently instruction. This is not the case when it is itself at the end of an enclosing alternation. We fix this by exposing that hole so that it is patched with the correct instruction by the enclosing alternation.
1 parent 38b4a76 commit 87bc27e

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

regex_macros/tests/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ fn regression_captures_rep() {
384384
assert_eq!(caps.name("foo").unwrap(), "x");
385385
}
386386

387+
// Regression test for https://github.com/rust-lang-nursery/regex/issues/153
388+
mat!(regression_alt_in_alt1, r"ab?|$", "az", Some((0, 1)));
389+
mat!(regression_alt_in_alt2, r"^(.*?)(\n|\r\n?|$)", "ab\rcd", Some((0, 3)));
390+
387391
// A whole mess of tests from Glenn Fowler's regex test suite.
388392
// Generated by the 'src/etc/regex-match-tests' program.
389393
#[path = "matches.rs"]

src/compile.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,14 @@ impl Compiler {
187187
) -> CompileResult {
188188
let split = self.push_split_hole();
189189
let goto1 = self.insts.len();
190-
let hole = try!(self.c(expr));
191-
let goto2 = self.insts.len();
190+
let hole1 = try!(self.c(expr));
192191

193-
if greedy {
194-
self.fill_split(split, Some(goto1), Some(goto2));
192+
let hole2 = if greedy {
193+
self.fill_split(split, Some(goto1), None)
195194
} else {
196-
self.fill_split(split, Some(goto2), Some(goto1));
197-
}
198-
Ok(hole)
195+
self.fill_split(split, None, Some(goto1))
196+
};
197+
Ok(Hole::Many(vec![hole1, hole2]))
199198
}
200199

201200
fn c_repeat_zero_or_more(

0 commit comments

Comments
 (0)