Load configuration for in language syntax replacements

This commit is contained in:
Yannick Reiß 2025-08-26 22:43:59 +02:00
parent f67c79c65b
commit 2a846a5f53
3 changed files with 154 additions and 27 deletions

View File

@ -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);
} */
}

76
src/syntax.rs Normal file
View File

@ -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<SyntaxRule>
// @brief Load configuration and retrieve transformation rules.
// @param configuration_filename: &str
pub fn load(configuration_filename: &str) -> Vec<SyntaxRule> {
let mut rules: Vec<SyntaxRule> = 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<SyntaxRule>, unsolved: String
pub fn resolve(rules: Vec<SyntaxRule>, 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()
}
}

View File

@ -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> =
crate::syntax::SyntaxRule::load("./testspecs.toml");
let verify: Vec<crate::syntax::SyntaxRule> = 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());
}
}