Skip to main content

dass/
parser.rs

1use std::cmp::Eq;
2use std::fmt::Display;
3use std::iter::Peekable;
4use std::result::Result;
5use std::vec::IntoIter;
6
7use super::error::ParserError;
8use super::lexer::DassLexer;
9use super::tokens::TokenData;
10
11pub trait DassParser<T>
12where
13    T: Clone + Display,
14{
15    fn eof(&mut self) -> bool;
16
17    fn la1(&mut self, tag: &T) -> bool;
18
19    fn match_token(&mut self, tag: &T) -> Result<TokenData<T>, ParserError>;
20
21    fn pop_token(&mut self) -> Result<TokenData<T>, ParserError>;
22
23    fn pop_until(&mut self, tag: &T) -> Result<TokenData<T>, ParserError> {
24        while !self.la1(tag) {
25            let t = self.pop_token();
26            if t.is_err() {
27                return t;
28            }
29        }
30        self.pop_token()
31    }
32}
33
34pub struct DassVecStreamTokenParser<T>
35where
36    T: Clone + Display,
37{
38    tokens: Peekable<IntoIter<TokenData<T>>>,
39}
40
41impl<T> DassVecStreamTokenParser<T>
42where
43    T: Clone + Display,
44{
45    pub fn new(tokens: Vec<TokenData<T>>) -> Self {
46        DassVecStreamTokenParser {
47            tokens: tokens.into_iter().peekable(),
48        }
49    }
50}
51
52impl<T> DassParser<T> for DassVecStreamTokenParser<T>
53where
54    T: Clone + Display + Eq,
55{
56    fn eof(&mut self) -> bool {
57        self.tokens.peek().is_none()
58    }
59    fn la1(&mut self, tag: &T) -> bool {
60        self.tokens.peek().map_or(false, |t| t.tag == *tag)
61    }
62    fn match_token(&mut self, tag: &T) -> Result<TokenData<T>, ParserError> {
63        self.tokens
64            .next()
65            .map_or(Err(ParserError::end_of_stream(&tag)), |t| {
66                if t.tag != *tag {
67                    Err(ParserError::unexpected_token(tag, t))
68                } else {
69                    Ok(t)
70                }
71            })
72    }
73    fn pop_token(&mut self) -> Result<TokenData<T>, ParserError> {
74        self.tokens.next().ok_or(ParserError::new(
75            String::from("To Pop token"),
76            String::from("End of Stream"),
77            None,
78        ))
79    }
80}
81
82pub struct DassTokenParser<'a, T>
83where
84    T: Clone + Display,
85{
86    lexer: Peekable<DassLexer<'a, T>>,
87}
88
89impl<'a, T> DassTokenParser<'a, T>
90where
91    T: Clone + Display,
92{
93    pub fn new(lexer: DassLexer<'a, T>) -> Self {
94        DassTokenParser {
95            lexer: lexer.peekable(),
96        }
97    }
98}
99
100impl<'a, T> DassParser<T> for DassTokenParser<'a, T>
101where
102    T: Clone + Display + Eq,
103{
104    fn eof(&mut self) -> bool {
105        self.lexer.peek().is_none()
106    }
107    fn la1(&mut self, tag: &T) -> bool {
108        self.lexer.peek().map_or(false, |res| match res {
109            Err(_) => false,
110            Ok(t) => t.tag == *tag,
111        })
112    }
113    fn match_token(&mut self, tag: &T) -> Result<TokenData<T>, ParserError> {
114        self.lexer
115            .next()
116            .map_or(Err(ParserError::end_of_stream(tag)), |res| {
117                res.and_then(|t| {
118                    if t.tag != *tag {
119                        Err(ParserError::unexpected_token(tag, t))
120                    } else {
121                        Ok(t)
122                    }
123                })
124            })
125    }
126    fn pop_token(&mut self) -> Result<TokenData<T>, ParserError> {
127        match self.lexer.next() {
128            Some(t) => t,
129            None => Err(ParserError::new(
130                String::from("To Pop token"),
131                String::from("End of Stream"),
132                None,
133            )),
134        }
135    }
136}