@@ -477,6 +477,9 @@ pub enum Ast {
477477 Dot ( Box < Span > ) ,
478478 /// A single zero-width assertion.
479479 Assertion ( Box < Assertion > ) ,
480+ #[ cfg( feature = "look-behinds" ) ]
481+ /// A single look-around regular expression.
482+ LookAround ( Box < LookAround > ) ,
480483 /// A single Unicode character class, e.g., `\pL` or `\p{Greek}`.
481484 ClassUnicode ( Box < ClassUnicode > ) ,
482485 /// A single perl character class, e.g., `\d` or `\W`.
@@ -521,6 +524,12 @@ impl Ast {
521524 Ast :: Assertion ( Box :: new ( e) )
522525 }
523526
527+ /// Create a "look-around" AST item.
528+ #[ cfg( feature = "look-behinds" ) ]
529+ pub fn lookaround ( e : LookAround ) -> Ast {
530+ Ast :: LookAround ( Box :: new ( e) )
531+ }
532+
524533 /// Create a "Unicode class" AST item.
525534 pub fn class_unicode ( e : ClassUnicode ) -> Ast {
526535 Ast :: ClassUnicode ( Box :: new ( e) )
@@ -564,6 +573,8 @@ impl Ast {
564573 Ast :: Literal ( ref x) => & x. span ,
565574 Ast :: Dot ( ref span) => span,
566575 Ast :: Assertion ( ref x) => & x. span ,
576+ #[ cfg( feature = "look-behinds" ) ]
577+ Ast :: LookAround ( ref x) => & x. span ,
567578 Ast :: ClassUnicode ( ref x) => & x. span ,
568579 Ast :: ClassPerl ( ref x) => & x. span ,
569580 Ast :: ClassBracketed ( ref x) => & x. span ,
@@ -598,6 +609,8 @@ impl Ast {
598609 | Ast :: Group ( _)
599610 | Ast :: Alternation ( _)
600611 | Ast :: Concat ( _) => true ,
612+ #[ cfg( feature = "look-behinds" ) ]
613+ Ast :: LookAround ( _) => true ,
601614 }
602615 }
603616}
@@ -1342,6 +1355,28 @@ pub enum AssertionKind {
13421355 WordBoundaryEndHalf ,
13431356}
13441357
1358+ /// A single zero-width look-around.
1359+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
1360+ #[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
1361+ pub struct LookAround {
1362+ /// The span of this look-around.
1363+ pub span : Span ,
1364+ /// The look-around kind, e.g. negative/positive look-behind.
1365+ pub kind : LookAroundKind ,
1366+ /// The regular expression inside the look-around.
1367+ pub ast : Box < Ast > ,
1368+ }
1369+
1370+ /// A look-around kind.
1371+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
1372+ #[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
1373+ pub enum LookAroundKind {
1374+ /// `(?<=...)`
1375+ PositiveLookBehind ,
1376+ /// `(?<!...)`
1377+ NegativeLookBehind ,
1378+ }
1379+
13451380/// A repetition operation applied to a regular expression.
13461381#[ derive( Clone , Debug , Eq , PartialEq ) ]
13471382#[ cfg_attr( feature = "arbitrary" , derive( arbitrary:: Arbitrary ) ) ]
@@ -1647,6 +1682,8 @@ impl Drop for Ast {
16471682 | Ast :: ClassBracketed ( _) => return ,
16481683 Ast :: Repetition ( ref x) if !x. ast . has_subexprs ( ) => return ,
16491684 Ast :: Group ( ref x) if !x. ast . has_subexprs ( ) => return ,
1685+ #[ cfg( feature = "look-behinds" ) ]
1686+ Ast :: LookAround ( ref x) if !x. ast . has_subexprs ( ) => return ,
16501687 Ast :: Alternation ( ref x) if x. asts . is_empty ( ) => return ,
16511688 Ast :: Concat ( ref x) if x. asts . is_empty ( ) => return ,
16521689 _ => { }
@@ -1673,6 +1710,10 @@ impl Drop for Ast {
16731710 Ast :: Group ( ref mut x) => {
16741711 stack. push ( mem:: replace ( & mut x. ast , empty_ast ( ) ) ) ;
16751712 }
1713+ #[ cfg( feature = "look-behinds" ) ]
1714+ Ast :: LookAround ( ref mut x) => {
1715+ stack. push ( mem:: replace ( & mut x. ast , empty_ast ( ) ) ) ;
1716+ }
16761717 Ast :: Alternation ( ref mut x) => {
16771718 stack. extend ( x. asts . drain ( ..) ) ;
16781719 }
0 commit comments