Skip to content

Commit e94394c

Browse files
Multimodcraftershilangyu
authored andcommitted
Fix cli tool and AST->HIR translation
1 parent 9c33cca commit e94394c

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

regex-cli/cmd/generate/fowler.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,5 @@ fn count_capturing_groups_ast(ast: &regex_syntax::ast::Ast) -> usize {
421421
Ast::Concat(ref concat) => {
422422
concat.asts.iter().map(count_capturing_groups_ast).sum()
423423
}
424-
Ast::LookAround(_) => todo!(),
425424
}
426425
}

regex-syntax/src/hir/translate.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,13 @@ enum HirFrame {
212212
/// This sentinel only exists to stop other things (like flattening
213213
/// literals) from reaching across repetition operators.
214214
Repetition,
215+
/// This is pushed whenever a look-around expression is observed. After
216+
/// visiting the sub-expression in the look-around, the translator's stack
217+
/// is expected to have this sentinel at the top.
218+
///
219+
/// This sentinel only exists to stop other things (like flattening
220+
/// literals) from reaching across look-around operators.
221+
LookAround,
215222
/// This is pushed on to the stack upon first seeing any kind of capture,
216223
/// indicated by parentheses (including non-capturing groups). It is popped
217224
/// upon leaving a group.
@@ -298,6 +305,18 @@ impl HirFrame {
298305
}
299306
}
300307

308+
fn unwrap_lookaround(self) {
309+
match self {
310+
HirFrame::LookAround => {}
311+
_ => {
312+
panic!(
313+
"tried to unwrap look-around from HirFrame, got: {:?}",
314+
self
315+
)
316+
}
317+
}
318+
}
319+
301320
/// Assert that the current stack frame is a group indicator and return
302321
/// its corresponding flags (the flags that were active at the time the
303322
/// group was entered).
@@ -363,6 +382,7 @@ impl<'t, 'p> Visitor for TranslatorI<'t, 'p> {
363382
self.push(HirFrame::AlternationBranch);
364383
}
365384
}
385+
Ast::LookAround(_) => self.push(HirFrame::LookAround),
366386
_ => {}
367387
}
368388
Ok(())
@@ -448,6 +468,7 @@ impl<'t, 'p> Visitor for TranslatorI<'t, 'p> {
448468
}
449469
Ast::LookAround(ref x) => {
450470
let expr = Box::new(self.pop().unwrap().unwrap_expr());
471+
self.pop().unwrap().unwrap_lookaround();
451472
self.push(HirFrame::Expr(Hir::lookaround(match x.kind {
452473
ast::LookAroundKind::PositiveLookBehind => {
453474
hir::LookAround::PositiveLookBehind(expr)
@@ -770,6 +791,9 @@ impl<'t, 'p> TranslatorI<'t, 'p> {
770791
HirFrame::AlternationBranch => {
771792
unreachable!("expected expr or concat, got alt branch marker")
772793
}
794+
HirFrame::LookAround => {
795+
unreachable!("expected expr or concat, got look-around")
796+
}
773797
}
774798
}
775799

@@ -801,6 +825,9 @@ impl<'t, 'p> TranslatorI<'t, 'p> {
801825
HirFrame::AlternationBranch => {
802826
unreachable!("expected expr or alt, got alt branch marker")
803827
}
828+
HirFrame::LookAround => {
829+
unreachable!("expected expr or alt, got look-around")
830+
}
804831
}
805832
}
806833

@@ -1612,6 +1639,15 @@ mod tests {
16121639
Hir::look(look)
16131640
}
16141641

1642+
fn hir_lookbehind(expr: Hir, positive: bool) -> Hir {
1643+
let lookaround = if positive {
1644+
hir::LookAround::PositiveLookBehind(Box::new(expr))
1645+
} else {
1646+
hir::LookAround::NegativeLookBehind(Box::new(expr))
1647+
};
1648+
Hir::lookaround(lookaround)
1649+
}
1650+
16151651
#[test]
16161652
fn empty() {
16171653
assert_eq!(t(""), Hir::empty());
@@ -1835,6 +1871,44 @@ mod tests {
18351871
assert_eq!(t(r"(?-u)\B"), hir_look(hir::Look::WordAsciiNegate));
18361872
}
18371873

1874+
#[test]
1875+
fn lookarounds() {
1876+
assert_eq!(t("(?<=a)"), hir_lookbehind(hir_lit("a"), true));
1877+
assert_eq!(t("(?<!a)"), hir_lookbehind(hir_lit("a"), false));
1878+
assert_eq!(t("(?<!)"), hir_lookbehind(Hir::empty(), false));
1879+
assert_eq!(
1880+
t("(?<=a|b)"),
1881+
hir_lookbehind(hir_alt(vec![hir_lit("a"), hir_lit("b")]), true)
1882+
);
1883+
assert_eq!(
1884+
t("(?<=a)|(?<!b)"),
1885+
hir_alt(vec![
1886+
hir_lookbehind(hir_lit("a"), true),
1887+
hir_lookbehind(hir_lit("b"), false)
1888+
])
1889+
);
1890+
assert_eq!(
1891+
t("(?<=a)(?<!b)"),
1892+
hir_cat(vec![
1893+
hir_lookbehind(hir_lit("a"), true),
1894+
hir_lookbehind(hir_lit("b"), false)
1895+
])
1896+
);
1897+
assert_eq!(
1898+
t("a(?<=ba(?<!c))"),
1899+
hir_cat(vec![
1900+
hir_lit("a"),
1901+
hir_lookbehind(
1902+
hir_cat(vec![
1903+
hir_lit("ba"),
1904+
hir_lookbehind(hir_lit("c"), false)
1905+
]),
1906+
true
1907+
)
1908+
])
1909+
);
1910+
}
1911+
18381912
#[test]
18391913
fn group() {
18401914
assert_eq!(t("(a)"), hir_capture(1, hir_lit("a")));

0 commit comments

Comments
 (0)