From 0075e0ead151a952e19da5a9c55f8a0035139a28 Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Mon, 2 Aug 2021 15:39:42 +0200 Subject: [PATCH] reintroduce Results to the expression parser --- src/parser.rs | 14 ++- src/parser/control_parser.rs | 16 +-- src/parser/expressions_parser.rs | 168 ++++++++++++++----------------- 3 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index c056abbfed..c23723c7e0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -472,7 +472,7 @@ fn parse_array_type_definition( expect_token!(lexer, KeywordSquareParensOpen, None); lexer.advance(); - let range_statement = parse_primary_expression(lexer); + let range_statement = parse_expression(lexer); expect_token!(lexer, KeywordSquareParensClose, None); lexer.advance(); @@ -539,7 +539,17 @@ pub fn parse_any_in_region T>( } fn parse_expression(lexer: &mut ParseSession) -> Statement { - parse_primary_expression(lexer) + let start = lexer.range().start; + match parse_primary_expression(lexer) { + Ok(statement) => statement, + Err(diagnostic) => { + lexer.accept_diagnostic(diagnostic); + let end = lexer.range().end; + Statement::EmptyStatement { + location: SourceRange::new(start..end) + } + } + } } fn parse_reference(lexer: &mut ParseSession) -> Statement { diff --git a/src/parser/control_parser.rs b/src/parser/control_parser.rs index ad141b7995..02488581e5 100644 --- a/src/parser/control_parser.rs +++ b/src/parser/control_parser.rs @@ -8,7 +8,7 @@ use crate::{ }; use super::ParseSession; -use super::{parse_primary_expression, parse_reference, parse_statement}; +use super::{parse_expression, parse_reference, parse_statement}; pub fn parse_control_statement(lexer: &mut ParseSession) -> Statement { match lexer.token { @@ -27,7 +27,7 @@ fn parse_if_statement(lexer: &mut ParseSession) -> Statement { let mut conditional_blocks = vec![]; while lexer.last_token == KeywordElseIf || lexer.last_token == KeywordIf { - let condition = parse_primary_expression(lexer); + let condition = parse_expression(lexer); expect_token!( lexer, KeywordThen, @@ -74,7 +74,7 @@ fn parse_for_statement(lexer: &mut ParseSession) -> Statement { ); lexer.advance(); - let start_expression = parse_primary_expression(lexer); + let start_expression = parse_expression(lexer); expect_token!( lexer, KeywordTo, @@ -83,11 +83,11 @@ fn parse_for_statement(lexer: &mut ParseSession) -> Statement { } ); lexer.advance(); - let end_expression = parse_primary_expression(lexer); + let end_expression = parse_expression(lexer); let step = if lexer.token == KeywordBy { lexer.advance(); // BY - Some(Box::new(parse_primary_expression(lexer))) + Some(Box::new(parse_expression(lexer))) } else { None }; @@ -108,7 +108,7 @@ fn parse_while_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); //WHILE - let condition = parse_primary_expression(lexer); + let condition = parse_expression(lexer); lexer.consume_or_report(KeywordDo); Statement::WhileLoopStatement { @@ -125,7 +125,7 @@ fn parse_repeat_statement(lexer: &mut ParseSession) -> Statement { let body = parse_body_in_region(lexer, vec![KeywordUntil, KeywordEndRepeat]); //UNTIL let condition = if lexer.last_token == KeywordUntil { parse_any_in_region(lexer, vec![KeywordEndRepeat], |lexer| { - parse_primary_expression(lexer) + parse_expression(lexer) }) } else { Statement::EmptyStatement { @@ -144,7 +144,7 @@ fn parse_case_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); // CASE - let selector = Box::new(parse_primary_expression(lexer)); + let selector = Box::new(parse_expression(lexer)); expect_token!( lexer, diff --git a/src/parser/expressions_parser.rs b/src/parser/expressions_parser.rs index 3eb71d89d7..55506f0e1c 100644 --- a/src/parser/expressions_parser.rs +++ b/src/parser/expressions_parser.rs @@ -10,46 +10,46 @@ use super::ParseSession; type ParseError = Diagnostic; -pub fn parse_primary_expression(lexer: &mut ParseSession) -> Statement { +pub fn parse_primary_expression(lexer: &mut ParseSession) -> Result { if lexer.token == KeywordSemicolon { - Statement::EmptyStatement { + Ok(Statement::EmptyStatement { location: lexer.location(), - } + }) } else { parse_expression_list(lexer) } } -pub fn parse_expression_list(lexer: &mut ParseSession) -> Statement { +pub fn parse_expression_list(lexer: &mut ParseSession) -> Result { let left = parse_range_statement(lexer); if lexer.token == KeywordComma { - let mut expressions = vec![left]; + let mut expressions = vec![left?]; // this starts an expression list while lexer.token == KeywordComma { lexer.advance(); - expressions.push(parse_range_statement(lexer)); + expressions.push(parse_range_statement(lexer)?); } - return Statement::ExpressionList { expressions }; + return Ok(Statement::ExpressionList { expressions }); } left } -pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Statement { +pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Result { let start = parse_or_expression(lexer); if lexer.token == KeywordDotDot { lexer.advance(); let end = parse_or_expression(lexer); - return Statement::RangeStatement { - start: Box::new(start), - end: Box::new(end), - }; + return Ok(Statement::RangeStatement { + start: Box::new(start?), + end: Box::new(end?), + }); } start } // OR -fn parse_or_expression(lexer: &mut ParseSession) -> Statement { +fn parse_or_expression(lexer: &mut ParseSession) -> Result { let left = parse_xor_expression(lexer); let operator = match lexer.token { @@ -60,15 +60,15 @@ fn parse_or_expression(lexer: &mut ParseSession) -> Statement { lexer.advance(); let right = parse_or_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } // XOR -fn parse_xor_expression(lexer: &mut ParseSession) -> Statement { +fn parse_xor_expression(lexer: &mut ParseSession) -> Result { let left = parse_and_expression(lexer); let operator = match lexer.token { @@ -79,15 +79,15 @@ fn parse_xor_expression(lexer: &mut ParseSession) -> Statement { lexer.advance(); let right = parse_xor_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } // AND -fn parse_and_expression(lexer: &mut ParseSession) -> Statement { +fn parse_and_expression(lexer: &mut ParseSession) -> Result { let left = parse_equality_expression(lexer); let operator = match lexer.token { @@ -98,15 +98,15 @@ fn parse_and_expression(lexer: &mut ParseSession) -> Statement { lexer.advance(); let right = parse_and_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } //EQUALITY =, <> -fn parse_equality_expression(lexer: &mut ParseSession) -> Statement { +fn parse_equality_expression(lexer: &mut ParseSession) -> Result { let left = parse_compare_expression(lexer); let operator = match lexer.token { OperatorEqual => Operator::Equal, @@ -115,15 +115,15 @@ fn parse_equality_expression(lexer: &mut ParseSession) -> Statement { }; lexer.advance(); let right = parse_equality_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } //COMPARE <, >, <=, >= -fn parse_compare_expression(lexer: &mut ParseSession) -> Statement { +fn parse_compare_expression(lexer: &mut ParseSession) -> Result { let left = parse_additive_expression(lexer); let operator = match lexer.token { OperatorLess => Operator::Less, @@ -134,15 +134,15 @@ fn parse_compare_expression(lexer: &mut ParseSession) -> Statement { }; lexer.advance(); let right = parse_compare_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } // Addition +, - -fn parse_additive_expression(lexer: &mut ParseSession) -> Statement { +fn parse_additive_expression(lexer: &mut ParseSession) -> Result { let left = parse_multiplication_expression(lexer); let operator = match lexer.token { OperatorPlus => Operator::Plus, @@ -151,15 +151,15 @@ fn parse_additive_expression(lexer: &mut ParseSession) -> Statement { }; lexer.advance(); let right = parse_additive_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } // Multiplication *, /, MOD -fn parse_multiplication_expression(lexer: &mut ParseSession) -> Statement { +fn parse_multiplication_expression(lexer: &mut ParseSession) -> Result { let left = parse_unary_expression(lexer); let operator = match lexer.token { OperatorMultiplication => Operator::Multiplication, @@ -169,15 +169,15 @@ fn parse_multiplication_expression(lexer: &mut ParseSession) -> Statement { }; lexer.advance(); let right = parse_multiplication_expression(lexer); - Statement::BinaryExpression { + Ok(Statement::BinaryExpression { operator, - left: Box::new(left), - right: Box::new(right), - } + left: Box::new(left?), + right: Box::new(right?), + }) } // UNARY -x, NOT x -fn parse_unary_expression(lexer: &mut ParseSession) -> Statement { +fn parse_unary_expression(lexer: &mut ParseSession) -> Result { let operator = match lexer.token { OperatorNot => Some(Operator::Not), OperatorMinus => Some(Operator::Minus), @@ -187,21 +187,21 @@ fn parse_unary_expression(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; if let Some(operator) = operator { lexer.advance(); - let expression = parse_parenthesized_expression(lexer); + let expression = parse_parenthesized_expression(lexer)?; let expression_location = expression.get_location(); let location = SourceRange::new(start..expression_location.get_end()); - Statement::UnaryExpression { + Ok(Statement::UnaryExpression { operator, value: Box::new(expression), location, - } + }) } else { parse_parenthesized_expression(lexer) } } // PARENTHESIZED (...) -fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { +fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Result { match lexer.token { KeywordParensOpen => { lexer.advance(); @@ -214,8 +214,8 @@ fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { } // Literals, Identifiers, etc. -fn parse_leaf_expression(lexer: &mut ParseSession) -> Statement { - let literal_parse_result = match lexer.token { +fn parse_leaf_expression(lexer: &mut ParseSession) -> Result { + let statement = match lexer.token { Identifier => parse_qualified_reference(lexer), LiteralInteger => parse_literal_number(lexer), LiteralDate => parse_literal_date(lexer), @@ -232,41 +232,30 @@ fn parse_leaf_expression(lexer: &mut ParseSession) -> Statement { lexer.slice().to_string(), lexer.location(), )), - }; + }?; - match literal_parse_result { - Ok(statement) => { - if lexer.token == KeywordAssignment { - lexer.advance(); - Statement::Assignment { - left: Box::new(statement), - right: Box::new(parse_range_statement(lexer)), - } - } else if lexer.token == KeywordOutputAssignment { - lexer.advance(); - Statement::OutputAssignment { - left: Box::new(statement), - right: Box::new(parse_range_statement(lexer)), - } - } else { - statement - } + Ok(if lexer.token == KeywordAssignment { + lexer.advance(); + Statement::Assignment { + left: Box::new(statement), + right: Box::new(parse_range_statement(lexer)?), } - Err(diagnostic) => { - let statement = Statement::EmptyStatement { - location: diagnostic.get_location(), - }; - lexer.accept_diagnostic(diagnostic); - statement + } else if lexer.token == KeywordOutputAssignment { + lexer.advance(); + Statement::OutputAssignment { + left: Box::new(statement), + right: Box::new(parse_range_statement(lexer)?), } - } + } else { + statement + }) } fn parse_array_literal(lexer: &mut ParseSession) -> Result { let start = lexer.range().start; lexer.expect(KeywordSquareParensOpen)?; lexer.advance(); - let elements = Some(Box::new(parse_primary_expression(lexer))); + let elements = Some(Box::new(parse_primary_expression(lexer)?)); let end = lexer.range().end; lexer.expect(KeywordSquareParensClose)?; lexer.advance(); @@ -301,22 +290,21 @@ pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result Result Result() .map_err(|e| Diagnostic::syntax_error(format!("{}", e), location.clone()))?; - let element = parse_primary_expression(lexer); + let element = parse_primary_expression(lexer)?; lexer.expect(KeywordParensClose)?; let end = lexer.range().end; lexer.advance();