From 4197eee870acbf6e6705680914b4186f55776a16 Mon Sep 17 00:00:00 2001 From: Zak Henry Date: Wed, 19 Feb 2025 10:16:27 +1300 Subject: [PATCH 1/3] fix(exchange): handle escape string sequence --- ruststep/src/parser/token.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ruststep/src/parser/token.rs b/ruststep/src/parser/token.rs index 005af3ecb..d990a85ba 100644 --- a/ruststep/src/parser/token.rs +++ b/ruststep/src/parser/token.rs @@ -12,6 +12,8 @@ use nom::{ sequence::tuple, Parser, }; +use nom::bytes::complete::tag; +use nom::combinator::map; /// sign = `+` | `-` . pub fn sign(input: &str) -> ParseResult { @@ -68,7 +70,12 @@ pub fn real(input: &str) -> ParseResult { /// string = `'` { [special] | [digit] | [space] | [lower] | [upper] | high_codepoint | [apostrophe] [apostrophe] | [reverse_solidus] [reverse_solidus] | control_directive } `'` . pub fn string(input: &str) -> ParseResult { - tuple((char('\''), many0(none_of("'")), char('\''))) + let escaped_char = map(tag("''"), |_| '\''); // Parse '' as a single ' + let normal_char = none_of("'"); // Parse any character except ' + + let string_content = many0(escaped_char.or(normal_char.map(|c| c))); + + tuple((char('\''), string_content, char('\''))) .map(|(_start, s, _end)| s.iter().collect()) .parse(input) } @@ -259,6 +266,14 @@ mod tests { assert_eq!(s, "vim"); } + + #[test] + fn escaped_string() { + let (res, s) = super::string("'vim''s'").finish().unwrap(); + assert_eq!(res, ""); + assert_eq!(s, "vim's"); + } + #[test] fn instance_name() { let (res, s) = super::entity_instance_name("#18446744073709551615" /* u64::MAX */) From 90fdc9351746f1f1d1e435b88f15371edaaaa14d Mon Sep 17 00:00:00 2001 From: Zak Henry Date: Wed, 19 Feb 2025 10:21:34 +1300 Subject: [PATCH 2/3] fix(exchange): handle empty parameter lists --- ruststep/src/parser/exchange/parameter.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ruststep/src/parser/exchange/parameter.rs b/ruststep/src/parser/exchange/parameter.rs index d374ffd3d..9c130add3 100644 --- a/ruststep/src/parser/exchange/parameter.rs +++ b/ruststep/src/parser/exchange/parameter.rs @@ -6,8 +6,8 @@ use nom::{branch::alt, combinator::value, Parser}; /// list = `(` \[ [parameter] { `,` [parameter] } \] `)` . pub fn list(input: &str) -> ParseResult { - tuple_((char_('('), comma_separated(parameter), char_(')'))) - .map(|(_open, params, _close)| Parameter::List(params)) + tuple_((char_('('), opt_(comma_separated(parameter)), char_(')'))) + .map(|(_open, params, _close)| Parameter::List(params.unwrap_or_default())) .parse(input) } @@ -66,4 +66,22 @@ mod tests { assert_eq!(res, ""); assert_eq!(record, Parameter::real(2.0)); } + + #[test] + fn parameter_list() { + let (res, record) = super::untyped_parameter("(1, 2, 3)").finish().unwrap(); + assert_eq!(res, ""); + assert_eq!(record, Parameter::List(vec![ + Parameter::Integer(1), + Parameter::Integer(2), + Parameter::Integer(3), + ])); + } + + #[test] + fn empty_parameter_list() { + let (res, record) = super::untyped_parameter("()").finish().unwrap(); + assert_eq!(res, ""); + assert_eq!(record, Parameter::List(vec![])); + } } From 43931fbaaed2e2aa51639ddafc27ef4ffda65c09 Mon Sep 17 00:00:00 2001 From: Tanimura Yoshinori Date: Thu, 20 Mar 2025 01:19:38 +0900 Subject: [PATCH 3/3] cargo fmt, updates CHANGELOG --- CHANGELOG.md | 6 ++++++ ruststep/src/parser/exchange/parameter.rs | 13 ++++++++----- ruststep/src/parser/token.rs | 5 ++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a3f6b4a..c65096d13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ In addition to original Keep-a-Changelog, we use following rules: - This will be checked by GitHub Actions - Each Pull Request MAY correspond to one or more lines in this file +## Unreleased + +### Fixed + +- Fixes to support parsing of ISO13399 database plib. https://github.com/ricosjp/ruststep/pull/251 + ## 0.4.0 - 2024-09-20 ### Added diff --git a/ruststep/src/parser/exchange/parameter.rs b/ruststep/src/parser/exchange/parameter.rs index 9c130add3..04d57f6be 100644 --- a/ruststep/src/parser/exchange/parameter.rs +++ b/ruststep/src/parser/exchange/parameter.rs @@ -71,11 +71,14 @@ mod tests { fn parameter_list() { let (res, record) = super::untyped_parameter("(1, 2, 3)").finish().unwrap(); assert_eq!(res, ""); - assert_eq!(record, Parameter::List(vec![ - Parameter::Integer(1), - Parameter::Integer(2), - Parameter::Integer(3), - ])); + assert_eq!( + record, + Parameter::List(vec![ + Parameter::Integer(1), + Parameter::Integer(2), + Parameter::Integer(3), + ]) + ); } #[test] diff --git a/ruststep/src/parser/token.rs b/ruststep/src/parser/token.rs index d990a85ba..f886e3aeb 100644 --- a/ruststep/src/parser/token.rs +++ b/ruststep/src/parser/token.rs @@ -4,6 +4,8 @@ use crate::{ ast::*, parser::{basic::*, combinator::*}, }; +use nom::bytes::complete::tag; +use nom::combinator::map; use nom::{ branch::alt, character::complete::{char, digit0, digit1, multispace0, none_of, satisfy}, @@ -12,8 +14,6 @@ use nom::{ sequence::tuple, Parser, }; -use nom::bytes::complete::tag; -use nom::combinator::map; /// sign = `+` | `-` . pub fn sign(input: &str) -> ParseResult { @@ -266,7 +266,6 @@ mod tests { assert_eq!(s, "vim"); } - #[test] fn escaped_string() { let (res, s) = super::string("'vim''s'").finish().unwrap();