use nom::branch::alt; use nom::bytes::complete::{escaped, is_not, tag, take_till}; use nom::character::complete::char; use nom::character::complete::{anychar, digit1}; use nom::combinator::{eof, map, not, opt, recognize, value}; use nom::error::ErrorKind; use nom::multi::separated_list1; use nom::sequence::{delimited, pair, tuple}; use nom::{error_position, AsChar, IResult, InputTakeAtPosition};
for (i, b) in i.chars().enumerate() { if !(b == '(' || b == ')') || !in_str { match b { '(' => nested += 1, ')' => { if nested == 0 {
last = i; break;
}
nested -= 1;
} '"' => { if in_str { if !escaped {
in_str = false;
}
} else {
in_str = true;
}
} '\\' => {
escaped = !escaped;
}
_ => (),
}
}
if escaped && b != '\\' {
escaped = false;
}
}
if nested == 0 {
Ok((&i[last..], ()))
} else {
Err(nom::Err::Error(error_position!(
i,
ErrorKind::SeparatedNonEmptyList
)))
}
}
fn path(i: &str) -> IResult<&str, Vec<&str>> { let root = opt(value("", ws(tag("::")))); let tail = separated_list1(ws(tag("::")), identifier);
match tuple((root, identifier, ws(tag("::")), tail))(i) {
Ok((i, (root, start, _, rest))) => { letmut path = Vec::new();
path.extend(root);
path.push(start);
path.extend(rest);
Ok((i, path))
}
Err(err) => { iflet Ok((i, name)) = identifier(i) { // The returned identifier can be assumed to be path if: // - Contains both a lowercase and uppercase character, i.e. a type name like `None` // - Doesn't contain any lowercase characters, i.e. it's a constant // In short, if it contains any uppercase characters it's a path. if name.contains(char::is_uppercase) { return Ok((i, vec![name]));
}
}
// If `identifier()` fails then just return the original error
Err(err)
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.