From f70404a0791e46ffa022bfb0b0cd2eda0fd0d4c4 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 31 May 2024 10:39:25 +0200 Subject: [PATCH 1/4] perf: avoid using alt when parsing Program Signed-off-by: ljedrz --- console/network/environment/src/lib.rs | 2 ++ .../src/data_types/record_type/parse.rs | 2 -- .../src/data_types/struct_type/parse.rs | 2 -- synthesizer/program/src/closure/parse.rs | 2 -- synthesizer/program/src/function/parse.rs | 2 -- synthesizer/program/src/lib.rs | 4 ++- synthesizer/program/src/mapping/parse.rs | 2 -- synthesizer/program/src/parse.rs | 29 ++++++++++++++----- 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/console/network/environment/src/lib.rs b/console/network/environment/src/lib.rs index 454a33b44f..fdd6b9c8ce 100644 --- a/console/network/environment/src/lib.rs +++ b/console/network/environment/src/lib.rs @@ -126,8 +126,10 @@ pub mod prelude { bytes::{complete::tag, streaming::take}, character::complete::{alpha1, alphanumeric1, char, one_of}, combinator::{complete, fail, map, map_res, opt, recognize}, + error::{make_error, ErrorKind}, multi::{count, many0, many0_count, many1, separated_list0, separated_list1}, sequence::{pair, terminated}, + Err, }; pub use num_traits::{AsPrimitive, One, Pow, Zero}; pub use rand::{ diff --git a/console/program/src/data_types/record_type/parse.rs b/console/program/src/data_types/record_type/parse.rs index d995622e7c..386b6ac0e3 100644 --- a/console/program/src/data_types/record_type/parse.rs +++ b/console/program/src/data_types/record_type/parse.rs @@ -45,8 +45,6 @@ impl Parser for RecordType { Ok((string, (identifier, value_type))) } - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/console/program/src/data_types/struct_type/parse.rs b/console/program/src/data_types/struct_type/parse.rs index 42ad3b7ca0..a047d5ec2a 100644 --- a/console/program/src/data_types/struct_type/parse.rs +++ b/console/program/src/data_types/struct_type/parse.rs @@ -45,8 +45,6 @@ impl Parser for StructType { Ok((string, (identifier, plaintext_type))) } - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/closure/parse.rs b/synthesizer/program/src/closure/parse.rs index 9560dfc924..66dd889739 100644 --- a/synthesizer/program/src/closure/parse.rs +++ b/synthesizer/program/src/closure/parse.rs @@ -18,8 +18,6 @@ impl> Parser for ClosureCore ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'closure' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/function/parse.rs b/synthesizer/program/src/function/parse.rs index 48258a3e0b..e6a912e4b4 100644 --- a/synthesizer/program/src/function/parse.rs +++ b/synthesizer/program/src/function/parse.rs @@ -20,8 +20,6 @@ impl, Command: CommandTrait> Par /// Parses a string into a function. #[inline] fn parse(string: &str) -> ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'function' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/lib.rs b/synthesizer/program/src/lib.rs index 6058ffa3ca..4dc7b39569 100644 --- a/synthesizer/program/src/lib.rs +++ b/synthesizer/program/src/lib.rs @@ -48,13 +48,13 @@ mod serialize; use console::{ network::prelude::{ - alt, anyhow, bail, de, ensure, error, fmt, + make_error, many0, many1, map, @@ -65,7 +65,9 @@ use console::{ Deserialize, Deserializer, Display, + Err, Error, + ErrorKind, Formatter, FromBytes, FromBytesDeserializer, diff --git a/synthesizer/program/src/mapping/parse.rs b/synthesizer/program/src/mapping/parse.rs index 4f25ed546c..dc546d8e9f 100644 --- a/synthesizer/program/src/mapping/parse.rs +++ b/synthesizer/program/src/mapping/parse.rs @@ -18,8 +18,6 @@ impl Parser for Mapping { /// Parses a string into a mapping. #[inline] fn parse(string: &str) -> ParserResult { - // Parse the whitespace and comments from the string. - let (string, _) = Sanitizer::parse(string)?; // Parse the 'mapping' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/parse.rs b/synthesizer/program/src/parse.rs index 40929f4341..f371b16993 100644 --- a/synthesizer/program/src/parse.rs +++ b/synthesizer/program/src/parse.rs @@ -44,14 +44,29 @@ impl, Command: CommandTrait> Par // Parse the semicolon ';' keyword from the string. let (string, _) = tag(";")(string)?; + fn intermediate, Command: CommandTrait>( + string: &str, + ) -> ParserResult> { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; + + if string.starts_with(Mapping::::type_name()) { + map(Mapping::parse, |mapping| P::::M(mapping))(string) + } else if string.starts_with(StructType::::type_name()) { + map(StructType::parse, |struct_| P::::I(struct_))(string) + } else if string.starts_with(RecordType::::type_name()) { + map(RecordType::parse, |record| P::::R(record))(string) + } else if string.starts_with(ClosureCore::::type_name()) { + map(ClosureCore::parse, |closure| P::::C(closure))(string) + } else if string.starts_with(FunctionCore::::type_name()) { + map(FunctionCore::parse, |function| P::::F(function))(string) + } else { + Err(Err::Error(make_error(string, ErrorKind::Alt))) + } + } + // Parse the struct or function from the string. - let (string, components) = many1(alt(( - map(Mapping::parse, |mapping| P::::M(mapping)), - map(StructType::parse, |struct_| P::::I(struct_)), - map(RecordType::parse, |record| P::::R(record)), - map(ClosureCore::parse, |closure| P::::C(closure)), - map(FunctionCore::parse, |function| P::::F(function)), - )))(string)?; + let (string, components) = many1(intermediate)(string)?; // Parse the whitespace and comments from the string. let (string, _) = Sanitizer::parse(string)?; From 39c48dd1cf13a0c0c791f7f9cea305ba3363a26d Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 31 May 2024 13:26:32 +0200 Subject: [PATCH 2/4] perf: don't clone Program components when parsing Signed-off-by: ljedrz --- synthesizer/program/src/parse.rs | 67 +++++++++++++++----------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/synthesizer/program/src/parse.rs b/synthesizer/program/src/parse.rs index f371b16993..f2da6a0035 100644 --- a/synthesizer/program/src/parse.rs +++ b/synthesizer/program/src/parse.rs @@ -70,47 +70,44 @@ impl, Command: CommandTrait> Par // Parse the whitespace and comments from the string. let (string, _) = Sanitizer::parse(string)?; - // Return the program. - map_res(take(0usize), move |_| { - // Initialize a new program. - let mut program = match ProgramCore::::new(id) { - Ok(program) => program, + // Initialize a new program. + let mut program = match ProgramCore::::new(id) { + Ok(program) => program, + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), move |error| Err(error))(string); + } + }; + // Construct the program with the parsed components. + for component in components { + let result = match component { + P::M(mapping) => program.add_mapping(mapping), + P::I(struct_) => program.add_struct(struct_), + P::R(record) => program.add_record(record), + P::C(closure) => program.add_closure(closure), + P::F(function) => program.add_function(function), + }; + + match result { + Ok(_) => (), Err(error) => { eprintln!("{error}"); - return Err(error); - } - }; - // Construct the program with the parsed components. - for component in components.iter() { - let result = match component { - P::M(mapping) => program.add_mapping(mapping.clone()), - P::I(struct_) => program.add_struct(struct_.clone()), - P::R(record) => program.add_record(record.clone()), - P::C(closure) => program.add_closure(closure.clone()), - P::F(function) => program.add_function(function.clone()), - }; - - match result { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + return map_res(take(0usize), move |error| Err(error))(string); } } - // Lastly, add the imports (if any) to the program. - for import in imports.iter() { - match program.add_import(import.clone()) { - Ok(_) => (), - Err(error) => { - eprintln!("{error}"); - return Err(error); - } + } + // Lastly, add the imports (if any) to the program. + for import in imports { + match program.add_import(import) { + Ok(_) => (), + Err(error) => { + eprintln!("{error}"); + return map_res(take(0usize), move |error| Err(error))(string); } } - // Output the program. - Ok::<_, Error>(program) - })(string) + } + + Ok((string, program)) } } From 132a0c14d4af4d90aa4065ec84a705d1ce81f625 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 10 Jul 2024 10:36:34 +0200 Subject: [PATCH 3/4] clippy: small fix Signed-off-by: ljedrz --- synthesizer/program/src/parse.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/synthesizer/program/src/parse.rs b/synthesizer/program/src/parse.rs index f2da6a0035..f42f8764ef 100644 --- a/synthesizer/program/src/parse.rs +++ b/synthesizer/program/src/parse.rs @@ -75,7 +75,7 @@ impl, Command: CommandTrait> Par Ok(program) => program, Err(error) => { eprintln!("{error}"); - return map_res(take(0usize), move |error| Err(error))(string); + return map_res(take(0usize), Err)(string); } }; // Construct the program with the parsed components. @@ -92,7 +92,7 @@ impl, Command: CommandTrait> Par Ok(_) => (), Err(error) => { eprintln!("{error}"); - return map_res(take(0usize), move |error| Err(error))(string); + return map_res(take(0usize), Err)(string); } } } @@ -102,7 +102,7 @@ impl, Command: CommandTrait> Par Ok(_) => (), Err(error) => { eprintln!("{error}"); - return map_res(take(0usize), move |error| Err(error))(string); + return map_res(take(0usize), Err)(string); } } } From 66de071f2158b0fdbcbfc1077ac935c76efa9277 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 10 Jul 2024 11:29:10 +0200 Subject: [PATCH 4/4] fix: correct parsing code Signed-off-by: ljedrz --- console/program/src/data_types/record_type/parse.rs | 2 ++ console/program/src/data_types/struct_type/parse.rs | 2 ++ synthesizer/program/src/closure/parse.rs | 2 ++ synthesizer/program/src/function/parse.rs | 2 ++ synthesizer/program/src/mapping/parse.rs | 2 ++ 5 files changed, 10 insertions(+) diff --git a/console/program/src/data_types/record_type/parse.rs b/console/program/src/data_types/record_type/parse.rs index 386b6ac0e3..d995622e7c 100644 --- a/console/program/src/data_types/record_type/parse.rs +++ b/console/program/src/data_types/record_type/parse.rs @@ -45,6 +45,8 @@ impl Parser for RecordType { Ok((string, (identifier, value_type))) } + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/console/program/src/data_types/struct_type/parse.rs b/console/program/src/data_types/struct_type/parse.rs index a047d5ec2a..42ad3b7ca0 100644 --- a/console/program/src/data_types/struct_type/parse.rs +++ b/console/program/src/data_types/struct_type/parse.rs @@ -45,6 +45,8 @@ impl Parser for StructType { Ok((string, (identifier, plaintext_type))) } + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; // Parse the type name from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/closure/parse.rs b/synthesizer/program/src/closure/parse.rs index 66dd889739..9560dfc924 100644 --- a/synthesizer/program/src/closure/parse.rs +++ b/synthesizer/program/src/closure/parse.rs @@ -18,6 +18,8 @@ impl> Parser for ClosureCore ParserResult { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; // Parse the 'closure' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/function/parse.rs b/synthesizer/program/src/function/parse.rs index e6a912e4b4..48258a3e0b 100644 --- a/synthesizer/program/src/function/parse.rs +++ b/synthesizer/program/src/function/parse.rs @@ -20,6 +20,8 @@ impl, Command: CommandTrait> Par /// Parses a string into a function. #[inline] fn parse(string: &str) -> ParserResult { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; // Parse the 'function' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string. diff --git a/synthesizer/program/src/mapping/parse.rs b/synthesizer/program/src/mapping/parse.rs index dc546d8e9f..4f25ed546c 100644 --- a/synthesizer/program/src/mapping/parse.rs +++ b/synthesizer/program/src/mapping/parse.rs @@ -18,6 +18,8 @@ impl Parser for Mapping { /// Parses a string into a mapping. #[inline] fn parse(string: &str) -> ParserResult { + // Parse the whitespace and comments from the string. + let (string, _) = Sanitizer::parse(string)?; // Parse the 'mapping' keyword from the string. let (string, _) = tag(Self::type_name())(string)?; // Parse the whitespace from the string.