#![allow(dead_code, unused_imports, non_camel_case_types)] #![allow(missing_docs, rustdoc::missing_crate_level_docs)] #![allow(clippy::unnecessary_cast)] #![doc = include_str!("readme.md")] mod parse_cst; mod parse_ast; use core::str::FromStr; use std::{borrow::Cow, ops::Range, sync::OnceLock}; use yggdrasil_rt::*; {%- set rules = self.grammar.rules() %} {%- set rule_name = self.grammar.rule_name() %} {%- set parser_name = self.grammar.parser_name() %} type Input<'i> = Box>; type Output<'i> = Result>, Box>>; #[doc = include_str!("railway.min.svg")] #[repr(C)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct {{ parser_name }} {} impl YggdrasilParser for {{ parser_name }} { type Rule = {{ rule_name }}; fn parse_cst(input: &str, rule: Self::Rule) -> OutputResult<{{ rule_name }}> { self::parse_cst::parse_cst(input, rule) } } #[repr(u32)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum {{ rule_name }} { {%- for rule in rules.iter() %} {{ rule.name.text|safe_rust_id }}, {%- endfor %} /// Label for text literal IgnoreText, /// Label for regex literal IgnoreRegex, } impl YggdrasilRule for {{ rule_name }} { fn is_ignore(&self) -> bool { {%- if self.grammar.ignore_rules_empty() %} false {%- else %} matches!(self, {{ self.grammar.ignore_rule_pattern() }}) {%- endif %} } fn get_style(&self) -> &'static str { match self { {%- for rule in rules.iter() %} Self::{{ rule.name.text|safe_rust_id }} => "", {%- endfor %} _ => "", } } } {%- for rule in rules.clone() %} #[derive(Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] {%- if rule.is_class() %} pub struct {{ rule.node_name() }} { {%- for field in rule.class_fields() %} {%- if field.field_type(self.grammar).is_empty() %} // Missing rule {{ field.rhs }} {%- else %} {%- if field.count.is_one() %} pub {{ field.field_name()|safe_rust_id }}: {{ field.field_type(self.grammar) }}, {%- else if field.count.is_optional() %} pub {{ field.field_name()|safe_rust_id }}: Option<{{ field.field_type(self.grammar) }}>, {%- else %} pub {{ field.field_name()|safe_rust_id }}: Vec<{{ field.field_type(self.grammar) }}>, {%- endif %} {%- endif %} {%- endfor %} {%- if rule.captures.text %} pub text: String, {%- endif %} pub span: Range<{{ self.config.range_type }}>, } {%- else if rule.is_union() %} pub enum {{ rule.node_name() }} { {%- for (name, variant) in rule.union_fields() %} {%- if variant.is_empty() %} {{ name }}, {%- else if variant.as_single().is_some() %} {{ name }}({{ variant.as_single().unwrap().field_type(self.grammar) }}), {%- else %} {{ name }} { {%- for field in variant %} {%- if field.field_type(self.grammar).is_empty() %} // Missing rule {{ field.rhs }} {%- else %} {%- if field.count.is_one() %} {{ field.field_name()|safe_rust_id }}: {{ field.field_type(self.grammar) }}, {%- else if field.count.is_optional() %} {{ field.field_name()|safe_rust_id }}: Option<{{ field.field_type(self.grammar) }}>, {%- else %} {{ field.field_name()|safe_rust_id }}: Vec<{{ field.field_type(self.grammar) }}>, {%- endif %} {%- endif %} {%- endfor %} }, {%- endif %} {%- endfor %} } {%- endif %} {%- endfor %}