use crate::error::{RealizarError, Result};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum GrammarElement {
Char(char),
CharRange(char, char),
RuleRef(String),
CharNot(Vec<char>),
Any,
End,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GrammarAlternative {
pub elements: Vec<GrammarElement>,
}
impl GrammarAlternative {
pub fn new(elements: Vec<GrammarElement>) -> Self {
Self { elements }
}
pub fn char(c: char) -> Self {
Self {
elements: vec![GrammarElement::Char(c)],
}
}
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct GrammarRule {
pub name: String,
pub alternatives: Vec<GrammarAlternative>,
}
impl GrammarRule {
pub fn new(name: impl Into<String>, alternatives: Vec<GrammarAlternative>) -> Self {
Self {
name: name.into(),
alternatives,
}
}
pub fn single(name: impl Into<String>, elements: Vec<GrammarElement>) -> Self {
Self {
name: name.into(),
alternatives: vec![GrammarAlternative::new(elements)],
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Grammar {
rules: HashMap<String, GrammarRule>,
root: String,
}
impl Grammar {
pub fn new() -> Self {
Self {
rules: HashMap::new(),
root: String::new(),
}
}
pub fn with_root(root: impl Into<String>) -> Self {
Self {
rules: HashMap::new(),
root: root.into(),
}
}
pub fn add_rule(&mut self, rule: GrammarRule) {
if self.root.is_empty() {
self.root.clone_from(&rule.name);
}
self.rules.insert(rule.name.clone(), rule);
}
pub fn get_rule(&self, name: &str) -> Option<&GrammarRule> {
self.rules.get(name)
}
pub fn root(&self) -> &str {
&self.root
}
pub fn set_root(&mut self, root: impl Into<String>) {
self.root = root.into();
}
pub fn rule_names(&self) -> impl Iterator<Item = &String> {
self.rules.keys()
}
pub fn len(&self) -> usize {
self.rules.len()
}
pub fn is_empty(&self) -> bool {
self.rules.is_empty()
}
pub fn validate(&self) -> Result<()> {
if self.root.is_empty() {
return Err(RealizarError::InvalidConfiguration(
"Grammar has no root rule".to_string(),
));
}
if !self.rules.contains_key(&self.root) {
return Err(RealizarError::InvalidConfiguration(format!(
"Root rule '{}' not found in grammar",
self.root
)));
}
for rule in self.rules.values() {
for alt in &rule.alternatives {
for elem in &alt.elements {
if let GrammarElement::RuleRef(ref_name) = elem {
if !self.rules.contains_key(ref_name) {
return Err(RealizarError::InvalidConfiguration(format!(
"Rule '{}' references undefined rule '{}'",
rule.name, ref_name
)));
}
}
}
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct GrammarState {
pub rule: String,
pub alt_idx: usize,
pub elem_idx: usize,
pub stack: Vec<(String, usize, usize)>,
}
impl GrammarState {
pub fn initial(root: &str) -> Self {
Self {
rule: root.to_string(),
alt_idx: 0,
elem_idx: 0,
stack: Vec::new(),
}
}
pub fn is_complete(&self, grammar: &Grammar) -> bool {
if let Some(rule) = grammar.get_rule(&self.rule) {
if self.alt_idx < rule.alternatives.len() {
let alt = &rule.alternatives[self.alt_idx];
return self.elem_idx >= alt.elements.len() && self.stack.is_empty();
}
}
false
}
pub fn current_element<'a>(&self, grammar: &'a Grammar) -> Option<&'a GrammarElement> {
grammar.get_rule(&self.rule).and_then(|rule| {
rule.alternatives
.get(self.alt_idx)
.and_then(|alt| alt.elements.get(self.elem_idx))
})
}
}
#[derive(Debug, Clone)]
pub struct GrammarStateMachine {
grammar: Grammar,
states: Vec<GrammarState>,
generated: String,
}
include!("grammar_state_machine.rs");
include!("mod_add_schema.rs");
include!("tool.rs");
include!("grammar.rs");