use std::collections::VecDeque;
use syntree::pointer::Width;
use syntree::{Builder, Checkpoint, Tree};
use crate::syntax::grammar;
use crate::syntax::lexer::{Lexer, Token};
type Result<T, E = syntree::Error> = std::result::Result<T, E>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Skip(usize);
impl Skip {
pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum Syntax {
WHITESPACE,
STAR,
STARSTAR,
SLASH,
PLUS,
DASH,
CARET,
COMMA,
OPEN_PAREN,
CLOSE_PAREN,
OPEN_BRACE,
CLOSE_BRACE,
TO,
WORD,
SENTENCE,
NUMBER,
WITH_UNIT,
UNIT,
FN_NAME,
FN_ARGUMENTS,
FN_CALL,
PERCENTAGE,
OP_CAST,
OP_ADD,
OP_SUB,
OP_IMPLICIT_MUL,
OP_MUL,
OP_DIV,
OP_POWER,
OPERATOR,
OPERATION,
ERROR,
EOF,
}
use Syntax::*;
pub struct Parser<'a> {
lexer: Lexer<'a>,
builder: Builder<Syntax, u32, u32>,
buf: VecDeque<Token>,
}
impl<'a> Parser<'a> {
pub fn new(source: &'a str) -> Parser<'a> {
Self {
lexer: Lexer::new(source),
builder: Builder::new_with(),
buf: VecDeque::new(),
}
}
pub fn parse_root(mut self) -> Result<Tree<Syntax, u32, u32>> {
grammar::root(&mut self)?;
self.builder.build()
}
pub fn parse_unit(mut self) -> Result<Tree<Syntax, u32, u32>> {
if grammar::unit(&mut self, Skip::ZERO)?.is_none() {
self.bump_empty_node(ERROR)?;
}
self.builder.build()
}
pub(crate) fn eat(&mut self, skip: Skip, expected: &[Syntax]) -> Result<bool> {
for (n, k) in expected.iter().enumerate() {
match self.get(n) {
Some(t) if t.kind == *k => {}
_ => return Ok(false),
}
}
for _ in 0..skip.0 {
self.bump()?;
}
for _ in 0..expected.len() {
self.bump()?;
}
Ok(true)
}
pub(crate) fn bump_until(&mut self, kind: Syntax) -> Result<()> {
while let Some(node) = self.get(0) {
self.bump()?;
if node.kind == kind {
break;
}
}
Ok(())
}
pub(crate) fn checkpoint(&mut self) -> Result<Checkpoint<<u32 as Width>::Pointer>> {
self.builder.checkpoint()
}
pub(crate) fn bump_empty_node(&mut self, kind: Syntax) -> Result<()> {
self.builder.open(kind)?;
self.builder.close()?;
Ok(())
}
pub(crate) fn bump_node(&mut self, kind: Syntax) -> Result<()> {
self.builder.open(kind)?;
self.bump()?;
self.builder.close()?;
Ok(())
}
pub(crate) fn close_at(
&mut self,
c: &Checkpoint<<u32 as Width>::Pointer>,
kind: Syntax,
) -> Result<()> {
self.builder.close_at(c, kind)?;
Ok(())
}
pub(crate) fn error_node_at(&mut self, c: &Checkpoint<<u32 as Width>::Pointer>) -> Result<()> {
self.builder.close_at(c, ERROR)?;
Ok(())
}
fn fill(&mut self, n: usize) {
while self.buf.len() <= n {
match self.lexer.next() {
Some(t) => {
self.buf.push_back(t);
}
None => break,
}
}
}
fn get(&mut self, n: usize) -> Option<Token> {
self.fill(n);
self.buf.get(n).copied()
}
pub(crate) fn skip(&mut self, skip: Skip) -> Result<()> {
for _ in 0..skip.0 {
self.bump()?;
}
Ok(())
}
pub(crate) fn nth(&mut self, skip: Skip, n: usize) -> Syntax {
match self.get(skip.0 + n) {
Some(t) => t.kind,
None => EOF,
}
}
pub(crate) fn bump(&mut self) -> Result<()> {
if let Some(t) = self.get(0) {
self.builder.token(t.kind, t.len)?;
self.buf.pop_front();
}
Ok(())
}
pub fn count_skip(&mut self) -> Skip {
let mut n = 0;
while let Some(WHITESPACE) = self.get(n).map(|t| t.kind) {
n += 1;
}
Skip(n)
}
}