From 3e0d9488b01237dc3d6ed6f25bfb06dd17d452d7 Mon Sep 17 00:00:00 2001 From: Bipul Lamsal Date: Wed, 8 Oct 2025 22:21:28 +0545 Subject: [PATCH 1/3] fix: enum parse error --- src/parser.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 4df9893b3aa..7aa26e28f76 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -33,7 +33,7 @@ use crate::{ use self::{ control_parser::parse_control_statement, - expressions_parser::{parse_expression, parse_expression_list}, + expressions_parser::{parse_expression, parse_strict_literal_integer}, }; mod control_parser; @@ -1159,22 +1159,73 @@ fn parse_enum_type_definition( name: Option, ) -> Option<(DataTypeDeclaration, Option)> { let start = lexer.last_location(); - let elements = parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| { - // Parse Enum - we expect at least one element - let elements = parse_expression_list(lexer); - Some(elements) - })?; - let initializer = lexer.try_consume(KeywordAssignment).then(|| parse_expression(lexer)); + + let elements = parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| parse_enum_elements(lexer))?; + Some(( DataTypeDeclaration::Definition { data_type: Box::new(DataType::EnumType { name, elements, numeric_type: DINT_TYPE.to_string() }), location: start.span(&lexer.last_location()), scope: lexer.scope.clone(), }, - initializer, + None, )) } +/// Parse comma-separated enum elements (identifier or identifier := literal) +fn parse_enum_elements(lexer: &mut ParseSession) -> Option { + let start = lexer.location(); + let mut elements = vec![]; + + loop { + let element = parse_enum_element(lexer)?; + elements.push(element); + + // check for comma + if !lexer.try_consume(KeywordComma) { + break; + } + + // check for trailing comma + if lexer.closes_open_region(&lexer.token) { + break; + } + } + + if elements.len() == 1 { + return Some(elements.into_iter().next().unwrap()); + } + + Some(AstFactory::create_expression_list(elements, start.span(&lexer.last_location()), lexer.next_id())) +} + +/// Parse a single enum element: identifier or identifier := literal +fn parse_enum_element(lexer: &mut ParseSession) -> Option { + let start = lexer.location(); + + if lexer.token != Identifier { + lexer.accept_diagnostic(Diagnostic::unexpected_token_found( + "Identifier", + lexer.slice(), + lexer.location(), + )); + lexer.advance(); + return Some(AstFactory::create_empty_statement(start, lexer.next_id())); + } + + let id_str = parse_identifier(lexer).unwrap().0; + + let identifier_node = AstFactory::create_identifier(&id_str, start, lexer.next_id()); + + if lexer.try_consume(KeywordAssignment) { + let value = parse_strict_literal_integer(lexer)?; + let result = AstFactory::create_assignment(identifier_node, value, lexer.next_id()); + return Some(result); + } + + Some(identifier_node) +} + fn parse_array_type_definition( lexer: &mut ParseSession, name: Option, From 70040c960fb95f2e061f1f44be14f6a29c61a1ee Mon Sep 17 00:00:00 2001 From: Bipul Lamsal Date: Wed, 8 Oct 2025 22:41:59 +0545 Subject: [PATCH 2/3] chore: prev initalizer restored --- src/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index 7aa26e28f76..74a29e2c56d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1161,6 +1161,7 @@ fn parse_enum_type_definition( let start = lexer.last_location(); let elements = parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| parse_enum_elements(lexer))?; + let initializer = lexer.try_consume(KeywordAssignment).then(|| parse_expression(lexer)); Some(( DataTypeDeclaration::Definition { @@ -1168,7 +1169,7 @@ fn parse_enum_type_definition( location: start.span(&lexer.last_location()), scope: lexer.scope.clone(), }, - None, + initializer, )) } From 2281f1cde2e4118c2fceee82c2fd247914c198f3 Mon Sep 17 00:00:00 2001 From: Bipul Lamsal Date: Fri, 10 Oct 2025 12:46:48 +0545 Subject: [PATCH 3/3] fix: ast node expression conversion --- src/parser.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 74a29e2c56d..7131e2e4bce 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -33,7 +33,7 @@ use crate::{ use self::{ control_parser::parse_control_statement, - expressions_parser::{parse_expression, parse_strict_literal_integer}, + expressions_parser::{parse_expression, parse_range_statement}, }; mod control_parser; @@ -1160,7 +1160,7 @@ fn parse_enum_type_definition( ) -> Option<(DataTypeDeclaration, Option)> { let start = lexer.last_location(); - let elements = parse_any_in_region(lexer, vec![KeywordParensClose], |lexer| parse_enum_elements(lexer))?; + let elements = parse_any_in_region(lexer, vec![KeywordParensClose], parse_enum_elements(lexer))?; let initializer = lexer.try_consume(KeywordAssignment).then(|| parse_expression(lexer)); Some(( @@ -1204,27 +1204,19 @@ fn parse_enum_elements(lexer: &mut ParseSession) -> Option { fn parse_enum_element(lexer: &mut ParseSession) -> Option { let start = lexer.location(); - if lexer.token != Identifier { - lexer.accept_diagnostic(Diagnostic::unexpected_token_found( - "Identifier", - lexer.slice(), - lexer.location(), - )); - lexer.advance(); - return Some(AstFactory::create_empty_statement(start, lexer.next_id())); - } + let idfr = parse_identifier(lexer)?; - let id_str = parse_identifier(lexer).unwrap().0; - - let identifier_node = AstFactory::create_identifier(&id_str, start, lexer.next_id()); + let identifier_node = AstFactory::create_identifier(&idfr.0, start, lexer.next_id()); if lexer.try_consume(KeywordAssignment) { - let value = parse_strict_literal_integer(lexer)?; + let value = parse_range_statement(lexer); let result = AstFactory::create_assignment(identifier_node, value, lexer.next_id()); return Some(result); } - Some(identifier_node) + let ref_expr = AstFactory::create_member_reference(identifier_node, None, lexer.next_id()); + + Some(ref_expr) } fn parse_array_type_definition(