mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
commit
bec9f09134
3 changed files with 59 additions and 4 deletions
|
@ -51,8 +51,12 @@ impl Grammar {
|
||||||
write!(acc, " {},\n", scream(kind)).unwrap();
|
write!(acc, " {},\n", scream(kind)).unwrap();
|
||||||
}
|
}
|
||||||
acc.push_str("\n");
|
acc.push_str("\n");
|
||||||
acc.push_str(" TOMBSTONE = !0 - 1,\n");
|
acc.push_str(" // Technical SyntaxKinds: they appear temporally during parsing,\n");
|
||||||
acc.push_str(" EOF = !0,\n");
|
acc.push_str(" // but never end up in the final tree\n");
|
||||||
|
acc.push_str(" #[doc(hidden)]\n");
|
||||||
|
acc.push_str(" TOMBSTONE,\n");
|
||||||
|
acc.push_str(" #[doc(hidden)]\n");
|
||||||
|
acc.push_str(" EOF,\n");
|
||||||
acc.push_str("}\n");
|
acc.push_str("}\n");
|
||||||
acc.push_str("pub(crate) use self::SyntaxKind::*;\n");
|
acc.push_str("pub(crate) use self::SyntaxKind::*;\n");
|
||||||
acc.push_str("\n");
|
acc.push_str("\n");
|
||||||
|
|
|
@ -4,17 +4,64 @@ use {SyntaxKind, Token};
|
||||||
mod parser;
|
mod parser;
|
||||||
mod grammar;
|
mod grammar;
|
||||||
|
|
||||||
|
/// `Parser` produces a flat list of `Event`s.
|
||||||
|
/// They are converted to a tree-structure in
|
||||||
|
/// a separate pass, via `TreeBuilder`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum Event {
|
pub(crate) enum Event {
|
||||||
|
/// This event signifies the start of the node.
|
||||||
|
/// It should be either abandoned (in which case the
|
||||||
|
/// `kind` is `TOMBSTONE`, and the event is ignored),
|
||||||
|
/// or completed via a `Finish` event.
|
||||||
|
///
|
||||||
|
/// All tokens between a `Start` and a `Finish` would
|
||||||
|
/// become the children of the respective node.
|
||||||
|
///
|
||||||
|
/// For left-recursive syntactic constructs, the parser produces
|
||||||
|
/// a child node before it sees a parent. `forward_parent`
|
||||||
|
/// exists to allow to tweak parent-child relationships.
|
||||||
|
///
|
||||||
|
/// Consider this path
|
||||||
|
///
|
||||||
|
/// foo::bar
|
||||||
|
///
|
||||||
|
/// The events for it would look like this:
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// START(PATH) IDENT('foo') FINISH START(PATH) COLONCOLON IDENT('bar') FINISH
|
||||||
|
/// | /\
|
||||||
|
/// | |
|
||||||
|
/// +------forward-parent------+
|
||||||
|
///
|
||||||
|
/// And the tree would look like this
|
||||||
|
///
|
||||||
|
/// +--PATH---------+
|
||||||
|
/// | | |
|
||||||
|
/// | | |
|
||||||
|
/// | '::' 'bar'
|
||||||
|
/// |
|
||||||
|
/// PATH
|
||||||
|
/// |
|
||||||
|
/// 'foo'
|
||||||
|
///
|
||||||
|
/// See also `CompleteMarker::precede`.
|
||||||
Start {
|
Start {
|
||||||
kind: SyntaxKind,
|
kind: SyntaxKind,
|
||||||
forward_parent: Option<u32>,
|
forward_parent: Option<u32>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Complete the previous `Start` event
|
||||||
Finish,
|
Finish,
|
||||||
|
|
||||||
|
/// Produce a single leaf-element.
|
||||||
|
/// `n_raw_tokens` is used to glue complex contextual tokens.
|
||||||
|
/// For example, lexer tokenizes `>>` as `>`, `>`, and
|
||||||
|
/// `n_raw_tokens = 2` is used to produced a single `>>`.
|
||||||
Token {
|
Token {
|
||||||
kind: SyntaxKind,
|
kind: SyntaxKind,
|
||||||
n_raw_tokens: u8,
|
n_raw_tokens: u8,
|
||||||
},
|
},
|
||||||
|
|
||||||
Error {
|
Error {
|
||||||
message: String,
|
message: String,
|
||||||
},
|
},
|
||||||
|
|
|
@ -92,8 +92,12 @@ pub enum SyntaxKind {
|
||||||
ALIAS,
|
ALIAS,
|
||||||
VISIBILITY,
|
VISIBILITY,
|
||||||
|
|
||||||
TOMBSTONE = !0 - 1,
|
// Technical SyntaxKinds: they appear temporally during parsing,
|
||||||
EOF = !0,
|
// but never end up in the final tree
|
||||||
|
#[doc(hidden)]
|
||||||
|
TOMBSTONE,
|
||||||
|
#[doc(hidden)]
|
||||||
|
EOF,
|
||||||
}
|
}
|
||||||
pub(crate) use self::SyntaxKind::*;
|
pub(crate) use self::SyntaxKind::*;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue