wagon_parser/parser/
wag.rs1use std::fmt::Display;
2
3use crate::firstpass::{FirstPassState, FirstPassResult, WagCheckError};
4
5use super::{Parse, ParseResult, LexerBridge, Rewrite, SpannableNode, Spannable, Peek};
6use super::metadata::Metadata;
7use super::rule::Rule;
8use indexmap::IndexMap;
9
10use wagon_macros::new_unspanned;
11
12#[derive(PartialEq, Debug, Eq, Hash)]
13#[new_unspanned]
14pub struct Wag {
19 pub metadata: SpannableNode<Metadata>,
21 pub grammar: Vec<SpannableNode<Rule>>,
23}
24
25impl Parse for Wag {
26 fn parse(lexer: &mut LexerBridge) -> ParseResult<Self> {
27 let metadata = SpannableNode::parse(lexer)?;
28 let mut grammar = Vec::new();
29 while lexer.peek().is_some() {
30 grammar.push(SpannableNode::parse(lexer)?);
31 }
32 Ok(Self {metadata, grammar})
33 }
34}
35
36impl Rewrite<()> for Wag {
38
39 fn rewrite(&mut self, depth: usize, state: &mut FirstPassState) -> FirstPassResult<()> {
40 fn handle_conflict(mut new_rule: SpannableNode<Rule>, map: &mut IndexMap<String, SpannableNode<Rule>>) -> FirstPassResult<()>{ let ident = match &new_rule.node { Rule::Analytic(s, ..) | Rule::Generate(s, ..) => s.clone(),
43 Rule::Import(..) | Rule::Exclude(..) => todo!(),
44 };
45 if let Some(orig) = map.get_mut(&ident) { match (&mut orig.node, &mut new_rule.node) {
47 (Rule::Analytic(_, args1, v1), Rule::Analytic(_, args2, v2)) | (Rule::Generate(_, args1, v1), Rule::Generate(_, args2, v2)) => { if args1 == args2 { v1.extend(std::mem::take(v2)); } else { return Err(WagCheckError::DisparateParameters { terminal: ident, offender: args1.to_owned(), expected: args2.to_owned(), span: new_rule.span()});
52 }
53 },
54 _ => {map.insert(ident, new_rule);}
55 }
56 } else { map.insert(ident, new_rule);
58 };
59 Ok(())
60 }
61 let rules = std::mem::take(&mut self.grammar);
62 let mut map: IndexMap<String, SpannableNode<Rule>> = IndexMap::with_capacity(rules.len());
63 for mut rule in rules {
64 let new_rules = rule.rewrite(depth, state)?.0; handle_conflict(rule, &mut map)?; for new_rule in new_rules {
67 handle_conflict(new_rule, &mut map)?; }
69 }
70 self.grammar.extend(map.into_values());
71 Ok(())
72 }
73
74}
75
76impl Display for Wag {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 self.metadata.fmt(f)?;
79 for rule in &self.grammar {
80 rule.fmt(f)?;
81 }
82 Ok(())
83 }
84}