use std::collections::HashMap;
use std::marker::{Send, Sync};
use std::mem::{Discriminant, discriminant};
use prelude::*;
use types::*;
pub trait Parser<T: Token + Send + Sync + 'static> {
fn parse(&mut self) -> Result<Node<T>, ParseError<T>>;
fn parse_expr(&mut self, rbp: PrecedenceLevel) -> Result<Node<T>, ParseError<T>>;
fn next_binds_tighter_than(&mut self, rbp: PrecedenceLevel) -> bool;
fn consume(&mut self, end_token: T) -> Result<(), ParseError<T>>;
}
pub struct GeneralParser<T, L>
where T: Token + Send + Sync + 'static,
L: Lexer<T>
{
null_map: HashMap<Discriminant<T>, NullInfo<T>>,
left_map: HashMap<Discriminant<T>, LeftInfo<T>>,
lexer: L,
}
#[allow(dead_code)]
impl<T: Token + Send + Sync + 'static, L: Lexer<T>> GeneralParser<T, L> {
pub fn new(spec: ParserSpec<T>, lexer: L) -> GeneralParser<T, L> {
let (null_map, left_map) = spec.maps();
GeneralParser {
null_map: null_map,
left_map: left_map,
lexer: lexer
}
}
fn parse(&mut self) -> Result<Node<T>, ParseError<T>> {
self.parse_expr(PrecedenceLevel::Root)
}
fn parse_expr(&mut self, rbp: PrecedenceLevel) -> Result<Node<T>, ParseError<T>> {
<Self as Parser<T>>::parse_expr(self, rbp)
}
fn next_binds_tighter_than(&mut self, rbp: PrecedenceLevel) -> bool {
<Self as Parser<T>>::next_binds_tighter_than(self, rbp)
}
fn consume(&mut self, end_token: T) -> Result<(), ParseError<T>> {
<Self as Parser<T>>::consume(self, end_token)
}
}
impl<T: Token + Send + Sync + 'static, L: Lexer<T>> Parser<T> for GeneralParser<T, L> {
fn parse(&mut self) -> Result<Node<T>, ParseError<T>> {
self.parse_expr(PrecedenceLevel::Root)
}
fn parse_expr(&mut self, rbp: PrecedenceLevel) -> Result<Node<T>, ParseError<T>> {
if let Some(tk) = self.lexer.peek() {
self.lexer.next_token();
let (lbp, func) = {
let val = self.null_map.get(&discriminant(&tk));
match val {
Some(val) => val.clone(),
None => return Err(ParseError::MissingRule {token: tk.clone(), ty: "Null".into()})
}
};
let mut left = func(self, tk, lbp)?;
while self.next_binds_tighter_than(rbp) {
let tk = self.lexer.next_token(); let val = {
let v = self.left_map.get(&discriminant(&tk));
match v {
Some(val) => val.clone(),
None => return Err(ParseError::MissingRule {token: tk.clone(), ty: "Left".into()})
}
};
let (lbp, _, func) = val;
left = func(self, tk, lbp, left)?;
}
Ok(left)
} else {
Err(ParseError::Incomplete)
}
}
fn next_binds_tighter_than(&mut self, rbp: PrecedenceLevel) -> bool {
if let Some(tk) = self.lexer.peek() {
if let Some((_, next_rbp, _)) = self.left_map.get(&discriminant(&tk)) {
*next_rbp > rbp
} else {
false
}
} else {
false
}
}
fn consume(&mut self, end_token: T) -> Result<(), ParseError<T>> {
if let Some(tk) = self.lexer.peek() {
if tk == end_token {
self.lexer.next_token();
Ok(())
} else {
Err(ParseError::ConsumeFailed{expected: end_token, found: tk.clone()})
}
} else {
Err(ParseError::Incomplete)
}
}
}
#[cfg(test)]
mod test {
use super::*;
use lexer::LexerVec;
#[test]
fn test_parser_send() {
fn assert_send<T: Send>() {}
assert_send::<GeneralParser<String, LexerVec<String>>>();
}
#[test]
fn test_parser_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<GeneralParser<String, LexerVec<String>>>();
}
}