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}