#[cfg(feature = "serialization")]
use adze_ir::{SymbolId, TokenPattern};
#[cfg(feature = "serialization")]
use std::collections::HashMap;
#[cfg(feature = "serialization")]
use std::fs::File;
#[cfg(feature = "serialization")]
use std::path::Path;
#[cfg(feature = "serialization")]
pub fn load_patterns_from_grammar_json(
path: &Path,
) -> Result<HashMap<String, TokenPattern>, Box<dyn std::error::Error>> {
let file = File::open(path)?;
let json: serde_json::Value = serde_json::from_reader(file)?;
let mut patterns = HashMap::new();
if let Some(rules) = json.get("rules").and_then(|r| r.as_object()) {
for (symbol_name, rule) in rules {
let pattern = extract_pattern_from_rule(rule);
if let Some(p) = pattern {
patterns.insert(symbol_name.clone(), p);
}
}
}
Ok(patterns)
}
#[cfg(feature = "serialization")]
fn extract_pattern_from_rule(rule: &serde_json::Value) -> Option<TokenPattern> {
match rule.get("type").and_then(|t| t.as_str()) {
Some("STRING") => {
rule.get("value")
.and_then(|v| v.as_str())
.map(|s| TokenPattern::String(s.to_string()))
}
Some("PATTERN") => {
rule.get("value")
.and_then(|v| v.as_str())
.map(|s| TokenPattern::Regex(s.to_string()))
}
Some("TOKEN") => {
rule.get("content").and_then(extract_pattern_from_rule)
}
Some("IMMEDIATE_TOKEN") => {
rule.get("content").and_then(extract_pattern_from_rule)
}
Some("ALIAS") => {
rule.get("content").and_then(extract_pattern_from_rule)
}
Some("CHOICE") => {
None
}
Some("SYMBOL") => {
None
}
Some("SEQ") | Some("REPEAT") | Some("REPEAT1") | Some("PREC") | Some("PREC_LEFT")
| Some("PREC_RIGHT") | Some("PREC_DYNAMIC") => {
None
}
_ => {
None
}
}
}
#[cfg(feature = "serialization")]
pub fn load_patterns_with_symbol_map(
grammar_json_path: &Path,
symbol_names: &[String],
) -> Result<HashMap<SymbolId, TokenPattern>, Box<dyn std::error::Error>> {
let patterns_by_name = load_patterns_from_grammar_json(grammar_json_path)?;
let mut patterns_by_id = HashMap::new();
for (idx, name) in symbol_names.iter().enumerate() {
if let Some(pattern) = patterns_by_name.get(name) {
patterns_by_id.insert(SymbolId(idx as u16), pattern.clone());
}
}
Ok(patterns_by_id)
}