2018-07-31 23:38:19 +03:00
|
|
|
mod event;
|
|
|
|
mod input;
|
|
|
|
|
2018-08-28 00:42:13 +03:00
|
|
|
use std::cell::Cell;
|
|
|
|
|
2018-10-15 19:55:32 +03:00
|
|
|
use crate::{
|
2018-07-31 23:38:19 +03:00
|
|
|
lexer::Token,
|
|
|
|
parser_api::Parser,
|
|
|
|
parser_impl::{
|
2018-10-15 17:44:23 -04:00
|
|
|
event::{Event, EventProcessor},
|
2018-07-31 23:38:19 +03:00
|
|
|
input::{InputPosition, ParserInput},
|
|
|
|
},
|
2018-11-04 16:45:22 +01:00
|
|
|
SmolStr, TextRange,
|
|
|
|
yellow::syntax_error::{
|
|
|
|
ParseError,
|
|
|
|
SyntaxErrorKind,
|
|
|
|
},
|
2018-07-31 23:38:19 +03:00
|
|
|
};
|
2018-02-11 16:53:57 +03:00
|
|
|
|
2018-10-15 19:55:32 +03:00
|
|
|
use crate::SyntaxKind::{self, EOF, TOMBSTONE};
|
2018-02-11 16:53:57 +03:00
|
|
|
|
2018-10-08 15:44:00 +03:00
|
|
|
pub(crate) trait Sink {
|
2018-07-31 23:38:19 +03:00
|
|
|
type Tree;
|
|
|
|
|
2018-10-08 15:44:00 +03:00
|
|
|
fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
|
2018-07-31 23:38:19 +03:00
|
|
|
fn start_internal(&mut self, kind: SyntaxKind);
|
|
|
|
fn finish_internal(&mut self);
|
2018-11-04 16:45:22 +01:00
|
|
|
fn error(&mut self, kind: SyntaxErrorKind, offset: TextRange);
|
2018-07-31 23:38:19 +03:00
|
|
|
fn finish(self) -> Self::Tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Parse a sequence of tokens into the representative node tree
|
2018-10-08 15:44:00 +03:00
|
|
|
pub(crate) fn parse_with<S: Sink>(
|
|
|
|
sink: S,
|
|
|
|
text: &str,
|
2018-08-25 14:45:17 +03:00
|
|
|
tokens: &[Token],
|
|
|
|
parser: fn(&mut Parser),
|
|
|
|
) -> S::Tree {
|
2018-10-08 15:44:00 +03:00
|
|
|
let mut events = {
|
2018-08-01 10:40:07 +03:00
|
|
|
let input = input::ParserInput::new(text, tokens);
|
2018-07-31 23:38:19 +03:00
|
|
|
let parser_impl = ParserImpl::new(&input);
|
|
|
|
let mut parser_api = Parser(parser_impl);
|
2018-08-25 14:45:17 +03:00
|
|
|
parser(&mut parser_api);
|
2018-07-31 23:38:19 +03:00
|
|
|
parser_api.0.into_events()
|
|
|
|
};
|
2018-10-08 15:44:00 +03:00
|
|
|
EventProcessor::new(sink, text, tokens, &mut events)
|
|
|
|
.process()
|
|
|
|
.finish()
|
2018-07-31 23:38:19 +03:00
|
|
|
}
|
|
|
|
|
2018-02-11 17:58:22 +03:00
|
|
|
/// Implementation details of `Parser`, extracted
|
|
|
|
/// to a separate struct in order not to pollute
|
|
|
|
/// the public API of the `Parser`.
|
2018-02-11 16:53:57 +03:00
|
|
|
pub(crate) struct ParserImpl<'t> {
|
|
|
|
inp: &'t ParserInput<'t>,
|
|
|
|
|
|
|
|
pos: InputPosition,
|
|
|
|
events: Vec<Event>,
|
2018-08-28 00:42:13 +03:00
|
|
|
steps: Cell<u32>,
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'t> ParserImpl<'t> {
|
|
|
|
pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> {
|
|
|
|
ParserImpl {
|
|
|
|
inp,
|
|
|
|
|
|
|
|
pos: InputPosition::new(),
|
|
|
|
events: Vec::new(),
|
2018-08-28 00:42:13 +03:00
|
|
|
steps: Cell::new(0),
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn into_events(self) -> Vec<Event> {
|
|
|
|
assert_eq!(self.nth(0), EOF);
|
|
|
|
self.events
|
|
|
|
}
|
|
|
|
|
2018-08-24 00:48:10 +03:00
|
|
|
pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> {
|
|
|
|
let c1 = self.inp.kind(self.pos);
|
|
|
|
let c2 = self.inp.kind(self.pos + 1);
|
|
|
|
if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) {
|
|
|
|
Some((c1, c2))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2018-08-05 16:09:25 +03:00
|
|
|
}
|
|
|
|
|
2018-08-24 00:48:10 +03:00
|
|
|
pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> {
|
|
|
|
let c1 = self.inp.kind(self.pos);
|
|
|
|
let c2 = self.inp.kind(self.pos + 1);
|
|
|
|
let c3 = self.inp.kind(self.pos + 2);
|
|
|
|
if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos)
|
2018-10-15 17:44:23 -04:00
|
|
|
&& self.inp.start(self.pos + 2)
|
|
|
|
== self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1)
|
|
|
|
{
|
2018-08-24 00:48:10 +03:00
|
|
|
Some((c1, c2, c3))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2018-08-07 14:24:03 +03:00
|
|
|
}
|
|
|
|
|
2018-02-11 16:53:57 +03:00
|
|
|
pub(super) fn nth(&self, n: u32) -> SyntaxKind {
|
2018-08-28 00:42:13 +03:00
|
|
|
let steps = self.steps.get();
|
|
|
|
if steps > 10_000_000 {
|
|
|
|
panic!("the parser seems stuck");
|
|
|
|
}
|
|
|
|
self.steps.set(steps + 1);
|
|
|
|
|
2018-02-11 16:53:57 +03:00
|
|
|
self.inp.kind(self.pos + n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn at_kw(&self, t: &str) -> bool {
|
|
|
|
self.inp.text(self.pos) == t
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn start(&mut self) -> u32 {
|
|
|
|
let pos = self.events.len() as u32;
|
|
|
|
self.event(Event::Start {
|
|
|
|
kind: TOMBSTONE,
|
|
|
|
forward_parent: None,
|
|
|
|
});
|
|
|
|
pos
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn bump(&mut self) {
|
|
|
|
let kind = self.nth(0);
|
|
|
|
if kind == EOF {
|
|
|
|
return;
|
|
|
|
}
|
2018-08-05 16:09:25 +03:00
|
|
|
self.do_bump(kind, 1);
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn bump_remap(&mut self, kind: SyntaxKind) {
|
|
|
|
if self.nth(0) == EOF {
|
|
|
|
// TODO: panic!?
|
|
|
|
return;
|
|
|
|
}
|
2018-08-05 16:09:25 +03:00
|
|
|
self.do_bump(kind, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) {
|
|
|
|
self.do_bump(kind, n);
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
|
2018-08-05 16:09:25 +03:00
|
|
|
fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
|
|
|
|
self.pos += u32::from(n_raw_tokens);
|
2018-10-15 17:44:23 -04:00
|
|
|
self.event(Event::Token { kind, n_raw_tokens });
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn error(&mut self, msg: String) {
|
2018-11-04 16:45:22 +01:00
|
|
|
self.event(Event::Error {
|
|
|
|
msg: ParseError(msg),
|
|
|
|
})
|
2018-02-11 16:53:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) {
|
|
|
|
match self.events[pos as usize] {
|
|
|
|
Event::Start {
|
|
|
|
kind: ref mut slot, ..
|
|
|
|
} => {
|
|
|
|
*slot = kind;
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
self.event(Event::Finish);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn abandon(&mut self, pos: u32) {
|
|
|
|
let idx = pos as usize;
|
|
|
|
if idx == self.events.len() - 1 {
|
|
|
|
match self.events.pop() {
|
|
|
|
Some(Event::Start {
|
2018-02-11 17:58:33 +03:00
|
|
|
kind: TOMBSTONE,
|
|
|
|
forward_parent: None,
|
|
|
|
}) => (),
|
2018-02-11 16:53:57 +03:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(super) fn precede(&mut self, pos: u32) -> u32 {
|
|
|
|
let new_pos = self.start();
|
|
|
|
match self.events[pos as usize] {
|
|
|
|
Event::Start {
|
|
|
|
ref mut forward_parent,
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
*forward_parent = Some(new_pos - pos);
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
new_pos
|
|
|
|
}
|
|
|
|
|
|
|
|
fn event(&mut self, event: Event) {
|
|
|
|
self.events.push(event)
|
|
|
|
}
|
|
|
|
}
|