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,
|
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.
|
/// A path, anything that looks vaguely path-like.
|
||||||
/// For example:
|
/// For example:
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ impl<'a> Display for Token<'a> {
|
||||||
} => write!(f, "{before}{space_before}{separator}{after}"),
|
} => write!(f, "{before}{space_before}{separator}{after}"),
|
||||||
Token::Delimited(delimited) => write!(f, "{delimited}"),
|
Token::Delimited(delimited) => write!(f, "{delimited}"),
|
||||||
Token::String(s) => write!(f, "{s}"),
|
Token::String(s) => write!(f, "{s}"),
|
||||||
|
Token::Lifetime(s) => write!(f, "'{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -263,11 +263,30 @@ impl<'a> Atom<'a> {
|
||||||
|
|
||||||
impl<'a> Token<'a> {
|
impl<'a> Token<'a> {
|
||||||
fn parse_without_separator<E: ParserError<&'a str> + 'a>() -> impl Parser<&'a str, Self, E> {
|
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>> =
|
let delimited: Box<dyn Parser<&'a str, Self, E>> =
|
||||||
Box::new(Delimited::parse().map(Self::Delimited));
|
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(
|
trace(
|
||||||
"token-without-sep",
|
"token-without-sep",
|
||||||
alt((
|
alt((
|
||||||
|
|
@ -276,6 +295,7 @@ impl<'a> Token<'a> {
|
||||||
"None".value(Self::None),
|
"None".value(Self::None),
|
||||||
Number::parse().map(Self::Number),
|
Number::parse().map(Self::Number),
|
||||||
Path::parse().map(Self::Path),
|
Path::parse().map(Self::Path),
|
||||||
|
lifetime,
|
||||||
AnyString::parse().map(Self::String),
|
AnyString::parse().map(Self::String),
|
||||||
delimited,
|
delimited,
|
||||||
Atom::parse(|| {
|
Atom::parse(|| {
|
||||||
|
|
@ -1116,14 +1136,8 @@ mod tests {
|
||||||
leading_space: Space(
|
leading_space: Space(
|
||||||
"",
|
"",
|
||||||
),
|
),
|
||||||
token: String(
|
token: Lifetime(
|
||||||
AnyString {
|
"_",
|
||||||
prefix: "",
|
|
||||||
ty: Single,
|
|
||||||
contents: "_, ",
|
|
||||||
num_hashtags: 0,
|
|
||||||
suffix: "",
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Segment {
|
Segment {
|
||||||
|
|
@ -1132,10 +1146,18 @@ mod tests {
|
||||||
),
|
),
|
||||||
token: Atom(
|
token: Atom(
|
||||||
Text(
|
Text(
|
||||||
"_",
|
",",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
Segment {
|
||||||
|
leading_space: Space(
|
||||||
|
" ",
|
||||||
|
),
|
||||||
|
token: Lifetime(
|
||||||
|
"_",
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
trailing_space: Space(
|
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,
|
Number,
|
||||||
/// Known literals, like `true`, `false`, `None`, `Ok`, `Err`
|
/// Known literals, like `true`, `false`, `None`, `Ok`, `Err`
|
||||||
Literal,
|
Literal,
|
||||||
|
/// Lifetimes (`'foo`)
|
||||||
|
Lifetime,
|
||||||
/// Strings
|
/// Strings
|
||||||
String,
|
String,
|
||||||
/// Paths
|
/// Paths
|
||||||
|
|
@ -193,6 +195,10 @@ mod private {
|
||||||
Token::Atom(atom) => {
|
Token::Atom(atom) => {
|
||||||
atom.into_spans(cx);
|
atom.into_spans(cx);
|
||||||
}
|
}
|
||||||
|
Token::Lifetime(lifetime) => {
|
||||||
|
cx.push("'", SpanKind::Surroundings);
|
||||||
|
cx.push(lifetime, SpanKind::Lifetime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ mod tests {
|
||||||
println!("undo");
|
println!("undo");
|
||||||
f.undo();
|
f.undo();
|
||||||
c.update_with_parents(&f);
|
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!(c.next(&f));
|
||||||
assert_eq!(c.curr().message_or_name(), Some("bar"));
|
assert_eq!(c.curr().message_or_name(), Some("bar"));
|
||||||
assert!(!c.next(&f));
|
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::Delimiter(_) => style.fg(styles.delimiter).bold(),
|
||||||
SpanKind::Separator => style.fg(styles.faded),
|
SpanKind::Separator => style.fg(styles.faded),
|
||||||
SpanKind::Number => style.fg(styles.literal),
|
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::String => style.fg(styles.string),
|
||||||
SpanKind::Path => style.fg(styles.literal).underlined(),
|
SpanKind::Path => style.fg(styles.literal).underlined(),
|
||||||
SpanKind::Space(_) => style,
|
SpanKind::Space(_) => style,
|
||||||
SpanKind::Constructor => style.fg(styles.literal),
|
SpanKind::Constructor => style.fg(styles.literal),
|
||||||
SpanKind::Surroundings => style.fg(styles.faded),
|
SpanKind::Surroundings => style.fg(styles.faded),
|
||||||
|
SpanKind::Lifetime => style.fg(styles.faded),
|
||||||
SpanKind::Text => style,
|
SpanKind::Text => style,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue