Build an executor that can run a regular expression.
(self)
| 288 | |
| 289 | /// Build an executor that can run a regular expression. |
| 290 | pub fn build(self) -> Result<Exec, Error> { |
| 291 | // Special case when we have no patterns to compile. |
| 292 | // This can happen when compiling a regex set. |
| 293 | if self.options.pats.is_empty() { |
| 294 | let ro = Arc::new(ExecReadOnly { |
| 295 | res: vec![], |
| 296 | nfa: Program::new(), |
| 297 | dfa: Program::new(), |
| 298 | dfa_reverse: Program::new(), |
| 299 | suffixes: LiteralSearcher::empty(), |
| 300 | ac: None, |
| 301 | match_type: MatchType::Nothing, |
| 302 | }); |
| 303 | return Ok(Exec { ro: ro, cache: CachedThreadLocal::new() }); |
| 304 | } |
| 305 | let parsed = self.parse()?; |
| 306 | let mut nfa = |
| 307 | Compiler::new() |
| 308 | .size_limit(self.options.size_limit) |
| 309 | .bytes(self.bytes || parsed.bytes) |
| 310 | .only_utf8(self.only_utf8) |
| 311 | .compile(&parsed.exprs)?; |
| 312 | let mut dfa = |
| 313 | Compiler::new() |
| 314 | .size_limit(self.options.size_limit) |
| 315 | .dfa(true) |
| 316 | .only_utf8(self.only_utf8) |
| 317 | .compile(&parsed.exprs)?; |
| 318 | let mut dfa_reverse = |
| 319 | Compiler::new() |
| 320 | .size_limit(self.options.size_limit) |
| 321 | .dfa(true) |
| 322 | .only_utf8(self.only_utf8) |
| 323 | .reverse(true) |
| 324 | .compile(&parsed.exprs)?; |
| 325 | |
| 326 | let prefixes = parsed.prefixes.unambiguous_prefixes(); |
| 327 | let suffixes = parsed.suffixes.unambiguous_suffixes(); |
| 328 | nfa.prefixes = LiteralSearcher::prefixes(prefixes); |
| 329 | dfa.prefixes = nfa.prefixes.clone(); |
| 330 | dfa.dfa_size_limit = self.options.dfa_size_limit; |
| 331 | dfa_reverse.dfa_size_limit = self.options.dfa_size_limit; |
| 332 | |
| 333 | let mut ac = None; |
| 334 | if parsed.exprs.len() == 1 { |
| 335 | if let Some(lits) = alternation_literals(&parsed.exprs[0]) { |
| 336 | // If we have a small number of literals, then let Teddy |
| 337 | // handle things (see literal/mod.rs). |
| 338 | if lits.len() > 32 { |
| 339 | let fsm = AhoCorasickBuilder::new() |
| 340 | .match_kind(MatchKind::LeftmostFirst) |
| 341 | .auto_configure(&lits) |
| 342 | // We always want this to reduce size, regardless of |
| 343 | // what auto-configure does. |
| 344 | .byte_classes(true) |
| 345 | .build_with_size::<u32, _, _>(&lits) |
| 346 | .expect("AC automaton too big"); |
| 347 | ac = Some(fsm); |