From 2a846a5f53f3aa25a7e988e05b3feb6086f13ea9 Mon Sep 17 00:00:00 2001 From: yannickreiss Date: Tue, 26 Aug 2025 22:43:59 +0200 Subject: [PATCH] Load configuration for in language syntax replacements --- src/main.rs | 28 +----------------- src/syntax.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++ src/testcases.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 27 deletions(-) create mode 100644 src/syntax.rs diff --git a/src/main.rs b/src/main.rs index 9e3d314..7b4bb84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -mod identification; mod preprocessor; +mod syntax; mod testcases; mod tokenizer; @@ -49,30 +49,4 @@ fn main() { // Syntax resolving // Apply translation - - /* let sample_code: String = std::fs::read_to_string("example.mlc").unwrap(); - let mut example_tokenizer: Tokenizer = Tokenizer::new(); - let mut meta_rules: crate::preprocessor::MetaRules = - crate::preprocessor::MetaRules::new("./language.toml"); - let processed_sample_code: String = meta_rules.process(sample_code.to_owned()); - - // tokenizing - example_tokenizer.read_configuration_from_file("./language.toml"); - example_tokenizer.eat(processed_sample_code.as_str()); - example_tokenizer.identify_tokens(); - // Insert meta tokens into token list - let mut token_index: usize = 0; - for meta_token in meta_rules.special_tokens.iter() { - println!("Token: {:?}", meta_token.0); - } - - // Semantic analysis - let mut example_identifier: identification::Identifier = - identification::Identifier::new(example_tokenizer.tokens); - example_identifier.load_criteria_from_configuration(example_tokenizer.configuration); - example_identifier.identify_identifiers(); - - for token in example_identifier.tokens.iter() { - print!("{}", token.token); - } */ } diff --git a/src/syntax.rs b/src/syntax.rs new file mode 100644 index 0000000..12221b4 --- /dev/null +++ b/src/syntax.rs @@ -0,0 +1,76 @@ +use toml::{Table, Value}; + +// SyntaxRule +// Implementation of a syntax rule that can be applied. +#[derive(Debug)] +pub struct SyntaxRule { + pub name: String, + pub left: String, + pub right: String, +} + +// Implementation of SyntaxRule +// Load and Resolve from outside +impl SyntaxRule { + // @name new + // @return SyntaxRule + // @brief Create a new syntax rule / load rule set. + // @param name_: String, left_: String, right_: String + fn new(name_: String, left_: String, right_: String) -> SyntaxRule { + SyntaxRule { + name: String::new(), + left: String::new(), + right: String::new(), + } + } + + // @name load + // @return Vec + // @brief Load configuration and retrieve transformation rules. + // @param configuration_filename: &str + pub fn load(configuration_filename: &str) -> Vec { + let mut rules: Vec = vec![]; + let configuration_content: String = std::fs::read_to_string(configuration_filename) + .expect("[ERROR] Could not open configuration file!"); + let configuration = gtoml::parse(configuration_content.as_str()) + .expect("[ERROR] TOML invalid in preprocessor!"); + let configuration_unpacked: Table = Table::try_from(configuration).unwrap(); + + let syntax_definitions: Table = match configuration_unpacked.get("syntax") { + Some(config) => config.as_table().unwrap().clone(), + None => Table::new(), + }; + + for key in syntax_definitions.keys() { + let rule: Value = syntax_definitions.get(key).unwrap().clone(); + if rule.is_array() { + let rule_array = rule.as_array().unwrap(); + let left: String = rule_array[0].to_string(); + let right: String = rule_array[1].to_string(); + rules.push(SyntaxRule { + name: key.to_string(), + left: left, + right: right, + }); + } + } + + rules + } + + // @name resolve + // @return String + // @brief Applies all rules until none of them can be applied again. + // @param rules: Vec, unsolved: String + pub fn resolve(rules: Vec, unsolved: String) -> String { + String::new() + } + + // @name transform + // @return String + // @brief Applies a rule. + // @param &mut self, unformed: String + fn transform(&mut self, unformed: String) -> String { + String::new() + } +} diff --git a/src/testcases.rs b/src/testcases.rs index 2f76581..ca05fd2 100644 --- a/src/testcases.rs +++ b/src/testcases.rs @@ -58,4 +58,81 @@ mod tests { ] ) } + + #[test] + fn test_identify_tokens() { + let mut token_sample: crate::tokenizer::Tokenizer = crate::tokenizer::Tokenizer::new(); + token_sample.read_configuration_from_file("./testspecs.toml"); + token_sample.eat("id : -> 125;"); + token_sample.identify_tokens(); + + let mut token_verify: crate::tokenizer::Tokenizer = crate::tokenizer::Tokenizer::new(); + token_verify.read_configuration_from_file("./testspecs.toml"); + token_verify.eat("id : -> 125;"); + + token_verify.tokens = vec![ + crate::tokenizer::Token { + token: String::from("id"), + token_type: crate::tokenizer::TokenType::IDENTIFIER, + }, + crate::tokenizer::Token { + token: String::from(":"), + token_type: crate::tokenizer::TokenType::OPERAND, + }, + crate::tokenizer::Token { + token: String::from("->"), + token_type: crate::tokenizer::TokenType::OPERAND, + }, + crate::tokenizer::Token { + token: String::from("125"), + token_type: crate::tokenizer::TokenType::IDENTIFIER, + }, + crate::tokenizer::Token { + token: String::from(";"), + token_type: crate::tokenizer::TokenType::TERMINATOR, + }, + ]; + + assert_eq!(token_sample.configuration, token_verify.configuration); + assert_eq!(token_sample.tokens.len(), token_verify.tokens.len()); + assert_eq!(token_sample.token_list.len(), token_verify.token_list.len()); + } + + // @name test_syntax_load + // @return + // @brief + // @param + #[test] + fn test_syntax_load() { + let test: Vec = + crate::syntax::SyntaxRule::load("./testspecs.toml"); + let verify: Vec = vec![ + crate::syntax::SyntaxRule { + name: String::from("replace_predef"), + left: String::from( + "IDENTIFIER#1 -> OTHER := OTHER#2 TERMINATOR OTHER IDENTIFIER#1", + ), + right: String::from("#1 -> OTHER := #2 TERMINATOR OTHER (#2)"), + }, + crate::syntax::SyntaxRule { + name: String::from("replace_postdef"), + left: String::from( + "IDENTIFIER#1 OTHER TERMINATOR IDENTIFIER#1 -> OTHER := OTHER#2 TERMINATOR", + ), + right: String::from("#2 OTHER TERMINATOR #1 -> OTHER := #2 TERMINATOR"), + }, + crate::syntax::SyntaxRule { + name: String::from("unfold_parameter"), + left: String::from(": OTHER IDENTIFIER#1 ( IDENTIFIER#2 OTHER#3 ) OTHER ->"), + right: String::from(": OTHER #1 #2 #1 ( #3 ) OTHER ->"), + }, + crate::syntax::SyntaxRule { + name: String::from("unfold_parameter_remove_brackets"), + left: String::from(": OTHER IDENTIFIER ( ) OTHER ->"), + right: String::from(": OTHER OTHER ->"), + }, + ]; + + assert_eq!(test.len(), verify.len()); + } }