|
1 | 1 | use std::cmp::PartialEq; |
2 | 2 | use std::fmt::Debug; |
| 3 | +use std::rc::Rc; |
| 4 | +use std::str::Chars; |
| 5 | +use std::iter::Peekable; |
3 | 6 |
|
4 | 7 | use super::tokenizer::*; |
5 | 8 |
|
@@ -105,41 +108,47 @@ impl<TokenType> From<TokenizerError<TokenType>> for ParserError<TokenType> |
105 | 108 |
|
106 | 109 |
|
107 | 110 | pub trait SQLParser<TokenType, ExprType> |
108 | | - where TokenType: Debug + PartialEq, ExprType: Debug + PartialEq { |
| 111 | + where TokenType: Debug + PartialEq, ExprType: Debug { |
109 | 112 |
|
110 | 113 | /// parse the prefix and stop once an infix operator is reached |
111 | 114 | fn parse_prefix(&mut self) -> Result<Box<SQLExpr<ExprType>>, ParserError<TokenType>> ; |
112 | 115 | /// parse the next infix expression, returning None if the precedence has changed |
113 | | - fn parse_infix(&mut self, left: SQLExpr<ExprType>) -> Result<Option<Box<SQLExpr<ExprType>>>, ParserError<TokenType>>; |
| 116 | + fn parse_infix(&mut self, left: &SQLExpr<ExprType>, precedence: usize) -> Result<Option<Box<SQLExpr<ExprType>>>, ParserError<TokenType>>; |
| 117 | +} |
| 118 | + |
| 119 | + |
| 120 | + |
| 121 | +struct PrattParser<'a, TokenType, ExprType> { |
| 122 | + chars: Peekable<Chars<'a>>, |
| 123 | + tokenizer: Rc<SQLTokenizer<TokenType>>, |
| 124 | + parser: SQLParser<TokenType, ExprType> |
| 125 | +} |
| 126 | + |
| 127 | +impl<'a, TokenType, ExprType> PrattParser<'a, TokenType, ExprType> |
| 128 | + where TokenType: Debug + PartialEq, ExprType: Debug { |
| 129 | + |
| 130 | + fn parse_expr(&mut self) -> Result<Box<SQLExpr<ExprType>>, ParserError<TokenType>> { |
| 131 | + |
| 132 | + let precedence: usize = 0; |
| 133 | + |
| 134 | + let mut expr = self.parser.parse_prefix()?; |
| 135 | + |
| 136 | + while let Some(token) = self.tokenizer.peek_token(&mut self.chars)? { |
| 137 | + |
| 138 | + let next_precedence = self.tokenizer.precedence(&token); |
| 139 | + |
| 140 | + if precedence >= next_precedence { |
| 141 | + break; |
| 142 | + } |
| 143 | + |
| 144 | + expr = self.parser.parse_infix(&expr, next_precedence)?.unwrap(); //TODO: fix me |
| 145 | + } |
| 146 | + |
| 147 | + Ok(expr) |
| 148 | + } |
| 149 | + |
114 | 150 | } |
115 | 151 |
|
116 | | -// |
117 | | -// |
118 | | -//struct GenericParser { |
119 | | -// tokenizer: SQLTokenizer |
120 | | -//} |
121 | | -// |
122 | | -//impl GenericParser { |
123 | | -// |
124 | | -// fn parse_expr(&mut self, precedence: u8) -> Result<Box<SQLExpr>, ParserError> { |
125 | | -// |
126 | | -// let mut expr = self.parse_prefix()?; |
127 | | -// |
128 | | -// // loop while there are more tokens and until the precedence changes |
129 | | -// while let Some(token) = self.tokenizer.peek_token()? { |
130 | | -// |
131 | | -// let next_precedence = self.get_precedence(&token); |
132 | | -// |
133 | | -// if precedence >= next_precedence { |
134 | | -// break; |
135 | | -// } |
136 | | -// |
137 | | -// expr = self.parse_infix(expr, next_precedence)?; |
138 | | -// } |
139 | | -// |
140 | | -// Ok(expr) |
141 | | -// } |
142 | | -// |
143 | 152 | // fn parse_prefix(&mut self) -> Result<Box<SQLExpr>, ParserError> { |
144 | 153 | // |
145 | 154 | // match self.tokenizer.peek_token()? { |
|
0 commit comments