Stop returning Option from parse_infix

This reduces amount of boilerplate and avoids cloning the `expr` param.
This commit is contained in:
Nickolay Ponomarev 2019-01-29 17:49:46 +03:00
parent d73a1e0e1d
commit eb4b5bc686

View file

@ -77,9 +77,7 @@ impl Parser {
break; break;
} }
if let Some(infix_expr) = self.parse_infix(expr.clone(), next_precedence)? { expr = self.parse_infix(expr, next_precedence)?;
expr = infix_expr;
}
} }
Ok(expr) Ok(expr)
} }
@ -102,9 +100,7 @@ impl Parser {
break; break;
} }
if let Some(infix_expr) = self.parse_infix(expr.clone(), next_precedence)? { expr = self.parse_infix(expr, next_precedence)?;
expr = infix_expr;
}
} }
Ok(expr) Ok(expr)
} }
@ -248,37 +244,33 @@ impl Parser {
} }
/// Parse an expression infix (typically an operator) /// Parse an expression infix (typically an operator)
pub fn parse_infix( pub fn parse_infix(&mut self, expr: ASTNode, precedence: u8) -> Result<ASTNode, ParserError> {
&mut self,
expr: ASTNode,
precedence: u8,
) -> Result<Option<ASTNode>, ParserError> {
debug!("parsing infix"); debug!("parsing infix");
match self.next_token() { match self.next_token() {
Some(tok) => match tok { Some(tok) => match tok {
Token::Keyword(ref k) if k == "IS" => { Token::Keyword(ref k) if k == "IS" => {
if self.parse_keywords(vec!["NULL"]) { if self.parse_keywords(vec!["NULL"]) {
Ok(Some(ASTNode::SQLIsNull(Box::new(expr)))) Ok(ASTNode::SQLIsNull(Box::new(expr)))
} else if self.parse_keywords(vec!["NOT", "NULL"]) { } else if self.parse_keywords(vec!["NOT", "NULL"]) {
Ok(Some(ASTNode::SQLIsNotNull(Box::new(expr)))) Ok(ASTNode::SQLIsNotNull(Box::new(expr)))
} else { } else {
parser_err!("Invalid tokens after IS") parser_err!("Invalid tokens after IS")
} }
} }
Token::Keyword(ref k) if k == "NOT" => { Token::Keyword(ref k) if k == "NOT" => {
if self.parse_keywords(vec!["LIKE"]) { if self.parse_keywords(vec!["LIKE"]) {
Ok(Some(ASTNode::SQLBinaryExpr { Ok(ASTNode::SQLBinaryExpr {
left: Box::new(expr), left: Box::new(expr),
op: SQLOperator::NotLike, op: SQLOperator::NotLike,
right: Box::new(self.parse_expr(precedence)?), right: Box::new(self.parse_expr(precedence)?),
})) })
} else { } else {
parser_err!("Invalid tokens after NOT") parser_err!("Invalid tokens after NOT")
} }
} }
Token::DoubleColon => { Token::DoubleColon => {
let pg_cast = self.parse_pg_cast(expr)?; let pg_cast = self.parse_pg_cast(expr)?;
Ok(Some(pg_cast)) Ok(pg_cast)
} }
Token::Keyword(_) Token::Keyword(_)
| Token::Eq | Token::Eq
@ -291,14 +283,16 @@ impl Parser {
| Token::Minus | Token::Minus
| Token::Mult | Token::Mult
| Token::Mod | Token::Mod
| Token::Div => Ok(Some(ASTNode::SQLBinaryExpr { | Token::Div => Ok(ASTNode::SQLBinaryExpr {
left: Box::new(expr), left: Box::new(expr),
op: self.to_sql_operator(&tok)?, op: self.to_sql_operator(&tok)?,
right: Box::new(self.parse_expr(precedence)?), right: Box::new(self.parse_expr(precedence)?),
})), }),
_ => parser_err!(format!("No infix parser for token {:?}", tok)), _ => parser_err!(format!("No infix parser for token {:?}", tok)),
}, },
None => Ok(None), // This is not supposed to happen, because of the precedence check
// in parse_expr.
None => parser_err!("Unexpected EOF in parse_infix"),
} }
} }