From a64e4d961769220ce681dfe0cedd79e6484ab7c2 Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Thu, 22 Jul 2021 11:34:07 +0200 Subject: [PATCH 1/9] take care of PResult in expression parser --- src/parser/expressions_parser.rs | 176 ++++++++++-------- .../parse_error_containers_tests.rs | 2 +- .../parse_error_statements_tests.rs | 36 +++- 3 files changed, 125 insertions(+), 89 deletions(-) diff --git a/src/parser/expressions_parser.rs b/src/parser/expressions_parser.rs index 3a295c1e0db..0bd58bad2c9 100644 --- a/src/parser/expressions_parser.rs +++ b/src/parser/expressions_parser.rs @@ -1,8 +1,9 @@ -use crate::Diagnostic; // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder + use crate::ast::*; use crate::lexer::Token::*; use crate::parser::parse_statement_in_region; +use crate::Diagnostic; use std::str::FromStr; use super::ParseSession; @@ -15,167 +16,168 @@ pub fn parse_primary_expression(lexer: &mut ParseSession) -> Result Result { +pub fn parse_expression_list(lexer: &mut ParseSession) -> Statement { 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 Ok(Statement::ExpressionList { expressions }); + return Statement::ExpressionList { expressions }; } left } -pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Result { - let start = parse_or_expression(lexer)?; +pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Statement { + let start = parse_or_expression(lexer); if lexer.token == KeywordDotDot { lexer.advance(); - let end = parse_or_expression(lexer)?; - return Ok(Statement::RangeStatement { + let end = parse_or_expression(lexer); + return Statement::RangeStatement { start: Box::new(start), end: Box::new(end), - }); + }; } - Ok(start) + start } // OR -fn parse_or_expression(lexer: &mut ParseSession) -> Result { - let left = parse_xor_expression(lexer)?; +fn parse_or_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_xor_expression(lexer); let operator = match lexer.token { OperatorOr => Operator::Or, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_or_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_or_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } // XOR -fn parse_xor_expression(lexer: &mut ParseSession) -> Result { - let left = parse_and_expression(lexer)?; +fn parse_xor_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_and_expression(lexer); let operator = match lexer.token { OperatorXor => Operator::Xor, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_xor_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_xor_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } // AND -fn parse_and_expression(lexer: &mut ParseSession) -> Result { - let left = parse_equality_expression(lexer)?; +fn parse_and_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_equality_expression(lexer); let operator = match lexer.token { OperatorAnd => Operator::And, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_and_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_and_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } //EQUALITY =, <> -fn parse_equality_expression(lexer: &mut ParseSession) -> Result { - let left = parse_compare_expression(lexer)?; +fn parse_equality_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_compare_expression(lexer); let operator = match lexer.token { OperatorEqual => Operator::Equal, OperatorNotEqual => Operator::NotEqual, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_equality_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_equality_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } //COMPARE <, >, <=, >= -fn parse_compare_expression(lexer: &mut ParseSession) -> Result { - let left = parse_additive_expression(lexer)?; +fn parse_compare_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_additive_expression(lexer); let operator = match lexer.token { OperatorLess => Operator::Less, OperatorGreater => Operator::Greater, OperatorLessOrEqual => Operator::LessOrEqual, OperatorGreaterOrEqual => Operator::GreaterOrEqual, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_compare_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_compare_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } // Addition +, - -fn parse_additive_expression(lexer: &mut ParseSession) -> Result { - let left = parse_multiplication_expression(lexer)?; +fn parse_additive_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_multiplication_expression(lexer); let operator = match lexer.token { OperatorPlus => Operator::Plus, OperatorMinus => Operator::Minus, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_additive_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_additive_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } // Multiplication *, /, MOD -fn parse_multiplication_expression(lexer: &mut ParseSession) -> Result { - let left = parse_unary_expression(lexer)?; +fn parse_multiplication_expression(lexer: &mut ParseSession) -> Statement { + let left = parse_unary_expression(lexer); let operator = match lexer.token { OperatorMultiplication => Operator::Multiplication, OperatorDivision => Operator::Division, OperatorModulo => Operator::Modulo, - _ => return Ok(left), + _ => return left, }; lexer.advance(); - let right = parse_multiplication_expression(lexer)?; - Ok(Statement::BinaryExpression { + let right = parse_multiplication_expression(lexer); + Statement::BinaryExpression { operator, left: Box::new(left), right: Box::new(right), - }) + } } + // UNARY -x, NOT x -fn parse_unary_expression(lexer: &mut ParseSession) -> Result { +fn parse_unary_expression(lexer: &mut ParseSession) -> Statement { let operator = match lexer.token { OperatorNot => Some(Operator::Not), OperatorMinus => Some(Operator::Minus), @@ -185,37 +187,35 @@ fn parse_unary_expression(lexer: &mut ParseSession) -> Result Result { +fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { match lexer.token { KeywordParensOpen => { lexer.advance(); - Ok(super::parse_statement_in_region( - lexer, - vec![KeywordParensClose], - |lexer| parse_primary_expression(lexer), - )) + super::parse_statement_in_region(lexer, vec![KeywordParensClose], |lexer| { + parse_primary_expression(lexer) + }) } _ => parse_leaf_expression(lexer), } } // Literals, Identifiers, etc. -fn parse_leaf_expression(lexer: &mut ParseSession) -> Result { - let current = match lexer.token { +fn parse_leaf_expression(lexer: &mut ParseSession) -> Statement { + let literal_parse_result = match lexer.token { Identifier => parse_qualified_reference(lexer), LiteralInteger => parse_literal_number(lexer), LiteralDate => parse_literal_date(lexer), @@ -228,26 +228,38 @@ fn parse_leaf_expression(lexer: &mut ParseSession) -> Result parse_bool_literal(lexer, false), KeywordSquareParensOpen => parse_array_literal(lexer), _ => Err(Diagnostic::unexpected_token_found( - "Value".to_string(), + "Literal".to_string(), lexer.slice().to_string(), lexer.location(), )), }; - if current.is_ok() && lexer.token == KeywordAssignment { - lexer.advance(); - return Ok(Statement::Assignment { - left: Box::new(current?), - right: Box::new(parse_range_statement(lexer)?), - }); - } else if current.is_ok() && lexer.token == KeywordOutputAssignment { - lexer.advance(); - return Ok(Statement::OutputAssignment { - left: Box::new(current?), - right: Box::new(parse_range_statement(lexer)?), - }); - }; - current + 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 + } + } + Err(diagnostic) => { + let statement = Statement::EmptyStatement { + location: diagnostic.get_location(), + }; + lexer.accept_diagnostic(diagnostic); + statement + } + } } fn parse_array_literal(lexer: &mut ParseSession) -> Result { @@ -299,7 +311,7 @@ pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result Date: Fri, 23 Jul 2021 11:37:09 +0200 Subject: [PATCH 2/9] take care of PResult in control parser --- src/lexer.rs | 14 +++++ src/parser.rs | 38 +++++++----- src/parser/control_parser.rs | 103 ++++++++++++++++--------------- src/parser/expressions_parser.rs | 16 ++--- 4 files changed, 96 insertions(+), 75 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index e99fa335299..482b8fd4626 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -37,6 +37,20 @@ impl<'a> ParseSession<'a> { lexer } + pub fn expect_token(&mut self, token: Token) -> bool { + if self.token != token { + self.accept_diagnostic(Diagnostic::unexpected_token_found( + format!("{:?}", token), + self.slice().to_string(), + self.location(), + )); + false + } else { + true + } + } + + /// this function will be removed soon: pub fn expect(&self, token: Token) -> Result<(), Diagnostic> { if self.token != token { Err(Diagnostic::unexpected_token_found( diff --git a/src/parser.rs b/src/parser.rs index 59e13a85a74..88fb8da817d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -494,7 +494,7 @@ fn parse_array_type_definition( //expect close range lexer.expect(KeywordSquareParensClose)?; lexer.advance(); - range + Ok(range) }); let inner_type_defintion = parse_data_type_definition(lexer, None); inner_type_defintion.map(|(reference, initializer)| { @@ -512,14 +512,9 @@ fn parse_array_type_definition( } /// parse a body and recovers until the given `end_keywords` -fn parse_body_in_region( - lexer: &mut ParseSession, - end_keywords: Vec, -) -> Result, Diagnostic> { - let statements = parse_any_in_region(lexer, end_keywords, |lexer| parse_body_standalone(lexer)) - .unwrap_or_default(); - - Ok(statements) +fn parse_body_in_region(lexer: &mut ParseSession, end_keywords: Vec) -> Vec { + parse_any_in_region(lexer, end_keywords, |lexer| parse_body_standalone(lexer)) + .unwrap_or_default() } fn parse_body_standalone(lexer: &mut ParseSession) -> PResult> { @@ -533,16 +528,16 @@ fn parse_body_standalone(lexer: &mut ParseSession) -> PResult> { /** * parses a statement ending with a ; */ -fn parse_statement(lexer: &mut ParseSession) -> Result { +fn parse_statement(lexer: &mut ParseSession) -> Statement { let result = parse_statement_in_region(lexer, vec![KeywordSemicolon, KeywordColon], |lexer| { parse_expression(lexer) }); if lexer.last_token == KeywordColon { - Ok(Statement::CaseCondition { + Statement::CaseCondition { condition: Box::new(result), - }) + } } else { - Ok(result) + result } } @@ -578,15 +573,24 @@ pub fn parse_any_in_region PResult>( } fn parse_expression(lexer: &mut ParseSession) -> Result { - parse_primary_expression(lexer) + Ok(parse_primary_expression(lexer)) } -fn parse_reference(lexer: &mut ParseSession) -> Result { - expressions_parser::parse_qualified_reference(lexer) +fn parse_reference(lexer: &mut ParseSession) -> Statement { + match expressions_parser::parse_qualified_reference(lexer) { + Ok(statement) => statement, + Err(diagnostic) => { + let statement = Statement::EmptyStatement { + location: diagnostic.get_location(), + }; + lexer.accept_diagnostic(diagnostic); + statement + } + } } fn parse_control(lexer: &mut ParseSession) -> Result { - parse_control_statement(lexer) + Ok(parse_control_statement(lexer)) } fn parse_variable_block_type(block_type: &Token) -> VariableBlockType { diff --git a/src/parser/control_parser.rs b/src/parser/control_parser.rs index 6d777013299..136c244f3e6 100644 --- a/src/parser/control_parser.rs +++ b/src/parser/control_parser.rs @@ -6,9 +6,9 @@ use crate::parser::parse_statement_in_region; use crate::Diagnostic; use super::ParseSession; -use super::{parse_expression, parse_reference, parse_statement}; +use super::{parse_primary_expression, parse_reference, parse_statement}; -pub fn parse_control_statement(lexer: &mut ParseSession) -> Result { +pub fn parse_control_statement(lexer: &mut ParseSession) -> Statement { match lexer.token { KeywordIf => parse_if_statement(lexer), KeywordFor => parse_for_statement(lexer), @@ -19,20 +19,23 @@ pub fn parse_control_statement(lexer: &mut ParseSession) -> Result Result { +fn parse_if_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); //If let mut conditional_blocks = vec![]; while lexer.last_token == KeywordElseIf || lexer.last_token == KeywordIf { - let condition = parse_expression(lexer); - lexer.expect(KeywordThen)?; + let condition = parse_primary_expression(lexer); + if !lexer.expect_token(KeywordThen) { + return Statement::EmptyStatement { + location: lexer.location(), + }; + } lexer.advance(); - let body = parse_body_in_region(lexer, vec![KeywordEndIf, KeywordElseIf, KeywordElse]); let condition_block = ConditionalBlock { - condition: Box::new(condition?), - body: body?, + condition: Box::new(condition), + body: parse_body_in_region(lexer, vec![KeywordEndIf, KeywordElseIf, KeywordElse]), }; conditional_blocks.push(condition_block); @@ -41,84 +44,80 @@ fn parse_if_statement(lexer: &mut ParseSession) -> Result let mut else_block = Vec::new(); if lexer.last_token == KeywordElse { - else_block.append(&mut parse_body_in_region(lexer, vec![KeywordEndIf])?); + else_block.append(&mut parse_body_in_region(lexer, vec![KeywordEndIf])); } let end = lexer.last_range.end; - Ok(Statement::IfStatement { + Statement::IfStatement { blocks: conditional_blocks, else_block, location: SourceRange::new(start..end), - }) + } } -fn parse_for_statement(lexer: &mut ParseSession) -> Result { +fn parse_for_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); // FOR - let counter_expression = parse_reference(lexer)?; - lexer.expect(KeywordAssignment)?; // := + let counter_expression = parse_reference(lexer); + if !lexer.expect_token(KeywordAssignment) { + return Statement::EmptyStatement { + location: lexer.location(), + }; + } lexer.advance(); - let start_expression = parse_expression(lexer)?; - - lexer.expect(KeywordTo)?; // TO + let start_expression = parse_primary_expression(lexer); + if !lexer.expect_token(KeywordTo) { + return Statement::EmptyStatement { + location: lexer.location(), + }; + } lexer.advance(); - let end_expression = parse_expression(lexer)?; + let end_expression = parse_primary_expression(lexer); let step = if lexer.token == KeywordBy { lexer.advance(); // BY - Some(Box::new(parse_expression(lexer)?)) + Some(Box::new(parse_primary_expression(lexer))) } else { None }; lexer.consume_or_report(KeywordDo); // DO - let body = parse_body_in_region(lexer, vec![KeywordEndFor]); - Ok(Statement::ForLoopStatement { + Statement::ForLoopStatement { counter: Box::new(counter_expression), start: Box::new(start_expression), end: Box::new(end_expression), by_step: step, - body: body?, + body: parse_body_in_region(lexer, vec![KeywordEndFor]), location: SourceRange::new(start..lexer.last_range.end), - }) + } } -fn parse_while_statement(lexer: &mut ParseSession) -> Result { +fn parse_while_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); //WHILE - let start_condition = lexer.range().start; - let condition = match parse_expression(lexer) { - Ok(condition) => condition, - Err(diagnostic) => { - lexer.accept_diagnostic(diagnostic); - Statement::EmptyStatement { - location: (start_condition..lexer.range().end).into(), - } - } - }; + let condition = parse_primary_expression(lexer); lexer.consume_or_report(KeywordDo); - let body = parse_body_in_region(lexer, vec![KeywordEndWhile])?; - Ok(Statement::WhileLoopStatement { + Statement::WhileLoopStatement { condition: Box::new(condition), - body, + body: parse_body_in_region(lexer, vec![KeywordEndWhile]), location: SourceRange::new(start..lexer.last_range.end), - }) + } } -fn parse_repeat_statement(lexer: &mut ParseSession) -> Result { +fn parse_repeat_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); //REPEAT - let body = parse_body_in_region(lexer, vec![KeywordUntil, KeywordEndRepeat])?; //UNTIL + let body = parse_body_in_region(lexer, vec![KeywordUntil, KeywordEndRepeat]); //UNTIL let condition = if lexer.last_token == KeywordUntil { parse_statement_in_region(lexer, vec![KeywordEndRepeat], |lexer| { - parse_expression(lexer) + Ok(parse_primary_expression(lexer)) }) } else { Statement::EmptyStatement { @@ -126,25 +125,29 @@ fn parse_repeat_statement(lexer: &mut ParseSession) -> Result Result { +fn parse_case_statement(lexer: &mut ParseSession) -> Statement { let start = lexer.range().start; lexer.advance(); // CASE - let selector = Box::new(parse_expression(lexer)?); + let selector = Box::new(parse_primary_expression(lexer)); - lexer.expect(KeywordOf)?; // OF + if !lexer.expect_token(KeywordOf) { + return Statement::EmptyStatement { + location: lexer.location(), + }; + } // OF lexer.advance(); let mut case_blocks = Vec::new(); if lexer.token != KeywordEndCase && lexer.token != KeywordElse { - let body = parse_body_in_region(lexer, vec![KeywordEndCase, KeywordElse])?; + let body = parse_body_in_region(lexer, vec![KeywordEndCase, KeywordElse]); let mut current_condition = None; let mut current_body = vec![]; @@ -183,16 +186,16 @@ fn parse_case_statement(lexer: &mut ParseSession) -> Result Result { +pub fn parse_primary_expression(lexer: &mut ParseSession) -> Statement { if lexer.token == KeywordSemicolon { - Ok(Statement::EmptyStatement { + Statement::EmptyStatement { location: lexer.location(), - }) + } } else { - Ok(parse_expression_list(lexer)) + parse_expression_list(lexer) } } @@ -206,7 +206,7 @@ fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { KeywordParensOpen => { lexer.advance(); super::parse_statement_in_region(lexer, vec![KeywordParensClose], |lexer| { - parse_primary_expression(lexer) + Ok(parse_primary_expression(lexer)) }) } _ => parse_leaf_expression(lexer), @@ -266,7 +266,7 @@ fn parse_array_literal(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(); From e7bfd95450b3e600c2c4e05bc8020cbb280649ca Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Mon, 26 Jul 2021 10:12:39 +0200 Subject: [PATCH 3/9] get rid of PResult from parser --- src/parser.rs | 280 ++++++++++----------- src/parser/control_parser.rs | 7 +- src/parser/expressions_parser.rs | 12 +- src/parser/tests/container_parser_tests.rs | 12 +- 4 files changed, 146 insertions(+), 165 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 88fb8da817d..5d6ceb5fa9e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -33,31 +33,26 @@ pub fn parse(mut lexer: ParseSession) -> PResult { .global_vars .push(parse_variable_block(&mut lexer, VariableBlockType::Global)), KeywordProgram => { - if let Some((pou, implementation)) = - parse_pou(&mut lexer, PouType::Program, linkage, KeywordEndProgram) - { - unit.units.push(pou); - unit.implementations.push(implementation); - } + let (pou, implementation) = + parse_pou(&mut lexer, PouType::Program, linkage, KeywordEndProgram); + unit.units.push(pou); + unit.implementations.push(implementation); } KeywordFunction => { - if let Some((pou, implementation)) = - parse_pou(&mut lexer, PouType::Function, linkage, KeywordEndFunction) - { - unit.units.push(pou); - unit.implementations.push(implementation); - } + let (pou, implementation) = + parse_pou(&mut lexer, PouType::Function, linkage, KeywordEndFunction); + unit.units.push(pou); + unit.implementations.push(implementation); } KeywordFunctionBlock => { - if let Some((pou, implementation)) = parse_pou( + let (pou, implementation) = parse_pou( &mut lexer, PouType::FunctionBlock, linkage, KeywordEndFunctionBlock, - ) { - unit.units.push(pou); - unit.implementations.push(implementation); - } + ); + unit.units.push(pou); + unit.implementations.push(implementation); } KeywordAction => { if let Some(implementation) = parse_action(&mut lexer, linkage, None) { @@ -65,7 +60,7 @@ pub fn parse(mut lexer: ParseSession) -> PResult { } } KeywordActions => { - let mut actions = parse_actions(&mut lexer, linkage)?; + let mut actions = parse_actions(&mut lexer, linkage); unit.implementations.append(&mut actions); } KeywordType => { @@ -87,35 +82,36 @@ pub fn parse(mut lexer: ParseSession) -> PResult { //the match in the loop will always return } -fn parse_actions( - mut lexer: &mut ParseSession, - linkage: LinkageType, -) -> Result, Diagnostic> { - lexer.advance(); //Consume ACTIONS - lexer.expect(Identifier)?; - let container = lexer.slice_and_advance(); - let mut result = vec![]; - - //Go through each action - while lexer.token != KeywordEndActions && !lexer.is_end_of_stream() { - match lexer.token { - KeywordAction => { - if let Some(implementation) = parse_action(&mut lexer, linkage, Some(&container)) { - result.push(implementation); +fn parse_actions(lexer: &mut ParseSession, linkage: LinkageType) -> Vec { + parse_any_in_region(lexer, vec![KeywordEndActions], |lexer| { + lexer.advance(); + let mut impls = vec![]; + if !lexer.expect_token(Identifier) { + return impls; + } + + let container = lexer.slice_and_advance(); + + //Go through each action + while lexer.token != KeywordEndActions && !lexer.is_end_of_stream() { + match lexer.token { + KeywordAction => { + if let Some(implementation) = parse_action(lexer, linkage, Some(&container)) { + impls.push(implementation); + } + } + _ => { + lexer.accept_diagnostic(Diagnostic::unexpected_token_found( + "KeywordAction".to_string(), + lexer.slice().to_string(), + lexer.location(), + )); + return impls; } - } - _ => { - return Err(Diagnostic::unexpected_token_found( - "KeywordAction".to_string(), - lexer.slice().to_string(), - lexer.location(), - )) } } - } - lexer.advance(); //Consume end actions - - Ok(result) + impls + }) } /// @@ -131,7 +127,7 @@ fn parse_pou( pou_type: PouType, linkage: LinkageType, expected_end_token: lexer::Token, -) -> Option<(Pou, Implementation)> { +) -> (Pou, Implementation) { let start = lexer.range().start; lexer.advance(); //Consume ProgramKeyword let closing_tokens = vec![ @@ -203,7 +199,7 @@ fn parse_pou( location: SourceRange::new(start..lexer.range().end), }; - Ok((pou, implementation)) + (pou, implementation) }); //check if we ended on the right end-keyword @@ -225,7 +221,7 @@ fn parse_implementation( type_name: &str, ) -> Implementation { let start = lexer.range().start; - let statements = parse_body_standalone(lexer).unwrap_or_default(); + let statements = parse_body_standalone(lexer); Implementation { name: call_name.into(), type_name: type_name.into(), @@ -251,12 +247,20 @@ fn parse_action( parse_any_in_region(lexer, closing_tokens.clone(), |lexer| { let name_or_container = lexer.slice_and_advance(); + let (container, name) = if let Some(container) = container { (container.into(), name_or_container) } else { - lexer.expect(KeywordDot)?; + if !lexer.expect_token(KeywordDot) { + return None; + } + lexer.advance(); - lexer.expect(Identifier)?; + + if !lexer.expect_token(Identifier) { + return None; + } + let name = lexer.slice_and_advance(); (name_or_container, name) }; @@ -272,7 +276,7 @@ fn parse_action( lexer.location(), )) } - Ok(implementation) + Some(implementation) }) } @@ -283,20 +287,12 @@ fn parse_type(lexer: &mut ParseSession) -> Option { lexer.consume_or_report(KeywordColon); let result = parse_full_data_type_definition(lexer, Some(name)); - if let Some((DataTypeDeclaration::DataTypeDefinition { data_type }, initializer)) = result { lexer.consume_or_report(KeywordEndType); Some(UserTypeDeclaration { data_type, initializer, }) - // } else { - // //What do we do if we want to continue parsing :( - // Err(Diagnostic::unexpected_token_found(Some( - // "struct, enum or subrange".into()), - // lexer.slice().into(), - // lexer.location(), - // )) } else { None } @@ -315,7 +311,7 @@ fn parse_full_data_type_definition( }; parse_any_in_region(lexer, vec![end_keyword], |lexer| { if lexer.allow(&KeywordDotDotDot) { - Ok(( + Some(( DataTypeDeclaration::DataTypeDefinition { data_type: DataType::VarArgs { referenced_type: None, @@ -346,16 +342,16 @@ fn parse_full_data_type_definition( fn parse_data_type_definition( lexer: &mut ParseSession, name: Option, -) -> Result { - let result = if lexer.allow(&KeywordStruct) { - //STRUCT +) -> Option { + if lexer.allow(&KeywordStruct) { + // Parse struct let mut variables = Vec::new(); while lexer.token == Identifier { if let Some(variable) = parse_variable(lexer) { variables.push(variable); } } - Ok(( + Some(( DataTypeDeclaration::DataTypeDefinition { data_type: DataType::StructType { name, variables }, }, @@ -371,37 +367,38 @@ fn parse_data_type_definition( parse_type_reference_type_definition(lexer, name) } else { //no datatype? - Err(Diagnostic::unexpected_token_found( + lexer.accept_diagnostic(Diagnostic::unexpected_token_found( "DataTypeDefinition".into(), format!("{:?}", lexer.token), lexer.location(), - )) - }; - - result + )); + None + } } fn parse_type_reference_type_definition( lexer: &mut ParseSession, name: Option, -) -> PResult<(DataTypeDeclaration, Option)> { +) -> Option<(DataTypeDeclaration, Option)> { //Subrange let referenced_type = lexer.slice_and_advance(); let bounds = if lexer.allow(&KeywordParensOpen) { // INT (..) := - let bounds = parse_expression(lexer)?; - lexer.expect(KeywordParensClose)?; + let bounds = parse_expression(lexer); + lexer.expect_token(KeywordParensClose).then(|| {})?; lexer.advance(); Some(bounds) } else { None }; + let initial_value = if lexer.allow(&KeywordAssignment) { - Some(parse_expression(lexer)?) + Some(parse_expression(lexer)) } else { None }; + if name.is_some() || bounds.is_some() { let data_type = DataTypeDeclaration::DataTypeDefinition { data_type: DataType::SubRangeType { @@ -410,9 +407,9 @@ fn parse_type_reference_type_definition( bounds, }, }; - Ok((data_type, initial_value)) + Some((data_type, initial_value)) } else { - Ok(( + Some(( DataTypeDeclaration::DataTypeReference { referenced_type }, initial_value, )) @@ -422,26 +419,16 @@ fn parse_type_reference_type_definition( fn parse_string_type_definition( lexer: &mut ParseSession, name: Option, -) -> PResult<(DataTypeDeclaration, Option)> { +) -> Option<(DataTypeDeclaration, Option)> { let is_wide = lexer.token == KeywordWideString; lexer.advance(); - let size = lexer - .allow(&KeywordSquareParensOpen) - .then(|| { - parse_any_in_region(lexer, vec![KeywordSquareParensClose], |lexer| { - let size_statement = parse_expression(lexer)?; - Ok(size_statement) - }) + let size = lexer.allow(&KeywordSquareParensOpen).then(|| { + parse_any_in_region(lexer, vec![KeywordSquareParensClose], |lexer| { + parse_expression(lexer) }) - .flatten(); - - let initializer = if lexer.allow(&KeywordAssignment) { - Some(parse_expression(lexer)?) - } else { - None - }; - Ok(( + }); + Some(( DataTypeDeclaration::DataTypeDefinition { data_type: DataType::StringType { name, @@ -449,30 +436,36 @@ fn parse_string_type_definition( size, }, }, - initializer, + lexer + .allow(&KeywordAssignment) + .then(|| parse_expression(lexer)), )) } fn parse_enum_type_definition( lexer: &mut ParseSession, name: Option, -) -> PResult<(DataTypeDeclaration, Option)> { +) -> Option<(DataTypeDeclaration, Option)> { let elements = parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| { - //ENUM + // Parse Enum - we expect at least one element + let mut elements = Vec::new(); - //we expect at least one element - lexer.expect(Identifier)?; + if !lexer.expect_token(Identifier) { + return None; + } elements.push(lexer.slice_and_advance()); - //parse additional elements separated by , + + // parse additional elements separated by ',' while lexer.allow(&KeywordComma) { - lexer.expect(Identifier)?; + if !lexer.expect_token(Identifier) { + return None; + } elements.push(lexer.slice_and_advance()); } - Ok(elements) - }) - .unwrap_or_default(); + Some(elements) + })?; - Ok(( + Some(( DataTypeDeclaration::DataTypeDefinition { data_type: DataType::EnumType { name, elements }, }, @@ -483,19 +476,27 @@ fn parse_enum_type_definition( fn parse_array_type_definition( lexer: &mut ParseSession, name: Option, -) -> PResult<(DataTypeDeclaration, Option)> { - let range = parse_statement_in_region(lexer, vec![KeywordOf], |lexer| { - //ARRAY - //expect open square - lexer.expect(KeywordSquareParensOpen)?; +) -> Option<(DataTypeDeclaration, Option)> { + let range = parse_any_in_region(lexer, vec![KeywordOf], |lexer| { + // Parse Array range + + if !lexer.expect_token(KeywordSquareParensOpen) { + // array range not opened + return None; + } lexer.advance(); - //parse range - let range = parse_primary_expression(lexer); - //expect close range - lexer.expect(KeywordSquareParensClose)?; + + let range_statement = parse_primary_expression(lexer); + + if !lexer.expect_token(KeywordSquareParensClose) { + // array range not closed + return None; + } lexer.advance(); - Ok(range) - }); + + Some(range_statement) + })?; + let inner_type_defintion = parse_data_type_definition(lexer, None); inner_type_defintion.map(|(reference, initializer)| { ( @@ -514,22 +515,19 @@ fn parse_array_type_definition( /// parse a body and recovers until the given `end_keywords` fn parse_body_in_region(lexer: &mut ParseSession, end_keywords: Vec) -> Vec { parse_any_in_region(lexer, end_keywords, |lexer| parse_body_standalone(lexer)) - .unwrap_or_default() } -fn parse_body_standalone(lexer: &mut ParseSession) -> PResult> { +fn parse_body_standalone(lexer: &mut ParseSession) -> Vec { let mut statements = Vec::new(); while !lexer.closes_open_region(&lexer.token) { - statements.push(parse_control(lexer)?); + statements.push(parse_control(lexer)); } - Ok(statements) + statements } -/** - * parses a statement ending with a ; - */ +/// parses a statement ending with a ';' fn parse_statement(lexer: &mut ParseSession) -> Statement { - let result = parse_statement_in_region(lexer, vec![KeywordSemicolon, KeywordColon], |lexer| { + let result = parse_any_in_region(lexer, vec![KeywordSemicolon, KeywordColon], |lexer| { parse_expression(lexer) }); if lexer.last_token == KeywordColon { @@ -541,39 +539,24 @@ fn parse_statement(lexer: &mut ParseSession) -> Statement { } } -pub fn parse_statement_in_region PResult>( - lexer: &mut ParseSession, - closing_tokens: Vec, - parse_fn: F, -) -> Statement { - let start = lexer.range().start; - parse_any_in_region(lexer, closing_tokens, parse_fn).unwrap_or_else(|| { - let end = lexer.range().end; - let location = SourceRange::new(start..end); - //drop the originally parsed statement and replace with an empty-statement - Statement::EmptyStatement { location } - }) -} - -pub fn parse_any_in_region PResult>( +pub fn parse_any_in_region T>( lexer: &mut ParseSession, closing_tokens: Vec, parse_fn: F, -) -> Option { +) -> T { lexer.enter_region(closing_tokens); - let result = parse_fn(lexer).map(Some).unwrap_or_else(|diagnostic| { - lexer.accept_diagnostic(diagnostic); - None - }); - //try to recover by eating everything until we believe the parser is able to continue + let result = parse_fn(lexer); + + // try to recover by eating everything until + // we believe the parser is able to continue lexer.recover_until_close(); lexer.close_region(); - //Report a diagnostic + result } -fn parse_expression(lexer: &mut ParseSession) -> Result { - Ok(parse_primary_expression(lexer)) +fn parse_expression(lexer: &mut ParseSession) -> Statement { + parse_primary_expression(lexer) } fn parse_reference(lexer: &mut ParseSession) -> Statement { @@ -589,8 +572,8 @@ fn parse_reference(lexer: &mut ParseSession) -> Statement { } } -fn parse_control(lexer: &mut ParseSession) -> Result { - Ok(parse_control_statement(lexer)) +fn parse_control(lexer: &mut ParseSession) -> Statement { + parse_control_statement(lexer) } fn parse_variable_block_type(block_type: &Token) -> VariableBlockType { @@ -617,9 +600,8 @@ fn parse_variable_block( variables.push(variable); } } - Ok(variables) - }) - .unwrap_or_default(); + variables + }); VariableBlock { variables, variable_block_type, diff --git a/src/parser/control_parser.rs b/src/parser/control_parser.rs index 136c244f3e6..f880c0fde3f 100644 --- a/src/parser/control_parser.rs +++ b/src/parser/control_parser.rs @@ -1,8 +1,7 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder use crate::ast::*; use crate::lexer::Token::*; -use crate::parser::parse_body_in_region; -use crate::parser::parse_statement_in_region; +use crate::parser::{parse_any_in_region, parse_body_in_region}; use crate::Diagnostic; use super::ParseSession; @@ -116,8 +115,8 @@ 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_statement_in_region(lexer, vec![KeywordEndRepeat], |lexer| { - Ok(parse_primary_expression(lexer)) + parse_any_in_region(lexer, vec![KeywordEndRepeat], |lexer| { + parse_primary_expression(lexer) }) } else { Statement::EmptyStatement { diff --git a/src/parser/expressions_parser.rs b/src/parser/expressions_parser.rs index a7a4c5b6d67..3eb71d89d70 100644 --- a/src/parser/expressions_parser.rs +++ b/src/parser/expressions_parser.rs @@ -2,7 +2,7 @@ use crate::ast::*; use crate::lexer::Token::*; -use crate::parser::parse_statement_in_region; +use crate::parser::parse_any_in_region; use crate::Diagnostic; use std::str::FromStr; @@ -205,8 +205,8 @@ fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { match lexer.token { KeywordParensOpen => { lexer.advance(); - super::parse_statement_in_region(lexer, vec![KeywordParensClose], |lexer| { - Ok(parse_primary_expression(lexer)) + super::parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| { + parse_primary_expression(lexer) }) } _ => parse_leaf_expression(lexer), @@ -308,12 +308,12 @@ pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result Date: Mon, 26 Jul 2021 10:58:56 +0200 Subject: [PATCH 4/9] get rid of ~200 unwrap()s --- src/codegen/tests.rs | 4 +- src/index/tests/index_tests.rs | 18 ++-- src/lib.rs | 9 +- src/parser.rs | 11 +- src/parser/tests/container_parser_tests.rs | 20 ++-- src/parser/tests/control_parser_tests.rs | 50 ++++----- src/parser/tests/expressions_parser_tests.rs | 100 +++++++++--------- src/parser/tests/function_parser_tests.rs | 10 +- src/parser/tests/initializer_parser_tests.rs | 16 ++- src/parser/tests/misc_parser_tests.rs | 4 +- .../parse_error_containers_tests.rs | 20 ++-- .../parse_error_literals_tests.rs | 8 +- .../parse_errors/parse_error_messages_test.rs | 10 +- .../parse_error_statements_tests.rs | 42 ++++---- src/parser/tests/program_parser_tests.rs | 10 +- src/parser/tests/statement_parser_tests.rs | 17 ++- src/parser/tests/type_parser_tests.rs | 23 ++-- src/parser/tests/variable_parser_tests.rs | 6 +- 18 files changed, 181 insertions(+), 197 deletions(-) diff --git a/src/codegen/tests.rs b/src/codegen/tests.rs index 2173a2ba756..263c02a1d69 100644 --- a/src/codegen/tests.rs +++ b/src/codegen/tests.rs @@ -7,7 +7,7 @@ mod typesystem_test; macro_rules! codegen_wihout_unwrap { ($code:tt) => {{ let lexer = crate::lexer::lex($code); - let (mut ast, ..) = crate::parser::parse(lexer).unwrap(); + let (mut ast, ..) = crate::parser::parse(lexer); let context = inkwell::context::Context::create(); crate::ast::pre_process(&mut ast); @@ -21,7 +21,7 @@ macro_rules! codegen_wihout_unwrap { macro_rules! codegen { ($code:tt) => {{ let lexer = crate::lexer::lex($code); - let (mut ast, ..) = crate::parser::parse(lexer).unwrap(); + let (mut ast, ..) = crate::parser::parse(lexer); let context = inkwell::context::Context::create(); crate::ast::pre_process(&mut ast); diff --git a/src/index/tests/index_tests.rs b/src/index/tests/index_tests.rs index 66929f42ab9..d1f7d3b78f5 100644 --- a/src/index/tests/index_tests.rs +++ b/src/index/tests/index_tests.rs @@ -8,7 +8,7 @@ use crate::{ast::*, index::VariableType, typesystem::DataTypeInformation}; macro_rules! index { ($code:tt) => {{ let lexer = crate::lexer::lex($code); - let (mut ast, ..) = crate::parser::parse(lexer).unwrap(); + let (mut ast, ..) = crate::parser::parse(lexer); crate::ast::pre_process(&mut ast); crate::index::visitor::visit(&ast) @@ -563,7 +563,7 @@ fn pre_processing_generates_inline_enums_global() { inline_enum : (a,b,c); END_VAR "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -606,7 +606,7 @@ fn pre_processing_generates_inline_structs_global() { inline_struct: STRUCT a: INT; END_STRUCT END_VAR "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -649,7 +649,7 @@ fn pre_processing_generates_inline_enums() { END_VAR END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -685,7 +685,7 @@ fn pre_processing_generates_inline_structs() { END_VAR END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -728,7 +728,7 @@ fn pre_processing_generates_inline_arrays() { END_VAR END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -778,7 +778,7 @@ fn pre_processing_generates_inline_array_of_array() { END_VAR END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -859,7 +859,7 @@ fn pre_processing_nested_array_in_struct() { END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); @@ -918,7 +918,7 @@ fn pre_processing_generates_inline_array_of_array_of_array() { END_VAR END_PROGRAM "#); - let (mut ast, ..) = parser::parse(lexer).unwrap(); + let (mut ast, ..) = parser::parse(lexer); // WHEN the AST ist pre-processed crate::ast::pre_process(&mut ast); diff --git a/src/lib.rs b/src/lib.rs index 630fd109c59..d8295c831a3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,7 +271,7 @@ pub fn compile_module<'c>( .load_source() .map_err(|err| CompileError::io_error(err, container.get_location().to_string()))?; - let (mut parse_result, diagnostics) = parse(e.source.as_str())?; + let (mut parse_result, diagnostics) = parse(e.source.as_str()); ast::pre_process(&mut parse_result); full_index.import(index::visitor::visit(&parse_result)); unit.import(parse_result); @@ -310,10 +310,7 @@ pub fn compile_module<'c>( Ok(code_generator) } -fn parse(source: &str) -> Result { - //Start lexing +fn parse(source: &str) -> ParsedAst { let lexer = lexer::lex(source); - //Parse - //TODO : Parser should also return compile errors with sane locations - parser::parse(lexer).map_err(|err| err.into()) + parser::parse(lexer) } diff --git a/src/parser.rs b/src/parser.rs index 5d6ceb5fa9e..8f4dcc226b9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -13,11 +13,9 @@ mod expressions_parser; #[cfg(test)] mod tests; - -pub type PResult = Result; pub type ParsedAst = (CompilationUnit, Vec); -pub fn parse(mut lexer: ParseSession) -> PResult { +pub fn parse(mut lexer: ParseSession) -> ParsedAst { let mut unit = CompilationUnit::default(); let mut linkage = LinkageType::Internal; @@ -68,13 +66,14 @@ pub fn parse(mut lexer: ParseSession) -> PResult { unit.types.push(unit_type); } } - KeywordEndActions | End => return Ok((unit, lexer.diagnostics)), + KeywordEndActions | End => return (unit, lexer.diagnostics), _ => { - return Err(Diagnostic::unexpected_token_found( + lexer.accept_diagnostic(Diagnostic::unexpected_token_found( "StartKeyword".to_string(), lexer.slice().to_string(), lexer.location(), - )) + )); + lexer.advance(); } }; linkage = LinkageType::Internal; diff --git a/src/parser/tests/container_parser_tests.rs b/src/parser/tests/container_parser_tests.rs index dc76ceeb9d6..d1f32d8b734 100644 --- a/src/parser/tests/container_parser_tests.rs +++ b/src/parser/tests/container_parser_tests.rs @@ -7,7 +7,7 @@ use pretty_assertions::*; #[test] fn action_container_parsed() { let lexer = lex("ACTIONS foo ACTION bar END_ACTION END_ACTIONS"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; assert_eq!(prg.name, "foo.bar"); @@ -17,7 +17,7 @@ fn action_container_parsed() { #[test] fn two_action_containers_parsed() { let lexer = lex("ACTIONS foo ACTION bar END_ACTION ACTION buz END_ACTION END_ACTIONS"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; assert_eq!(prg.name, "foo.bar"); @@ -31,7 +31,7 @@ fn two_action_containers_parsed() { #[test] fn mixed_action_types_parsed() { let lexer = lex("PROGRAM foo END_PROGRAM ACTIONS foo ACTION bar END_ACTION END_ACTIONS ACTION foo.buz END_ACTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[1]; assert_eq!(prg.name, "foo.bar"); @@ -45,7 +45,7 @@ fn mixed_action_types_parsed() { #[test] fn actions_with_no_container_error() { let lexer = lex("ACTIONS ACTION bar END_ACTION ACTION buz END_ACTION END_ACTIONS"); - let errors = parse(lexer).unwrap().1; + let errors = parse(lexer).1; assert_eq!( errors.first().unwrap(), &Diagnostic::unexpected_token_found("Identifier".into(), "ACTION".into(), (8..14).into()) @@ -55,7 +55,7 @@ fn actions_with_no_container_error() { #[test] fn actions_with_invalid_token() { let lexer = lex("ACTIONS LIMA BRAVO END_ACTIONS"); - let errors = parse(lexer).unwrap().1; + let errors = parse(lexer).1; assert_eq!( errors.first().unwrap(), &Diagnostic::unexpected_token_found( @@ -69,7 +69,7 @@ fn actions_with_invalid_token() { #[test] fn two_programs_can_be_parsed() { let lexer = lex("PROGRAM foo END_PROGRAM PROGRAM bar END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; assert_eq!(prg.name, "foo"); @@ -80,7 +80,7 @@ fn two_programs_can_be_parsed() { #[test] fn simple_program_with_varblock_can_be_parsed() { let lexer = lex("PROGRAM buz VAR END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; @@ -90,7 +90,7 @@ fn simple_program_with_varblock_can_be_parsed() { #[test] fn simple_program_with_two_varblocks_can_be_parsed() { let lexer = lex("PROGRAM buz VAR END_VAR VAR END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; @@ -100,7 +100,7 @@ fn simple_program_with_two_varblocks_can_be_parsed() { #[test] fn single_action_parsed() { let lexer = lex("ACTION foo.bar END_ACTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; assert_eq!(prg.name, "foo.bar"); @@ -110,7 +110,7 @@ fn single_action_parsed() { #[test] fn two_actions_parsed() { let lexer = lex("ACTION foo.bar END_ACTION ACTION fuz.bar END_ACTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; assert_eq!(prg.name, "foo.bar"); diff --git a/src/parser/tests/control_parser_tests.rs b/src/parser/tests/control_parser_tests.rs index 353dbe78785..0f88bbaff74 100644 --- a/src/parser/tests/control_parser_tests.rs +++ b/src/parser/tests/control_parser_tests.rs @@ -13,7 +13,7 @@ fn if_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -46,7 +46,7 @@ fn if_else_statement_with_expressions() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -91,7 +91,7 @@ fn if_elsif_elsif_else_statement_with_expressions() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -149,7 +149,7 @@ fn for_with_literals_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -181,7 +181,7 @@ fn for_with_step_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -217,7 +217,7 @@ fn for_with_reference_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -251,7 +251,7 @@ fn for_with_body_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -290,7 +290,7 @@ fn while_with_literal() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -315,7 +315,7 @@ fn while_with_expression() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -348,7 +348,7 @@ fn while_with_body_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -382,7 +382,7 @@ fn repeat_with_literal() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -408,7 +408,7 @@ fn repeat_with_expression() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -442,7 +442,7 @@ fn repeat_with_body_statement() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -476,7 +476,7 @@ fn case_statement_with_one_condition() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -515,7 +515,7 @@ fn case_statement_with_else_and_no_condition() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -542,7 +542,7 @@ fn case_statement_with_no_conditions() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -572,7 +572,7 @@ fn case_statement_with_one_condition_and_an_else() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -617,7 +617,7 @@ fn case_statement_with_one_empty_condition_and_an_else() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -658,7 +658,7 @@ fn case_statement_with_multiple_conditions() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -724,7 +724,7 @@ fn case_statement_with_multiple_expressions_per_condition() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -796,7 +796,7 @@ fn if_stmnt_location_test() { END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -835,7 +835,7 @@ fn for_stmnt_location_test() { END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -896,7 +896,7 @@ fn while_stmnt_location_test() { END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -922,7 +922,7 @@ fn case_stmnt_location_test() { END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -946,7 +946,7 @@ fn call_stmnt_location_test() { END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; diff --git a/src/parser/tests/expressions_parser_tests.rs b/src/parser/tests/expressions_parser_tests.rs index 5e7ad280119..8bf93ef24a7 100644 --- a/src/parser/tests/expressions_parser_tests.rs +++ b/src/parser/tests/expressions_parser_tests.rs @@ -6,7 +6,7 @@ use pretty_assertions::*; #[test] fn single_statement_parsed() { let lexer = super::lex("PROGRAM exp x; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -21,7 +21,7 @@ fn single_statement_parsed() { #[test] fn qualified_reference_statement_parsed() { let lexer = super::lex("PROGRAM exp a.x; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -48,7 +48,7 @@ fn qualified_reference_statement_parsed() { #[test] fn literal_can_be_parsed() { let lexer = super::lex("PROGRAM exp 7; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -63,7 +63,7 @@ fn literal_can_be_parsed() { #[test] fn additon_of_two_variables_parsed() { let lexer = super::lex("PROGRAM exp x+y; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -89,7 +89,7 @@ fn additon_of_two_variables_parsed() { #[test] fn additon_of_three_variables_parsed() { let lexer = super::lex("PROGRAM exp x+y-z; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -128,7 +128,7 @@ fn additon_of_three_variables_parsed() { #[test] fn parenthesis_expressions_should_not_change_the_ast() { let lexer = super::lex("PROGRAM exp (x+y); END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -154,7 +154,7 @@ fn parenthesis_expressions_should_not_change_the_ast() { #[test] fn multiplication_expressions_parse() { let lexer = super::lex("PROGRAM exp 1*2/7; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -181,7 +181,7 @@ fn multiplication_expressions_parse() { #[test] fn addition_ast_test() { let lexer = super::lex("PROGRAM exp 1+2; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -202,7 +202,7 @@ fn addition_ast_test() { #[test] fn multiplication_ast_test() { let lexer = super::lex("PROGRAM exp 1+2*3; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -229,7 +229,7 @@ fn multiplication_ast_test() { #[test] fn term_ast_test() { let lexer = super::lex("PROGRAM exp 1+2*3+4; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -263,7 +263,7 @@ fn term_ast_test() { fn module_expression_test() { let lexer = super::lex("PROGRAM exp 5 MOD 2; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -285,7 +285,7 @@ fn module_expression_test() { #[test] fn parenthesized_term_ast_test() { let lexer = super::lex("PROGRAM exp (1+2)*(3+4); END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -318,7 +318,7 @@ fn parenthesized_term_ast_test() { #[test] fn boolean_literals_can_be_parsed() { let lexer = super::lex("PROGRAM exp TRUE OR FALSE; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -339,7 +339,7 @@ fn boolean_literals_can_be_parsed() { #[test] fn assignment_test() { let lexer = super::lex("PROGRAM exp x := 3; x := 1 + 2; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; { @@ -380,7 +380,7 @@ fn assignment_test() { #[test] fn equality_expression_test() { let lexer = super::lex("PROGRAM exp x = 3; x - 0 <> 1 + 2; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; { @@ -436,7 +436,7 @@ fn comparison_expression_test() { e := 2 + 1 > 3 + 1; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; { @@ -527,7 +527,7 @@ fn comparison_expression_test() { #[test] fn boolean_expression_ast_test() { let lexer = super::lex("PROGRAM exp a AND NOT b OR c XOR d; END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -563,7 +563,7 @@ fn boolean_expression_ast_test() { #[test] fn boolean_expression_param_ast_test() { let lexer = super::lex("PROGRAM exp a AND (NOT (b OR c) XOR d); END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -605,7 +605,7 @@ fn signed_literal_minus_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -630,7 +630,7 @@ fn literal_date_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let ast_string = format!("{:#?}", &result.implementations[0].statements); let expected_ast = r#"[ LiteralDate { @@ -664,7 +664,7 @@ fn literal_time_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let ast_string = format!("{:#?}", &result.implementations[0].statements); let expected_ast = r#"[ LiteralTime { @@ -775,7 +775,7 @@ fn literal_time_of_day_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let ast_string = format!("{:#?}", &result.implementations[0].statements); let expected_ast = r#"[ LiteralTimeOfDay { @@ -829,7 +829,7 @@ fn literal_date_and_time_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let ast_string = format!("{:#?}", &result.implementations[0].statements); let expected_ast = r#"[ LiteralDateAndTime { @@ -875,7 +875,7 @@ fn literal_real_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements; @@ -910,7 +910,7 @@ fn signed_literal_expression_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -940,7 +940,7 @@ fn signed_literal_expression_reversed_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -970,7 +970,7 @@ fn or_compare_expressions_priority_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1003,7 +1003,7 @@ fn addition_compare_or_priority_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1042,7 +1042,7 @@ fn boolean_priority_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1081,7 +1081,7 @@ fn comparison_priority_test() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1121,7 +1121,7 @@ fn expression_list() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1153,7 +1153,7 @@ fn expression_list_assignments() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1203,7 +1203,7 @@ fn range_expression() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1268,7 +1268,7 @@ fn negative_range_expression() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1301,7 +1301,7 @@ fn negative_range_expression_space() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1334,7 +1334,7 @@ fn range_expression2() { END_PROGRAM ", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1360,7 +1360,7 @@ fn function_call_no_params() { END_PROGRAM ", ); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let statement = &parse_result.implementations[0].statements[0]; @@ -1385,7 +1385,7 @@ fn function_call_params() { END_PROGRAM ", ); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let statement = &parse_result.implementations[0].statements[0]; @@ -1420,7 +1420,7 @@ fn string_can_be_parsed() { let lexer = super::lex( "PROGRAM buz VAR x : STRING; END_VAR x := 'Hello, World!'; x := ''; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let unit = &result.units[0]; let prg = &result.implementations[0]; @@ -1474,7 +1474,7 @@ fn wide_string_can_be_parsed() { let lexer = super::lex( "PROGRAM buz VAR x : WSTRING; END_VAR x := \"Hello, World!\"; x := \"\"; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let unit = &result.units[0]; let prg = &result.implementations[0]; @@ -1528,7 +1528,7 @@ fn arrays_can_be_parsed() { let lexer = super::lex( "PROGRAM buz VAR x : ARRAY[0..9] OF STRING; END_VAR x[0] := 'Hello, World!'; x[y] := ''; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let unit = &result.units[0]; let prg = &result.implementations[0]; @@ -1605,7 +1605,7 @@ fn nested_arrays_can_be_parsed() { let lexer = super::lex( "PROGRAM buz VAR x : ARRAY[0..9] OF ARRAY[0..9] OF STRING; END_VAR x[0][1] := 'Hello, World!'; x[y][1] := ''; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let unit = &result.units[0]; let prg = &result.implementations[0]; @@ -1705,7 +1705,7 @@ fn multidim_arrays_can_be_parsed() { let lexer = super::lex( "PROGRAM buz VAR x : ARRAY[0..9,1..2] OF STRING; END_VAR x[0,1] := 'Hello, World!'; x[y,1] := ''; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let unit = &result.units[0]; let prg = &result.implementations[0]; @@ -1809,7 +1809,7 @@ fn arrays_in_structs_can_be_parsed() { " PROGRAM buz VAR x : MyStructWithArray; END_VAR x.y[7]; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1839,7 +1839,7 @@ fn arrays_of_structs_can_be_parsed() { " PROGRAM buz VAR x : ARRAY[0..1] OF MyStruct; END_VAR x[1].y; END_PROGRAM", ); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -1872,7 +1872,7 @@ fn function_call_formal_params() { END_PROGRAM ", ); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let statement = &parse_result.implementations[0].statements[0]; @@ -1926,7 +1926,7 @@ fn function_call_return_params() { END_PROGRAM ", ); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let statement = &parse_result.implementations[0].statements[0]; @@ -1965,7 +1965,7 @@ fn function_call_return_params() { fn literals_location_test() { let source = "PROGRAM prg 7; 'hello'; TRUE; 3.1415; END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -2006,7 +2006,7 @@ fn literals_location_test() { fn reference_location_test() { let source = "PROGRAM prg a;bb;ccc; END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; @@ -2040,7 +2040,7 @@ fn expressions_location_test() { a := a + 4; END_PROGRAM"; let lexer = super::lex(source); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let unit = &parse_result.implementations[0]; diff --git a/src/parser/tests/function_parser_tests.rs b/src/parser/tests/function_parser_tests.rs index c0216ee52cb..42e3b566fef 100644 --- a/src/parser/tests/function_parser_tests.rs +++ b/src/parser/tests/function_parser_tests.rs @@ -8,7 +8,7 @@ use pretty_assertions::*; #[test] fn simple_foo_function_can_be_parsed() { let lexer = lex("FUNCTION foo : INT END_FUNCTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; assert_eq!(prg.pou_type, PouType::Function); @@ -24,7 +24,7 @@ fn simple_foo_function_can_be_parsed() { #[test] fn simple_foo_function_block_can_be_parsed() { let lexer = lex("FUNCTION_BLOCK foo END_FUNCTION_BLOCK"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; assert_eq!(prg.pou_type, PouType::FunctionBlock); @@ -35,7 +35,7 @@ fn simple_foo_function_block_can_be_parsed() { #[test] fn a_function_with_varargs_can_be_parsed() { let lexer = lex("FUNCTION foo : INT VAR_INPUT x : INT; y : ...; END_VAR END_FUNCTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; @@ -65,7 +65,7 @@ fn a_function_with_varargs_can_be_parsed() { #[test] fn a_function_with_typed_varargs_can_be_parsed() { let lexer = lex("FUNCTION foo : INT VAR_INPUT x : INT; y : INT...; END_VAR END_FUNCTION"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; @@ -106,7 +106,7 @@ fn varargs_parameters_can_be_parsed() { END_VAR END_FUNCTION "); - let (parse_result, diagnostics) = parse(lexer).unwrap(); + let (parse_result, diagnostics) = parse(lexer); assert_eq!( format!("{:#?}", diagnostics), diff --git a/src/parser/tests/initializer_parser_tests.rs b/src/parser/tests/initializer_parser_tests.rs index 9ac4ad836b8..7fed470bb41 100644 --- a/src/parser/tests/initializer_parser_tests.rs +++ b/src/parser/tests/initializer_parser_tests.rs @@ -24,7 +24,7 @@ fn initial_scalar_values_can_be_parsed() { END_VAR END_PROGRAM "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { @@ -126,7 +126,7 @@ fn array_initializer_can_be_parsed() { x : ARRAY[0..2] OF INT := [7,8,9]; END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { name: "x", @@ -176,7 +176,7 @@ fn multi_dim_array_initializer_can_be_parsed() { x : MyMultiArray := [[1,2],[3,4],[5,6]]; END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { name: "x", @@ -246,7 +246,7 @@ fn array_initializer_multiplier_can_be_parsed() { x : ARRAY[0..2] OF INT := [3(7)]; END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { name: "x", @@ -289,7 +289,7 @@ fn struct_initializer_can_be_parsed() { x : Point := (x := 1, y:= 2); END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { name: "x", @@ -330,8 +330,7 @@ fn array_initializer_in_pou_can_be_parsed() { my_array: ARRAY[0..2] OF INT := [5,6,7]; END_VAR END_PROGRAM - "#)) - .unwrap(); + "#)); let member = &result.units[0].variable_blocks[0].variables[0]; if let Some(initializer) = &member.initializer { @@ -361,8 +360,7 @@ fn array_initializer_in_pou_can_be_parsed() { fn array_type_initialization_with_literals_can_be_parsed_test() { let (result, ..) = parse(lex(r#" TYPE MyArray : ARRAY[0..2] OF INT := [1,2,3]; END_TYPE - "#)) - .unwrap(); + "#)); let initializer = &result.types[0].initializer; let ast_string = format!("{:#?}", &initializer); diff --git a/src/parser/tests/misc_parser_tests.rs b/src/parser/tests/misc_parser_tests.rs index 3591ce17e68..77f192e8612 100644 --- a/src/parser/tests/misc_parser_tests.rs +++ b/src/parser/tests/misc_parser_tests.rs @@ -7,14 +7,14 @@ use pretty_assertions::*; #[test] fn empty_returns_empty_compilation_unit() { - let (result, ..) = parse(lex("")).unwrap(); + let (result, ..) = parse(lex("")); assert_eq!(result.units.len(), 0); } #[test] fn programs_can_be_external() { let lexer = lex("@EXTERNAL PROGRAM foo END_PROGRAM"); - let parse_result = parse(lexer).unwrap().0; + let parse_result = parse(lexer).0; let implementation = &parse_result.implementations[0]; assert_eq!(LinkageType::External, implementation.linkage); } diff --git a/src/parser/tests/parse_errors/parse_error_containers_tests.rs b/src/parser/tests/parse_errors/parse_error_containers_tests.rs index 91dcddb0cf0..fc2a713642d 100644 --- a/src/parser/tests/parse_errors/parse_error_containers_tests.rs +++ b/src/parser/tests/parse_errors/parse_error_containers_tests.rs @@ -25,7 +25,7 @@ fn missing_pou_name() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); //expected end of statement (e.g. ;), but found KeywordEndProgram at line: 1 offset: 14..25" //Expecting a missing semicolon message let expected = Diagnostic::unexpected_token_found( @@ -58,7 +58,7 @@ fn missing_pou_name_2() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, vec![ @@ -98,7 +98,7 @@ fn illegal_end_pou_keyword() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); let expected = Diagnostic::unexpected_token_found( format!("{:?}", Token::KeywordEndProgram), "END_FUNCTION".into(), @@ -131,7 +131,7 @@ fn function_without_return_variable_declaration() { "); // WHEN the function is parsed - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); // THEN I expect a diagnostic complaining about a missing return type let expected = Diagnostic::unexpected_token_found( @@ -162,7 +162,7 @@ fn function_with_illegal_return_variable_declaration() { END_FUNCTION "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); //expected end of statement (e.g. ;), but found KeywordEndProgram at line: 1 offset: 14..25" //Expecting a missing semicolon message let expected = Diagnostic::unexpected_token_found( @@ -193,7 +193,7 @@ fn program_with_illegal_return_variable_declaration() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); //expected end of statement (e.g. ;), but found KeywordEndProgram at line: 1 offset: 14..25" //Expecting a missing semicolon message let expected = @@ -223,7 +223,7 @@ fn unclosed_var_container() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); assert_eq!( vec![Diagnostic::unexpected_token_found( "KeywordEndVar".into(), @@ -260,7 +260,7 @@ fn test_unexpected_type_declaration_error_message() { END_PROGRAM END_TYPE "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( vec![ Diagnostic::unexpected_token_found( @@ -286,7 +286,7 @@ fn test_unexpected_type_declaration_error_message() { #[test] fn a_program_needs_to_end_with_end_program() { let lexer = lex("PROGRAM buz "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, vec![Diagnostic::unexpected_token_found( @@ -300,7 +300,7 @@ fn a_program_needs_to_end_with_end_program() { #[test] fn a_variable_declaration_block_needs_to_end_with_endvar() { let lexer = lex("PROGRAM buz VAR END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, diff --git a/src/parser/tests/parse_errors/parse_error_literals_tests.rs b/src/parser/tests/parse_errors/parse_error_literals_tests.rs index 6985b20192b..3fb7cc0086e 100644 --- a/src/parser/tests/parse_errors/parse_error_literals_tests.rs +++ b/src/parser/tests/parse_errors/parse_error_literals_tests.rs @@ -11,7 +11,7 @@ fn illegal_literal_time_missing_segments_test() { T#; END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, vec![Diagnostic::unexpected_token_found( @@ -30,7 +30,7 @@ fn time_literal_problems_can_be_recovered_from_during_parsing() { x; END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let actual_statements = cu.implementations[0].statements.len(); assert_eq!(actual_statements, 2); @@ -51,7 +51,7 @@ fn illegal_literal_time_double_segments_test() { END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics[0], Diagnostic::syntax_error( @@ -69,7 +69,7 @@ fn illegal_literal_time_out_of_order_segments_test() { END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics[0], Diagnostic::syntax_error( diff --git a/src/parser/tests/parse_errors/parse_error_messages_test.rs b/src/parser/tests/parse_errors/parse_error_messages_test.rs index 947ae60f672..c84a59dc397 100644 --- a/src/parser/tests/parse_errors/parse_error_messages_test.rs +++ b/src/parser/tests/parse_errors/parse_error_messages_test.rs @@ -10,7 +10,7 @@ fn test_unexpected_token_error_message() { END_PROGRAM "; let lexer = super::super::lex(source); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( format!("{:?}", diagnostics), @@ -36,11 +36,11 @@ fn test_unexpected_token_error_message2() { ); let parse_result = parse(lexer); assert_eq!( - Err(Diagnostic::syntax_error( + &Diagnostic::syntax_error( "Unexpected token: expected StartKeyword but found SOME".into(), (0..4).into() - )), - parse_result + ), + parse_result.1.first().unwrap() ); } @@ -53,7 +53,7 @@ fn test_unclosed_body_error_message() { ", ); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, diff --git a/src/parser/tests/parse_errors/parse_error_statements_tests.rs b/src/parser/tests/parse_errors/parse_error_statements_tests.rs index d8ddb0d10eb..98c631d94cc 100644 --- a/src/parser/tests/parse_errors/parse_error_statements_tests.rs +++ b/src/parser/tests/parse_errors/parse_error_statements_tests.rs @@ -31,7 +31,7 @@ fn missing_semicolon_after_call() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); //expected end of statement (e.g. ;), but found KeywordEndProgram at line: 1 offset: 14..25" //Expecting a missing semicolon message let expected = Diagnostic::unexpected_token_found( @@ -67,7 +67,7 @@ fn missing_comma_in_call_parameters() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); let expected = Diagnostic::unexpected_token_found( "KeywordParensClose".into(), "'c'".into(), @@ -103,7 +103,7 @@ fn illegal_semicolon_in_call_parameters() { END_PROGRAM "); - let (compilation_unit, diagnostics) = parse(lexer).unwrap(); + let (compilation_unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, vec![ @@ -149,7 +149,7 @@ fn incomplete_statement_test() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let pou = &cu.implementations[0]; assert_eq!( format!("{:#?}", pou.statements), @@ -191,7 +191,7 @@ fn incomplete_statement_in_parantheses_recovery_test() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let pou = &cu.implementations[0]; assert_eq!( format!("{:#?}", pou.statements), @@ -239,7 +239,7 @@ fn mismatched_parantheses_recovery_test() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let pou = &cu.implementations[0]; assert_eq!( format!("{:#?}", pou.statements), @@ -276,7 +276,7 @@ fn invalid_variable_name_error_recovery() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let pou = &cu.units[0]; assert_eq!( format!("{:#?}", pou.variable_blocks[0]), @@ -317,7 +317,7 @@ fn invalid_variable_data_type_error_recovery() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); let pou = &cu.units[0]; assert_eq!( format!("{:#?}", pou.variable_blocks[0]), @@ -362,7 +362,7 @@ fn test_if_with_missing_semicolon_in_body() { END_IF END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -388,7 +388,7 @@ fn test_nested_if_with_missing_end_if() { y := x; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -452,7 +452,7 @@ fn test_for_with_missing_semicolon_in_body() { END_FOR END_PROGRAM "); - let (_, diagnostics) = parse(lexer).unwrap(); + let (_, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -478,7 +478,7 @@ fn test_nested_for_with_missing_end_for() { x := y; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -547,7 +547,7 @@ fn test_repeat_with_missing_semicolon_in_body() { y := x; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -601,7 +601,7 @@ fn test_nested_repeat_with_missing_until_end_repeat() { y := x; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -654,7 +654,7 @@ fn test_nested_repeat_with_missing_condition_and_end_repeat() { UNTIL END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -711,7 +711,7 @@ fn test_nested_repeat_with_missing_end_repeat() { UNTIL x = y END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -766,7 +766,7 @@ fn test_while_with_missing_semicolon_in_body() { y := x; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -820,7 +820,7 @@ fn test_nested_while_with_missing_end_while() { y := x; END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -874,7 +874,7 @@ fn test_while_with_missing_do() { END_WHILE END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -913,7 +913,7 @@ fn test_case_body_with_missing_semicolon() { END_CASE END_PROGRAM "); - let (unit, diagnostics) = parse(lexer).unwrap(); + let (unit, diagnostics) = parse(lexer); assert_eq!( diagnostics, @@ -957,7 +957,7 @@ fn test_case_without_condition() { END_PROGRAM "); - let (cu, diagnostics) = parse(lexer).unwrap(); + let (cu, diagnostics) = parse(lexer); assert_eq!( format!("{:#?}", cu.implementations[0].statements), diff --git a/src/parser/tests/program_parser_tests.rs b/src/parser/tests/program_parser_tests.rs index 3da7a168aee..5b40bc312e1 100644 --- a/src/parser/tests/program_parser_tests.rs +++ b/src/parser/tests/program_parser_tests.rs @@ -6,7 +6,7 @@ use crate::{ #[test] fn simple_foo_program_can_be_parsed() { let lexer = lex("PROGRAM foo END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; assert_eq!(prg.pou_type, PouType::Program); @@ -17,7 +17,7 @@ fn simple_foo_program_can_be_parsed() { #[test] fn simple_program_with_variable_can_be_parsed() { let lexer = lex("PROGRAM buz VAR x : INT; END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; @@ -39,7 +39,7 @@ fn simple_program_with_variable_can_be_parsed() { #[test] fn simple_program_with_var_input_can_be_parsed() { let lexer = lex("PROGRAM buz VAR_INPUT x : INT; END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; @@ -61,7 +61,7 @@ fn simple_program_with_var_input_can_be_parsed() { #[test] fn simple_program_with_var_output_can_be_parsed() { let lexer = lex("PROGRAM buz VAR_OUTPUT x : INT; END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; @@ -83,7 +83,7 @@ fn simple_program_with_var_output_can_be_parsed() { #[test] fn simple_program_with_var_inout_can_be_parsed() { let lexer = lex("PROGRAM buz VAR_IN_OUT x : INT; END_VAR END_PROGRAM"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.units[0]; let variable_block = &prg.variable_blocks[0]; diff --git a/src/parser/tests/statement_parser_tests.rs b/src/parser/tests/statement_parser_tests.rs index 37fb9fa3c4f..4c03b182f08 100644 --- a/src/parser/tests/statement_parser_tests.rs +++ b/src/parser/tests/statement_parser_tests.rs @@ -7,7 +7,7 @@ use pretty_assertions::*; #[test] fn empty_statements_are_are_parsed() { let lexer = lex("PROGRAM buz ;;;; END_PROGRAM "); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; assert_eq!( @@ -35,7 +35,7 @@ fn empty_statements_are_are_parsed() { #[test] fn empty_statements_are_parsed_before_a_statement() { let lexer = lex("PROGRAM buz ;;;;x; END_PROGRAM "); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; @@ -68,7 +68,7 @@ fn empty_statements_are_parsed_before_a_statement() { #[test] fn empty_statements_are_ignored_after_a_statement() { let lexer = lex("PROGRAM buz x;;;; END_PROGRAM "); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let prg = &result.implementations[0]; let statement = &prg.statements[0]; @@ -90,8 +90,7 @@ fn inline_struct_declaration_can_be_parsed() { Three:INT; END_STRUCT END_VAR - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.global_vars[0].variables[0]); let expected_ast = r#"Variable { @@ -132,8 +131,7 @@ fn inline_enum_declaration_can_be_parsed() { VAR_GLOBAL my_enum : (red, yellow, green); END_VAR - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.global_vars[0].variables[0]); @@ -163,8 +161,7 @@ fn multilevel_inline_struct_and_enum_declaration_can_be_parsed() { END_STRUCT END_STRUCT END_VAR - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.global_vars[0].variables[0]); let expected_ast = r#"Variable { @@ -220,7 +217,7 @@ fn string_variable_declaration_can_be_parsed() { wy : WSTRING[500]; END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = r#"Variable { name: "x", diff --git a/src/parser/tests/type_parser_tests.rs b/src/parser/tests/type_parser_tests.rs index c2972b3b94d..2c708210151 100644 --- a/src/parser/tests/type_parser_tests.rs +++ b/src/parser/tests/type_parser_tests.rs @@ -14,8 +14,7 @@ fn simple_struct_type_can_be_parsed() { Three:INT; END_STRUCT END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); @@ -62,8 +61,7 @@ fn simple_enum_type_can_be_parsed() { let (result, ..) = parse(lex(r#" TYPE SampleEnum : (red, yellow, green); END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); @@ -84,8 +82,7 @@ fn type_alias_can_be_parsed() { TYPE MyInt : INT; END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); let exptected_ast = format!( @@ -107,8 +104,7 @@ fn type_alias_can_be_parsed() { fn array_type_can_be_parsed_test() { let (result, ..) = parse(lex(r#" TYPE MyArray : ARRAY[0..8] OF INT; END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); @@ -143,8 +139,7 @@ fn string_type_can_be_parsed_test() { let (result, ..) = parse(lex(r#" TYPE MyString : STRING[253]; END_TYPE TYPE MyString : STRING[253] := 'abc'; END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types); @@ -187,8 +182,7 @@ fn string_type_can_be_parsed_test() { fn wide_string_type_can_be_parsed_test() { let (result, ..) = parse(lex(r#" TYPE MyString : WSTRING[253]; END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); @@ -217,7 +211,7 @@ fn subrangetype_can_be_parsed() { x : UINT(0..1000); END_VAR "); - let (parse_result, ..) = parse(lexer).unwrap(); + let (parse_result, ..) = parse(lexer); let x = &parse_result.global_vars[0].variables[0]; let expected = Variable { @@ -252,8 +246,7 @@ fn struct_with_inline_array_can_be_parsed() { One: ARRAY[0..1] OF INT; END_STRUCT END_TYPE - "#)) - .unwrap(); + "#)); let ast_string = format!("{:#?}", &result.types[0]); diff --git a/src/parser/tests/variable_parser_tests.rs b/src/parser/tests/variable_parser_tests.rs index 3b86360d663..58445727862 100644 --- a/src/parser/tests/variable_parser_tests.rs +++ b/src/parser/tests/variable_parser_tests.rs @@ -3,7 +3,7 @@ use crate::parser::{parse, tests::lex}; #[test] fn empty_global_vars_can_be_parsed() { let lexer = lex("VAR_GLOBAL END_VAR"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let vars = &result.global_vars[0]; //globar_vars let ast_string = format!("{:#?}", vars); @@ -17,7 +17,7 @@ fn empty_global_vars_can_be_parsed() { #[test] fn global_vars_can_be_parsed() { let lexer = lex("VAR_GLOBAL x : INT; y : BOOL; END_VAR"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let vars = &result.global_vars[0]; //globar_vars let ast_string = format!("{:#?}", vars); @@ -44,7 +44,7 @@ fn global_vars_can_be_parsed() { #[test] fn two_global_vars_can_be_parsed() { let lexer = lex("VAR_GLOBAL a: INT; END_VAR VAR_GLOBAL x : INT; y : BOOL; END_VAR"); - let result = parse(lexer).unwrap().0; + let result = parse(lexer).0; let vars = &result.global_vars; //global_vars let ast_string = format!("{:#?}", vars); From e31f54f43da916e9ce96acc0562a1bb40275ba7d Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Mon, 26 Jul 2021 13:26:27 +0200 Subject: [PATCH 5/9] Add expect_token! macro to avoid duplicated code --- src/lexer.rs | 27 ++++++++++--------- src/parser.rs | 34 +++++++---------------- src/parser/control_parser.rs | 52 ++++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 482b8fd4626..4a7966c9343 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -22,6 +22,20 @@ pub struct ParseSession<'a> { pub parse_progress: usize, } +#[macro_export] +macro_rules! expect_token { + ($lexer:expr, $token:expr, $return_value:expr) => { + if $lexer.token != $token { + $lexer.accept_diagnostic(Diagnostic::unexpected_token_found( + format!("{:?}", $token), + $lexer.slice().to_string(), + $lexer.location(), + )); + return $return_value; + } + }; +} + impl<'a> ParseSession<'a> { pub fn new(l: Lexer<'a, Token>) -> ParseSession<'a> { let mut lexer = ParseSession { @@ -37,19 +51,6 @@ impl<'a> ParseSession<'a> { lexer } - pub fn expect_token(&mut self, token: Token) -> bool { - if self.token != token { - self.accept_diagnostic(Diagnostic::unexpected_token_found( - format!("{:?}", token), - self.slice().to_string(), - self.location(), - )); - false - } else { - true - } - } - /// this function will be removed soon: pub fn expect(&self, token: Token) -> Result<(), Diagnostic> { if self.token != token { diff --git a/src/parser.rs b/src/parser.rs index 8f4dcc226b9..c056abbfeda 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder use crate::{ ast::*, - lexer, + expect_token, lexer, lexer::{ParseSession, Token, Token::*}, Diagnostic, }; @@ -85,9 +85,7 @@ fn parse_actions(lexer: &mut ParseSession, linkage: LinkageType) -> Vec Statement { while lexer.last_token == KeywordElseIf || lexer.last_token == KeywordIf { let condition = parse_primary_expression(lexer); - if !lexer.expect_token(KeywordThen) { - return Statement::EmptyStatement { + expect_token!( + lexer, + KeywordThen, + Statement::EmptyStatement { location: lexer.location(), - }; - } + } + ); lexer.advance(); let condition_block = ConditionalBlock { @@ -60,19 +65,23 @@ fn parse_for_statement(lexer: &mut ParseSession) -> Statement { lexer.advance(); // FOR let counter_expression = parse_reference(lexer); - if !lexer.expect_token(KeywordAssignment) { - return Statement::EmptyStatement { + expect_token!( + lexer, + KeywordAssignment, + Statement::EmptyStatement { location: lexer.location(), - }; - } + } + ); lexer.advance(); let start_expression = parse_primary_expression(lexer); - if !lexer.expect_token(KeywordTo) { - return Statement::EmptyStatement { + expect_token!( + lexer, + KeywordTo, + Statement::EmptyStatement { location: lexer.location(), - }; - } + } + ); lexer.advance(); let end_expression = parse_primary_expression(lexer); @@ -137,11 +146,14 @@ fn parse_case_statement(lexer: &mut ParseSession) -> Statement { let selector = Box::new(parse_primary_expression(lexer)); - if !lexer.expect_token(KeywordOf) { - return Statement::EmptyStatement { + expect_token!( + lexer, + KeywordOf, + Statement::EmptyStatement { location: lexer.location(), - }; - } // OF + } + ); + lexer.advance(); let mut case_blocks = Vec::new(); From c9b45c548cc8a3bc3f70113d147cc9fce208ab0e Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Mon, 26 Jul 2021 14:34:22 +0200 Subject: [PATCH 6/9] add tests for expect_token!() usages --- .../parse_errors/parse_error_messages_test.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/parser/tests/parse_errors/parse_error_messages_test.rs b/src/parser/tests/parse_errors/parse_error_messages_test.rs index c84a59dc397..7d7161363e9 100644 --- a/src/parser/tests/parse_errors/parse_error_messages_test.rs +++ b/src/parser/tests/parse_errors/parse_error_messages_test.rs @@ -44,6 +44,94 @@ fn test_unexpected_token_error_message2() { ); } +#[test] +fn for_with_unexpected_token_1() { + let lexer = super::super::lex( + " + PROGRAM exp + FOR z ALPHA x TO y DO + x; + y; + END_FOR + END_PROGRAM + ", + ); + let parse_result = parse(lexer); + assert_eq!( + &Diagnostic::syntax_error( + "Unexpected token: expected KeywordAssignment but found ALPHA".into(), + (36..41).into() + ), + parse_result.1.first().unwrap() + ); +} + +#[test] +fn for_with_unexpected_token_2() { + let lexer = super::super::lex( + " + PROGRAM exp + FOR z := x BRAVO y DO + x; + y; + END_FOR + END_PROGRAM + ", + ); + let parse_result = parse(lexer); + assert_eq!( + &Diagnostic::syntax_error( + "Unexpected token: expected KeywordTo but found BRAVO".into(), + (41..46).into() + ), + parse_result.1.first().unwrap() + ); +} + +#[test] +fn if_then_with_unexpected_token() { + let lexer = super::super::lex( + " + PROGRAM exp + IF TRUE CHARLIE + x; + ELSE + y; + END_IF + END_PROGRAM + ", + ); + let parse_result = parse(lexer); + assert_eq!( + &Diagnostic::syntax_error( + "Unexpected token: expected KeywordThen but found CHARLIE".into(), + (38..45).into() + ), + parse_result.1.first().unwrap() + ); +} + +#[test] +fn case_with_unexpected_token() { + let lexer = super::super::lex( + " + PROGRAM exp + CASE StateMachine DELTA + 1: x; + END_CASE + END_PROGRAM + ", + ); + let parse_result = parse(lexer); + assert_eq!( + &Diagnostic::syntax_error( + "Unexpected token: expected KeywordOf but found DELTA".into(), + (48..53).into() + ), + parse_result.1.first().unwrap() + ); +} + #[test] fn test_unclosed_body_error_message() { let lexer = super::super::lex( From 0075e0ead151a952e19da5a9c55f8a0035139a28 Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Mon, 2 Aug 2021 15:39:42 +0200 Subject: [PATCH 7/9] 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 c056abbfeda..c23723c7e04 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 ad141b79955..02488581e50 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 3eb71d89d70..55506f0e1c3 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(); From 79b1cbed1c4cc60aab8ae1877a176f21e5ca41ff Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Tue, 3 Aug 2021 09:56:29 +0200 Subject: [PATCH 8/9] Revert "reintroduce Results to the expression parser" This reverts commit 0075e0ead151a952e19da5a9c55f8a0035139a28. --- src/parser.rs | 14 +-- src/parser/control_parser.rs | 16 +-- src/parser/expressions_parser.rs | 168 +++++++++++++++++-------------- 3 files changed, 100 insertions(+), 98 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index c23723c7e04..c056abbfeda 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_expression(lexer); + let range_statement = parse_primary_expression(lexer); expect_token!(lexer, KeywordSquareParensClose, None); lexer.advance(); @@ -539,17 +539,7 @@ pub fn parse_any_in_region T>( } fn parse_expression(lexer: &mut ParseSession) -> Statement { - 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) - } - } - } + parse_primary_expression(lexer) } fn parse_reference(lexer: &mut ParseSession) -> Statement { diff --git a/src/parser/control_parser.rs b/src/parser/control_parser.rs index 02488581e50..ad141b79955 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_expression, parse_reference, parse_statement}; +use super::{parse_primary_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_expression(lexer); + let condition = parse_primary_expression(lexer); expect_token!( lexer, KeywordThen, @@ -74,7 +74,7 @@ fn parse_for_statement(lexer: &mut ParseSession) -> Statement { ); lexer.advance(); - let start_expression = parse_expression(lexer); + let start_expression = parse_primary_expression(lexer); expect_token!( lexer, KeywordTo, @@ -83,11 +83,11 @@ fn parse_for_statement(lexer: &mut ParseSession) -> Statement { } ); lexer.advance(); - let end_expression = parse_expression(lexer); + let end_expression = parse_primary_expression(lexer); let step = if lexer.token == KeywordBy { lexer.advance(); // BY - Some(Box::new(parse_expression(lexer))) + Some(Box::new(parse_primary_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_expression(lexer); + let condition = parse_primary_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_expression(lexer) + parse_primary_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_expression(lexer)); + let selector = Box::new(parse_primary_expression(lexer)); expect_token!( lexer, diff --git a/src/parser/expressions_parser.rs b/src/parser/expressions_parser.rs index 55506f0e1c3..3eb71d89d70 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) -> Result { +pub fn parse_primary_expression(lexer: &mut ParseSession) -> Statement { if lexer.token == KeywordSemicolon { - Ok(Statement::EmptyStatement { + Statement::EmptyStatement { location: lexer.location(), - }) + } } else { parse_expression_list(lexer) } } -pub fn parse_expression_list(lexer: &mut ParseSession) -> Result { +pub fn parse_expression_list(lexer: &mut ParseSession) -> Statement { 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 Ok(Statement::ExpressionList { expressions }); + return Statement::ExpressionList { expressions }; } left } -pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Result { +pub(crate) fn parse_range_statement(lexer: &mut ParseSession) -> Statement { let start = parse_or_expression(lexer); if lexer.token == KeywordDotDot { lexer.advance(); let end = parse_or_expression(lexer); - return Ok(Statement::RangeStatement { - start: Box::new(start?), - end: Box::new(end?), - }); + return Statement::RangeStatement { + start: Box::new(start), + end: Box::new(end), + }; } start } // OR -fn parse_or_expression(lexer: &mut ParseSession) -> Result { +fn parse_or_expression(lexer: &mut ParseSession) -> Statement { let left = parse_xor_expression(lexer); let operator = match lexer.token { @@ -60,15 +60,15 @@ fn parse_or_expression(lexer: &mut ParseSession) -> Result Result { +fn parse_xor_expression(lexer: &mut ParseSession) -> Statement { let left = parse_and_expression(lexer); let operator = match lexer.token { @@ -79,15 +79,15 @@ fn parse_xor_expression(lexer: &mut ParseSession) -> Result Result { +fn parse_and_expression(lexer: &mut ParseSession) -> Statement { let left = parse_equality_expression(lexer); let operator = match lexer.token { @@ -98,15 +98,15 @@ fn parse_and_expression(lexer: &mut ParseSession) -> Result -fn parse_equality_expression(lexer: &mut ParseSession) -> Result { +fn parse_equality_expression(lexer: &mut ParseSession) -> Statement { 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) -> Result, <=, >= -fn parse_compare_expression(lexer: &mut ParseSession) -> Result { +fn parse_compare_expression(lexer: &mut ParseSession) -> Statement { 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) -> Result Result { +fn parse_additive_expression(lexer: &mut ParseSession) -> Statement { 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) -> Result Result { +fn parse_multiplication_expression(lexer: &mut ParseSession) -> Statement { 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) -> Result Result { +fn parse_unary_expression(lexer: &mut ParseSession) -> Statement { let operator = match lexer.token { OperatorNot => Some(Operator::Not), OperatorMinus => Some(Operator::Minus), @@ -187,21 +187,21 @@ fn parse_unary_expression(lexer: &mut ParseSession) -> Result Result { +fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { match lexer.token { KeywordParensOpen => { lexer.advance(); @@ -214,8 +214,8 @@ fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Result Result { - let statement = match lexer.token { +fn parse_leaf_expression(lexer: &mut ParseSession) -> Statement { + let literal_parse_result = match lexer.token { Identifier => parse_qualified_reference(lexer), LiteralInteger => parse_literal_number(lexer), LiteralDate => parse_literal_date(lexer), @@ -232,30 +232,41 @@ fn parse_leaf_expression(lexer: &mut ParseSession) -> Result { + 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 + } } - } else if lexer.token == KeywordOutputAssignment { - lexer.advance(); - Statement::OutputAssignment { - 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 { - 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(); @@ -290,21 +301,22 @@ 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(); From de7fcf9791c4f317f045bba736d2bda63ccff3fb Mon Sep 17 00:00:00 2001 From: Alexander Ulmer Date: Tue, 3 Aug 2021 10:10:57 +0200 Subject: [PATCH 9/9] finalize expression_parser, remove misleading fn parse_primary_expression() --- src/parser.rs | 8 ++---- src/parser/control_parser.rs | 16 +++++------ src/parser/expressions_parser.rs | 49 ++++++++++++++++---------------- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index c056abbfeda..794dabb0090 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -6,7 +6,7 @@ use crate::{ Diagnostic, }; -use self::{control_parser::parse_control_statement, expressions_parser::parse_primary_expression}; +use self::{control_parser::parse_control_statement, expressions_parser::parse_expression}; mod control_parser; mod expressions_parser; @@ -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(); @@ -538,10 +538,6 @@ pub fn parse_any_in_region T>( result } -fn parse_expression(lexer: &mut ParseSession) -> Statement { - parse_primary_expression(lexer) -} - fn parse_reference(lexer: &mut ParseSession) -> Statement { match expressions_parser::parse_qualified_reference(lexer) { Ok(statement) => statement, diff --git a/src/parser/control_parser.rs b/src/parser/control_parser.rs index ad141b79955..02488581e50 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 3eb71d89d70..adb8177bc89 100644 --- a/src/parser/expressions_parser.rs +++ b/src/parser/expressions_parser.rs @@ -1,16 +1,15 @@ // Copyright (c) 2020 Ghaith Hachem and Mathias Rieder -use crate::ast::*; -use crate::lexer::Token::*; -use crate::parser::parse_any_in_region; -use crate::Diagnostic; +use crate::{ + ast::*, lexer::ParseSession, lexer::Token::*, parser::parse_any_in_region, Diagnostic, +}; use std::str::FromStr; -use super::ParseSession; - -type ParseError = Diagnostic; - -pub fn parse_primary_expression(lexer: &mut ParseSession) -> Statement { +/// parse_expression(): returns expression as Statement. if a parse error +/// is encountered, the erroneous part of the AST will consist of an +/// EmptyStatement and a diagnostic will be logged. That case is different from +/// only an EmptyStatement returned, which does not denote an error condition. +pub fn parse_expression(lexer: &mut ParseSession) -> Statement { if lexer.token == KeywordSemicolon { Statement::EmptyStatement { location: lexer.location(), @@ -206,7 +205,7 @@ fn parse_parenthesized_expression(lexer: &mut ParseSession) -> Statement { KeywordParensOpen => { lexer.advance(); super::parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| { - parse_primary_expression(lexer) + parse_expression(lexer) }) } _ => parse_leaf_expression(lexer), @@ -262,11 +261,11 @@ fn parse_leaf_expression(lexer: &mut ParseSession) -> Statement { } } -fn parse_array_literal(lexer: &mut ParseSession) -> Result { +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_expression(lexer))); let end = lexer.range().end; lexer.expect(KeywordSquareParensClose)?; lexer.advance(); @@ -278,13 +277,13 @@ fn parse_array_literal(lexer: &mut ParseSession) -> Result Result { +fn parse_bool_literal(lexer: &mut ParseSession, value: bool) -> Result { let location = lexer.location(); lexer.advance(); Ok(Statement::LiteralBool { value, location }) } -pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result { +pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result { let start = lexer.range().start; let mut reference_elements = vec![parse_reference_access(lexer)?]; while lexer.allow(&KeywordDot) { @@ -322,7 +321,7 @@ pub fn parse_qualified_reference(lexer: &mut ParseSession) -> Result Result { +pub fn parse_reference_access(lexer: &mut ParseSession) -> Result { let location = lexer.location(); let mut reference = Statement::Reference { name: lexer.slice_and_advance(), @@ -330,7 +329,7 @@ pub fn parse_reference_access(lexer: &mut ParseSession) -> Result Result Result { +fn parse_literal_number(lexer: &mut ParseSession) -> Result { let location = lexer.location(); let result = lexer.slice_and_advance(); if lexer.allow(&KeywordDot) { @@ -350,7 +349,7 @@ fn parse_literal_number(lexer: &mut ParseSession) -> Result() .map_err(|e| Diagnostic::syntax_error(format!("{}", e), location.clone()))?; - let element = parse_primary_expression(lexer); + let element = parse_expression(lexer); lexer.expect(KeywordParensClose)?; let end = lexer.range().end; lexer.advance(); @@ -373,7 +372,7 @@ fn parse_number(text: &str, location: &SourceRange) -> Result Result { +fn parse_date_from_string(text: &str, location: SourceRange) -> Result { let mut segments = text.split('-'); //we can safely expect 3 numbers @@ -398,7 +397,7 @@ fn parse_date_from_string(text: &str, location: SourceRange) -> Result Result { +fn parse_literal_date_and_time(lexer: &mut ParseSession) -> Result { let location = lexer.location(); //get rid of D# or DATE# let slice = lexer.slice_and_advance(); @@ -435,7 +434,7 @@ fn parse_literal_date_and_time(lexer: &mut ParseSession) -> Result Result { +fn parse_literal_date(lexer: &mut ParseSession) -> Result { let location = lexer.location(); //get rid of D# or DATE# let slice = lexer.slice_and_advance(); @@ -445,7 +444,7 @@ fn parse_literal_date(lexer: &mut ParseSession) -> Result parse_date_from_string(slice, location) } -fn parse_literal_time_of_day(lexer: &mut ParseSession) -> Result { +fn parse_literal_time_of_day(lexer: &mut ParseSession) -> Result { let location = lexer.location(); //get rid of TOD# or TIME_OF_DAY# let slice = lexer.slice_and_advance(); @@ -467,7 +466,7 @@ fn parse_literal_time_of_day(lexer: &mut ParseSession) -> Result Result { +fn parse_literal_time(lexer: &mut ParseSession) -> Result { const POS_D: usize = 0; const POS_H: usize = 1; const POS_M: usize = 2; @@ -573,7 +572,7 @@ fn trim_quotes(quoted_string: &str) -> String { quoted_string[1..quoted_string.len() - 1].to_string() } -fn parse_literal_string(lexer: &mut ParseSession, is_wide: bool) -> Result { +fn parse_literal_string(lexer: &mut ParseSession, is_wide: bool) -> Result { let result = lexer.slice(); let location = lexer.location(); let string_literal = Ok(Statement::LiteralString { @@ -589,7 +588,7 @@ fn parse_literal_real( lexer: &mut ParseSession, integer: String, integer_range: SourceRange, -) -> Result { +) -> Result { lexer.expect(LiteralInteger)?; let start = integer_range.get_start(); let fraction_end = lexer.range().end;