2018-10-15 11:55:32 -05:00
|
|
|
use crate::{
|
2018-10-15 16:44:23 -05:00
|
|
|
drop_bomb::DropBomb,
|
2018-07-31 15:38:19 -05:00
|
|
|
parser_impl::ParserImpl,
|
2018-10-15 16:44:23 -05:00
|
|
|
token_set::TokenSet,
|
2018-07-31 15:38:19 -05:00
|
|
|
SyntaxKind::{self, ERROR},
|
|
|
|
};
|
2018-02-11 07:53:57 -06:00
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// `Parser` struct provides the low-level API for
|
|
|
|
/// navigating through the stream of tokens and
|
|
|
|
/// constructing the parse tree. The actual parsing
|
|
|
|
/// happens in the `grammar` module.
|
|
|
|
///
|
|
|
|
/// However, the result of this `Parser` is not a real
|
|
|
|
/// tree, but rather a flat stream of events of the form
|
|
|
|
/// "start expression, consume number literal,
|
|
|
|
/// finish expression". See `Event` docs for more.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>);
|
|
|
|
|
|
|
|
impl<'t> Parser<'t> {
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Returns the kind of the current token.
|
|
|
|
/// If parser has already reached the end of input,
|
|
|
|
/// the special `EOF` kind is returned.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn current(&self) -> SyntaxKind {
|
|
|
|
self.nth(0)
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Lookahead operation: returns the kind of the next nth
|
|
|
|
/// token.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn nth(&self, n: u32) -> SyntaxKind {
|
|
|
|
self.0.nth(n)
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Checks if the current token is `kind`.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
|
|
|
|
self.current() == kind
|
|
|
|
}
|
|
|
|
|
2018-09-08 02:38:53 -05:00
|
|
|
/// Checks if the current token is `kind`.
|
|
|
|
pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
|
|
|
|
kinds.contains(self.current())
|
|
|
|
}
|
|
|
|
|
2018-08-23 16:48:10 -05:00
|
|
|
pub(crate) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
|
|
|
|
self.0.next2()
|
2018-08-05 08:09:25 -05:00
|
|
|
}
|
|
|
|
|
2018-08-23 16:48:10 -05:00
|
|
|
pub(crate) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
|
|
|
|
self.0.next3()
|
2018-08-07 06:24:03 -05:00
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Checks if the current token is contextual keyword with text `t`.
|
|
|
|
pub(crate) fn at_contextual_kw(&self, t: &str) -> bool {
|
2018-02-11 07:53:57 -06:00
|
|
|
self.0.at_kw(t)
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Starts a new node in the syntax tree. All nodes and tokens
|
|
|
|
/// consumed between the `start` and the corresponding `Marker::complete`
|
|
|
|
/// belong to the same node.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn start(&mut self) -> Marker {
|
2018-08-01 03:58:19 -05:00
|
|
|
Marker::new(self.0.start())
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Advances the parser by one token.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn bump(&mut self) {
|
|
|
|
self.0.bump();
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Advances the parser by one token, remapping its kind.
|
|
|
|
/// This is useful to create contextual keywords from
|
|
|
|
/// identifiers. For example, the lexer creates an `union`
|
|
|
|
/// *identifier* token, but the parser remaps it to the
|
|
|
|
/// `union` keyword, and keyword is what ends up in the
|
|
|
|
/// final tree.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) {
|
|
|
|
self.0.bump_remap(kind);
|
|
|
|
}
|
|
|
|
|
2018-08-05 08:09:25 -05:00
|
|
|
/// Advances the parser by `n` tokens, remapping its kind.
|
|
|
|
/// This is useful to create compound tokens from parts. For
|
|
|
|
/// example, an `<<` token is two consecutive remapped `<` tokens
|
|
|
|
pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
|
|
|
|
self.0.bump_compound(kind, n);
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Emit error with the `message`
|
|
|
|
/// TODO: this should be much more fancy and support
|
|
|
|
/// structured errors with spans and notes, like rustc
|
|
|
|
/// does.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
|
|
|
|
self.0.error(message.into())
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Consume the next token if it is `kind`.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
|
|
|
|
if !self.at(kind) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
self.bump();
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Consume the next token if it is `kind` or emit an error
|
|
|
|
/// otherwise.
|
|
|
|
pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
|
|
|
|
if self.eat(kind) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
self.error(format!("expected {:?}", kind));
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create an error node and consume the next token.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn err_and_bump(&mut self, message: &str) {
|
2018-08-28 03:12:42 -05:00
|
|
|
self.err_recover(message, TokenSet::EMPTY);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create an error node and consume the next token.
|
2018-08-31 05:35:48 -05:00
|
|
|
pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
|
2018-10-15 16:44:23 -05:00
|
|
|
if self.at(SyntaxKind::L_CURLY) || self.at(SyntaxKind::R_CURLY) || self.at_ts(recovery) {
|
2018-08-28 03:12:42 -05:00
|
|
|
self.error(message);
|
|
|
|
} else {
|
|
|
|
let m = self.start();
|
|
|
|
self.error(message);
|
2018-08-26 01:12:18 -05:00
|
|
|
self.bump();
|
2018-08-28 03:12:42 -05:00
|
|
|
m.complete(self, ERROR);
|
2018-08-28 03:17:08 -05:00
|
|
|
};
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// See `Parser::start`.
|
2018-08-01 03:58:19 -05:00
|
|
|
pub(crate) struct Marker {
|
|
|
|
pos: u32,
|
|
|
|
bomb: DropBomb,
|
|
|
|
}
|
2018-02-11 07:53:57 -06:00
|
|
|
|
|
|
|
impl Marker {
|
2018-08-01 03:58:19 -05:00
|
|
|
fn new(pos: u32) -> Marker {
|
|
|
|
Marker {
|
|
|
|
pos,
|
2018-08-01 06:55:37 -05:00
|
|
|
bomb: DropBomb::new("Marker must be either completed or abandoned"),
|
2018-08-01 03:58:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Finishes the syntax tree node and assigns `kind` to it.
|
2018-08-01 03:58:19 -05:00
|
|
|
pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
|
|
|
|
self.bomb.defuse();
|
|
|
|
p.0.complete(self.pos, kind);
|
2018-08-07 08:32:09 -05:00
|
|
|
CompletedMarker(self.pos, kind)
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|
|
|
|
|
2018-02-11 08:58:22 -06:00
|
|
|
/// Abandons the syntax tree node. All its children
|
|
|
|
/// are attached to its parent instead.
|
2018-08-01 03:58:19 -05:00
|
|
|
pub(crate) fn abandon(mut self, p: &mut Parser) {
|
|
|
|
self.bomb.defuse();
|
|
|
|
p.0.abandon(self.pos);
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-07 08:32:09 -05:00
|
|
|
pub(crate) struct CompletedMarker(u32, SyntaxKind);
|
2018-02-11 07:53:57 -06:00
|
|
|
|
|
|
|
impl CompletedMarker {
|
2018-02-11 08:58:22 -06:00
|
|
|
/// This one is tricky :-)
|
|
|
|
/// This method allows to create a new node which starts
|
|
|
|
/// *before* the current one. That is, parser could start
|
|
|
|
/// node `A`, then complete it, and then after parsing the
|
|
|
|
/// whole `A`, decide that it should have started some node
|
|
|
|
/// `B` before starting `A`. `precede` allows to do exactly
|
|
|
|
/// that. See also docs about `forward_parent` in `Event::Start`.
|
2018-02-11 07:53:57 -06:00
|
|
|
pub(crate) fn precede(self, p: &mut Parser) -> Marker {
|
2018-08-01 03:58:19 -05:00
|
|
|
Marker::new(p.0.precede(self.0))
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|
2018-08-07 08:32:09 -05:00
|
|
|
|
|
|
|
pub(crate) fn kind(&self) -> SyntaxKind {
|
|
|
|
self.1
|
|
|
|
}
|
2018-02-11 07:53:57 -06:00
|
|
|
}
|