parser finally fixed

This commit is contained in:
filipriec
2025-07-07 15:07:08 +02:00
parent 11487f0833
commit afdd5c5740

View File

@@ -4,7 +4,7 @@ use std::collections::HashSet;
pub struct ScriptParser { pub struct ScriptParser {
math_operators: Vec<(Regex, &'static str)>, math_operators: Vec<(Regex, &'static str)>,
number_literal_re: Regex, number_re: Regex,
variable_re: Regex, variable_re: Regex,
} }
@@ -50,8 +50,10 @@ impl ScriptParser {
ScriptParser { ScriptParser {
math_operators, math_operators,
// Simple regex that matches numbers - we'll handle context in the replacement // VALID REGEX:
number_literal_re: Regex::new(r"\b(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\b").unwrap(), // This captures the preceding delimiter (group 1) and the number (group 2) separately.
// This avoids lookarounds and allows us to reconstruct the string correctly.
number_re: Regex::new(r"(^|[\s\(])(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)").unwrap(),
variable_re: Regex::new(r"\$(\w+)").unwrap(), variable_re: Regex::new(r"\$(\w+)").unwrap(),
} }
} }
@@ -60,40 +62,40 @@ impl ScriptParser {
pub fn transform(&self, script: &str) -> String { pub fn transform(&self, script: &str) -> String {
let mut transformed = script.to_string(); let mut transformed = script.to_string();
// Step 1: Convert numeric literals to strings // CORRECT ORDER: Functions first, then variables, then numbers.
transformed = self.convert_numbers_to_strings(&transformed);
// Step 2: Replace math function calls with decimal equivalents
transformed = self.replace_math_functions(&transformed); transformed = self.replace_math_functions(&transformed);
// Step 3: Replace variable references
transformed = self.replace_variable_references(&transformed); transformed = self.replace_variable_references(&transformed);
transformed = self.convert_numbers_to_strings(&transformed);
transformed transformed
} }
/// Convert all unquoted numeric literals to quoted strings /// Convert all unquoted numeric literals to quoted strings
fn convert_numbers_to_strings(&self, script: &str) -> String { fn convert_numbers_to_strings(&self, script: &str) -> String {
// Simple approach: split on quotes and only process unquoted sections
let parts: Vec<&str> = script.split('"').collect(); let parts: Vec<&str> = script.split('"').collect();
let mut result = String::new(); let mut result = String::new();
for (i, part) in parts.iter().enumerate() { for (i, part) in parts.iter().enumerate() {
if i % 2 == 0 { if i % 2 == 0 {
// Even indices are outside quotes - process them // Even indices are outside quotes - process them
let processed = self.number_literal_re.replace_all(part, "\"$1\""); let processed = self.number_re.replace_all(part, |caps: &regex::Captures| {
// Reconstruct the string:
// caps[1] is the delimiter (space, '(', or start of string)
// caps[2] is the number itself
// We put the delimiter back and wrap the number in quotes.
format!("{}\"{}\"", &caps[1], &caps[2])
});
result.push_str(&processed); result.push_str(&processed);
} else { } else {
// Odd indices are inside quotes - keep as is // Odd indices are inside quotes - keep as is
result.push_str(part); result.push_str(part);
} }
// Add back the quote if not the last part
if i < parts.len() - 1 { if i < parts.len() - 1 {
result.push('"'); result.push('"');
} }
} }
result result
} }
@@ -119,7 +121,6 @@ impl ScriptParser {
pub fn extract_dependencies(&self, script: &str) -> HashSet<String> { pub fn extract_dependencies(&self, script: &str) -> HashSet<String> {
let mut dependencies = HashSet::new(); let mut dependencies = HashSet::new();
// Extract variable dependencies
for cap in self.variable_re.captures_iter(script) { for cap in self.variable_re.captures_iter(script) {
dependencies.insert(cap[1].to_string()); dependencies.insert(cap[1].to_string());
} }