summaryrefslogtreecommitdiff
path: root/vendor/logos-codegen/src/parser/subpattern.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/logos-codegen/src/parser/subpattern.rs')
-rw-r--r--vendor/logos-codegen/src/parser/subpattern.rs97
1 files changed, 0 insertions, 97 deletions
diff --git a/vendor/logos-codegen/src/parser/subpattern.rs b/vendor/logos-codegen/src/parser/subpattern.rs
deleted file mode 100644
index eb620028..00000000
--- a/vendor/logos-codegen/src/parser/subpattern.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-use proc_macro2::TokenStream;
-use syn::Ident;
-
-use crate::error::Errors;
-use crate::mir::Mir;
-use crate::parser::definition::{bytes_to_regex_string, Literal};
-
-#[derive(Default)]
-pub struct Subpatterns {
- map: Vec<(Ident, String)>,
-}
-
-impl Subpatterns {
- pub fn add(&mut self, param: Ident, pattern: TokenStream, errors: &mut Errors) {
- let lit = match syn::parse2::<Literal>(pattern) {
- Ok(lit) => lit,
- Err(e) => {
- errors.err(e.to_string(), e.span());
- return;
- }
- };
-
- if let Some((name, _)) = self.map.iter().find(|(name, _)| *name == param) {
- errors
- .err(format!("{} can only be assigned once", param), param.span())
- .err("Previously assigned here", name.span());
- return;
- }
-
- let fixed = self.fix(&lit, errors);
-
- // Validate the literal as proper regex. If it's not, emit an error.
- let mir = match &lit {
- Literal::Utf8(_) => Mir::utf8(&fixed),
- Literal::Bytes(_) => Mir::binary(&fixed),
- };
-
- if let Err(err) = mir {
- errors.err(err, lit.span());
- };
-
- self.map.push((param, fixed));
- }
-
- pub fn fix(&self, lit: &Literal, errors: &mut Errors) -> String {
- let mut i = 0;
- let mut pattern = match lit {
- Literal::Utf8(s) => s.value(),
- Literal::Bytes(b) => bytes_to_regex_string(b.value()),
- };
-
- while let Some(f) = pattern[i..].find("(?&") {
- i += f;
- pattern.replace_range(i..i + 3, "(?:");
- i += 3;
-
- let subref_end = if let Some(f) = pattern[i..].find(')') {
- i + f
- } else {
- pattern.truncate(i); // truncate so latter error doesn't suppress
- break; // regex-syntax will report the unclosed group
- };
-
- let name = &pattern[i..subref_end];
- let name = match syn::parse_str::<Ident>(name) {
- Ok(name) => name,
- Err(_) => {
- errors.err(
- format!("subpattern reference `{}` is not an identifier", name),
- lit.span(),
- );
- // we emitted the error; make something up and continue
- pattern.replace_range(i..subref_end, "_");
- i += 2;
- continue;
- }
- };
-
- match self.map.iter().find(|(def, _)| *def == name) {
- Some((_, subpattern)) => {
- pattern.replace_range(i..subref_end, subpattern);
- i += subpattern.len() + 1;
- }
- None => {
- errors.err(
- format!("subpattern reference `{}` has not been defined", name),
- lit.span(),
- );
- // leaving `(?:name)` is fine
- i = subref_end + 1;
- }
- }
- }
-
- pattern
- }
-}