parse lifetimes
This commit is contained in:
parent
53fc09c02f
commit
47f4c1e8c2
6 changed files with 402 additions and 12 deletions
|
|
@ -156,6 +156,28 @@ pub enum Token<'a> {
|
|||
/// ```
|
||||
None,
|
||||
|
||||
/// A lifetime, a la rust. The rules for this are pretty restrictive.
|
||||
/// A lifetime must be, a single quote, followed by no more than 3 ascii lowercase alphabetic characters,
|
||||
/// followed by *not* a closing quote, and any nonalphabetic character. Like a comma,
|
||||
/// whitespace, eof, etc.
|
||||
///
|
||||
/// ```
|
||||
/// # logparse::generate_ast_recognizer!(is_lt, Token::Lifetime(_));
|
||||
///
|
||||
/// assert!(is_lt("'a"));
|
||||
/// assert!(is_lt("'tcx"));
|
||||
///
|
||||
/// // some counterexamples
|
||||
///
|
||||
/// assert!(!is_lt("'verylong"));
|
||||
/// assert!(!is_lt("'foo'"));
|
||||
/// assert!(!is_lt("'a'"));
|
||||
/// assert!(!is_lt("'a longer single-quoted string'"));
|
||||
/// assert!(!is_lt("a"));
|
||||
/// assert!(!is_lt("13"));
|
||||
/// ``
|
||||
Lifetime(Cow<'a, str>),
|
||||
|
||||
/// A path, anything that looks vaguely path-like.
|
||||
/// For example:
|
||||
///
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ impl<'a> Display for Token<'a> {
|
|||
} => write!(f, "{before}{space_before}{separator}{after}"),
|
||||
Token::Delimited(delimited) => write!(f, "{delimited}"),
|
||||
Token::String(s) => write!(f, "{s}"),
|
||||
Token::Lifetime(s) => write!(f, "'{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,11 +263,30 @@ impl<'a> Atom<'a> {
|
|||
|
||||
impl<'a> Token<'a> {
|
||||
fn parse_without_separator<E: ParserError<&'a str> + 'a>() -> impl Parser<&'a str, Self, E> {
|
||||
use winnow::{combinator::*, prelude::*};
|
||||
use winnow::{combinator::*, prelude::*, token::*};
|
||||
|
||||
let delimited: Box<dyn Parser<&'a str, Self, E>> =
|
||||
Box::new(Delimited::parse().map(Self::Delimited));
|
||||
|
||||
let lifetime = (
|
||||
"'",
|
||||
alt((
|
||||
repeat::<_, _, Cow<'a, str>, _, _>(
|
||||
1..=3,
|
||||
any.verify(|i: &char| i.is_ascii_lowercase() || *i == '_'),
|
||||
)
|
||||
.take(),
|
||||
"{erased}",
|
||||
)),
|
||||
peek(alt((
|
||||
any::<&str, _>
|
||||
.verify(|i: &char| !i.is_alphabetic() && *i != '\'')
|
||||
.value(()),
|
||||
eof::<&str, _>.value(()),
|
||||
))),
|
||||
)
|
||||
.map(|(_, lifetime, _)| Token::Lifetime(lifetime.into()));
|
||||
|
||||
trace(
|
||||
"token-without-sep",
|
||||
alt((
|
||||
|
|
@ -276,6 +295,7 @@ impl<'a> Token<'a> {
|
|||
"None".value(Self::None),
|
||||
Number::parse().map(Self::Number),
|
||||
Path::parse().map(Self::Path),
|
||||
lifetime,
|
||||
AnyString::parse().map(Self::String),
|
||||
delimited,
|
||||
Atom::parse(|| {
|
||||
|
|
@ -1116,14 +1136,8 @@ mod tests {
|
|||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: String(
|
||||
AnyString {
|
||||
prefix: "",
|
||||
ty: Single,
|
||||
contents: "_, ",
|
||||
num_hashtags: 0,
|
||||
suffix: "",
|
||||
},
|
||||
token: Lifetime(
|
||||
"_",
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
|
|
@ -1132,10 +1146,18 @@ mod tests {
|
|||
),
|
||||
token: Atom(
|
||||
Text(
|
||||
"_",
|
||||
",",
|
||||
),
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
" ",
|
||||
),
|
||||
token: Lifetime(
|
||||
"_",
|
||||
),
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
|
|
@ -1251,4 +1273,342 @@ mod tests {
|
|||
}
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_ex2() {
|
||||
assert_debug_snapshot!(parse(r#"super_combine_consts::<rustc_type_ir::relate::solver_relating::SolverRelating<'_, rustc_infer::infer::InferCtxt<'_>, rustc_middle::ty::context::TyCtxt<'_>>>(?1c, ?2c)"#), @r#"
|
||||
Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"super_combine_consts",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Delimited(
|
||||
Delimited {
|
||||
prefix: None,
|
||||
delimiter: Angle,
|
||||
contents: Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"rustc_type_ir",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"relate",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"solver_relating",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Delimited(
|
||||
Delimited {
|
||||
prefix: Some(
|
||||
(
|
||||
Text(
|
||||
"SolverRelating",
|
||||
),
|
||||
Space(
|
||||
"",
|
||||
),
|
||||
),
|
||||
),
|
||||
delimiter: Angle,
|
||||
contents: Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Lifetime(
|
||||
"_",
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Atom(
|
||||
Text(
|
||||
",",
|
||||
),
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
" ",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"rustc_infer",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"infer",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Delimited(
|
||||
Delimited {
|
||||
prefix: Some(
|
||||
(
|
||||
Text(
|
||||
"InferCtxt",
|
||||
),
|
||||
Space(
|
||||
"",
|
||||
),
|
||||
),
|
||||
),
|
||||
delimiter: Angle,
|
||||
contents: Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Lifetime(
|
||||
"_",
|
||||
),
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Atom(
|
||||
Text(
|
||||
",",
|
||||
),
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
" ",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"rustc_middle",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"ty",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Separated {
|
||||
before: Atom(
|
||||
Text(
|
||||
"context",
|
||||
),
|
||||
),
|
||||
space_before: Space(
|
||||
"",
|
||||
),
|
||||
separator: DoubleColon,
|
||||
after: Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Delimited(
|
||||
Delimited {
|
||||
prefix: Some(
|
||||
(
|
||||
Text(
|
||||
"TyCtxt",
|
||||
),
|
||||
Space(
|
||||
"",
|
||||
),
|
||||
),
|
||||
),
|
||||
delimiter: Angle,
|
||||
contents: Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Lifetime(
|
||||
"_",
|
||||
),
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Delimited(
|
||||
Delimited {
|
||||
prefix: None,
|
||||
delimiter: Paren,
|
||||
contents: Segments {
|
||||
segments: [
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
"",
|
||||
),
|
||||
token: Atom(
|
||||
Text(
|
||||
"?1c,",
|
||||
),
|
||||
),
|
||||
},
|
||||
Segment {
|
||||
leading_space: Space(
|
||||
" ",
|
||||
),
|
||||
token: Atom(
|
||||
Text(
|
||||
"?2c",
|
||||
),
|
||||
),
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
trailing_space: Space(
|
||||
"",
|
||||
),
|
||||
}
|
||||
"#)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ pub enum SpanKind {
|
|||
Number,
|
||||
/// Known literals, like `true`, `false`, `None`, `Ok`, `Err`
|
||||
Literal,
|
||||
/// Lifetimes (`'foo`)
|
||||
Lifetime,
|
||||
/// Strings
|
||||
String,
|
||||
/// Paths
|
||||
|
|
@ -193,6 +195,10 @@ mod private {
|
|||
Token::Atom(atom) => {
|
||||
atom.into_spans(cx);
|
||||
}
|
||||
Token::Lifetime(lifetime) => {
|
||||
cx.push("'", SpanKind::Surroundings);
|
||||
cx.push(lifetime, SpanKind::Lifetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ mod tests {
|
|||
println!("undo");
|
||||
f.undo();
|
||||
c.update_with_parents(&f);
|
||||
assert_eq!(c.curr().message_or_name(), Some("nest"));
|
||||
assert_eq!(c.curr().message_or_name(), Some("enter"));
|
||||
assert!(c.next(&f));
|
||||
assert_eq!(c.curr().message_or_name(), Some("bar"));
|
||||
assert!(!c.next(&f));
|
||||
|
|
|
|||
|
|
@ -165,12 +165,13 @@ pub fn style_span(kind: SpanKind, style: Style, styles: &Styles) -> Style {
|
|||
SpanKind::Delimiter(_) => style.fg(styles.delimiter).bold(),
|
||||
SpanKind::Separator => style.fg(styles.faded),
|
||||
SpanKind::Number => style.fg(styles.literal),
|
||||
SpanKind::Literal => style.fg(styles.literal).dim(),
|
||||
SpanKind::Literal => style.fg(styles.literal),
|
||||
SpanKind::String => style.fg(styles.string),
|
||||
SpanKind::Path => style.fg(styles.literal).underlined(),
|
||||
SpanKind::Space(_) => style,
|
||||
SpanKind::Constructor => style.fg(styles.literal),
|
||||
SpanKind::Surroundings => style.fg(styles.faded),
|
||||
SpanKind::Lifetime => style.fg(styles.faded),
|
||||
SpanKind::Text => style,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue