@@ -41,7 +41,9 @@ enum State {
4141    } , 
4242    /// A state that only transitions to another state if the current input 
4343     /// byte is in a particular range of bytes. 
44-      ByteRange  {  trans :  Transition  } , 
44+      ByteRange  { 
45+         trans :  Transition , 
46+     } , 
4547    /// A state with possibly many transitions, represented in a sparse 
4648     /// fashion. Transitions must be ordered lexicographically by input range 
4749     /// and be non-overlapping. As such, this may only be used when every 
@@ -55,10 +57,15 @@ enum State {
5557     /// that `Sparse` is used for via `Union`. But this creates a more bloated 
5658     /// NFA with more epsilon transitions than is necessary in the special case 
5759     /// of character classes. 
58-      Sparse  {  transitions :  Vec < Transition >  } , 
60+      Sparse  { 
61+         transitions :  Vec < Transition > , 
62+     } , 
5963    /// A conditional epsilon transition satisfied via some sort of 
6064     /// look-around. 
61-      Look  {  look :  Look ,  next :  StateID  } , 
65+      Look  { 
66+         look :  Look , 
67+         next :  StateID , 
68+     } , 
6269    /// An empty state that records the start of a capture location. This is an 
6370     /// unconditional epsilon transition like `Empty`, except it can be used to 
6471     /// record position information for a capture group when using the NFA for 
@@ -91,10 +98,20 @@ enum State {
9198        /// The next state that this state should transition to. 
9299         next :  StateID , 
93100    } , 
101+     WriteLookaround  { 
102+         lookaround_index :  usize , 
103+     } , 
104+     CheckLookaround  { 
105+         lookaround_index :  usize , 
106+         positive :  bool , 
107+         next :  StateID , 
108+     } , 
94109    /// An alternation such that there exists an epsilon transition to all 
95110     /// states in `alternates`, where matches found via earlier transitions 
96111     /// are preferred over later transitions. 
97-      Union  {  alternates :  Vec < StateID >  } , 
112+      Union  { 
113+         alternates :  Vec < StateID > , 
114+     } , 
98115    /// An alternation such that there exists an epsilon transition to all 
99116     /// states in `alternates`, where matches found via later transitions are 
100117     /// preferred over earlier transitions. 
@@ -110,7 +127,9 @@ enum State {
110127     /// to be amortized constant time. But if we used a `Union`, we'd need to 
111128     /// prepend the state, which takes O(n) time. There are other approaches we 
112129     /// could use to solve this, but this seems simple enough. 
113-      UnionReverse  {  alternates :  Vec < StateID >  } , 
130+      UnionReverse  { 
131+         alternates :  Vec < StateID > , 
132+     } , 
114133    /// A state that cannot be transitioned out of. This is useful for cases 
115134     /// where you want to prevent matching from occurring. For example, if your 
116135     /// regex parser permits empty character classes, then one could choose a 
@@ -124,7 +143,9 @@ enum State {
124143     /// 
125144     /// `pattern_id` refers to the ID of the pattern itself, which corresponds 
126145     /// to the pattern's index (starting at 0). 
127-      Match  {  pattern_id :  PatternID  } , 
146+      Match  { 
147+         pattern_id :  PatternID , 
148+     } , 
128149} 
129150
130151impl  State  { 
@@ -154,7 +175,9 @@ impl State {
154175            | State :: CaptureStart  {  .. } 
155176            | State :: CaptureEnd  {  .. } 
156177            | State :: Fail 
157-             | State :: Match  {  .. }  => 0 , 
178+             | State :: Match  {  .. } 
179+             | State :: CheckLookaround  {  .. } 
180+             | State :: WriteLookaround  {  .. }  => 0 , 
158181            State :: Sparse  {  ref  transitions }  => { 
159182                transitions. len ( )  *  mem:: size_of :: < Transition > ( ) 
160183            } 
@@ -470,6 +493,22 @@ impl Builder {
470493                State :: Look  {  look,  next }  => { 
471494                    remap[ sid]  = nfa. add ( nfa:: State :: Look  {  look,  next } ) ; 
472495                } 
496+                 State :: WriteLookaround  {  lookaround_index }  => { 
497+                     remap[ sid]  = nfa. add ( nfa:: State :: WriteLookaround  { 
498+                         look_idx :  lookaround_index, 
499+                     } ) ; 
500+                 } 
501+                 State :: CheckLookaround  { 
502+                     lookaround_index, 
503+                     positive, 
504+                     next, 
505+                 }  => { 
506+                     remap[ sid]  = nfa. add ( nfa:: State :: CheckLookaround  { 
507+                         look_idx :  lookaround_index, 
508+                         positive, 
509+                         next, 
510+                     } ) ; 
511+                 } 
473512                State :: CaptureStart  {  pattern_id,  group_index,  next }  => { 
474513                    // We can't remove this empty state because of the side 
475514                    // effect of capturing an offset for this capture slot. 
@@ -693,6 +732,30 @@ impl Builder {
693732        self . add ( State :: Empty  {  next :  StateID :: ZERO  } ) 
694733    } 
695734
735+     /// Add a state which will record that the lookaround with the given index 
736+      /// is satisfied at the current position. 
737+      pub  fn  add_write_lookaround ( 
738+         & mut  self , 
739+         index :  usize , 
740+     )  -> Result < StateID ,  BuildError >  { 
741+         self . add ( State :: WriteLookaround  {  lookaround_index :  index } ) 
742+     } 
743+ 
744+     /// Add a state which will check whether the lookaround with the given 
745+      /// index is satisfied at the current position. 
746+      pub  fn  add_check_lookaround ( 
747+         & mut  self , 
748+         index :  usize , 
749+         positive :  bool , 
750+         next :  StateID , 
751+     )  -> Result < StateID ,  BuildError >  { 
752+         self . add ( State :: CheckLookaround  { 
753+             lookaround_index :  index, 
754+             positive, 
755+             next, 
756+         } ) 
757+     } 
758+ 
696759    /// Add a "union" NFA state. 
697760     /// 
698761     /// A "union" NFA state that contains zero or more unconditional epsilon 
@@ -1159,6 +1222,9 @@ impl Builder {
11591222            State :: Look  {  ref  mut  next,  .. }  => { 
11601223                * next = to; 
11611224            } 
1225+             State :: CheckLookaround  {  ref  mut  next,  .. }  => { 
1226+                 * next = to; 
1227+             } 
11621228            State :: Union  {  ref  mut  alternates }  => { 
11631229                alternates. push ( to) ; 
11641230                self . memory_states  += mem:: size_of :: < StateID > ( ) ; 
@@ -1173,6 +1239,7 @@ impl Builder {
11731239            State :: CaptureEnd  {  ref  mut  next,  .. }  => { 
11741240                * next = to; 
11751241            } 
1242+             State :: WriteLookaround  {  .. }  => { } 
11761243            State :: Fail  => { } 
11771244            State :: Match  {  .. }  => { } 
11781245        } 
0 commit comments