alder/core/
state.rs

1use crate::*;
2use std::fmt::{Debug, Error, Formatter};
3use std::sync::Arc;
4
5#[derive(Debug)]
6pub struct ParseErrorContext {
7    pub node: NodeId,
8    pub span: Span,
9}
10
11impl ParseErrorContext {
12    pub fn new(node: NodeId, span: Span) -> Self {
13        Self { node, span }
14    }
15}
16
17#[derive(Debug)]
18pub struct ParseError {
19    pub problem: Box<dyn Problem + 'static>,
20    pub span: Span,
21    pub context: Vec<ParseErrorContext>,
22}
23
24impl ParseError {
25    pub fn new(
26        problem: Box<dyn Problem + 'static>,
27        span: Span,
28        context: Vec<ParseErrorContext>,
29    ) -> Self {
30        Self {
31            problem,
32            span,
33            context,
34        }
35    }
36}
37
38pub struct State {
39    pub input: Span,
40    pub nodes: Vec<Node>,
41    extras: Vec<Option<Arc<dyn Parser>>>,
42    parsing_extra: bool,
43    pub(crate) errors: Vec<ParseError>,
44    pub panic: bool,
45}
46
47impl Debug for State {
48    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
49        self.input.fmt(f)?;
50        self.nodes.fmt(f)?;
51        Ok(())
52    }
53}
54
55impl<'a> From<&'a str> for State {
56    fn from(input: &'a str) -> State {
57        let input: Span = input.into();
58        Self {
59            input: input.clone(),
60            nodes: vec![Node::root(input)],
61            extras: vec![],
62            errors: vec![],
63            parsing_extra: false,
64            panic: false,
65        }
66    }
67}
68
69impl State {
70    pub fn parse(input: &str, parser: impl Parser) -> Parsed {
71        let mut state = Self::from(input);
72        state.add(parser);
73        let nodes = state.nodes.pop().expect("At least root").children;
74        Parsed {
75            input: input.into(),
76            rest: state.input,
77            nodes,
78            errors: state.errors,
79        }
80    }
81
82    pub fn add_node(&mut self, node: Node) {
83        if !self.parsing_extra && !self.panic {
84            self.add_extra();
85        }
86
87        self.add_node_inner(node);
88
89        if !self.parsing_extra && !self.panic {
90            self.add_extra();
91        }
92    }
93
94    pub fn add(&mut self, parser: impl Parser) {
95        if !self.parsing_extra && !self.panic {
96            self.add_extra();
97        }
98
99        let node = parser.parse(self);
100        self.add_node_inner(node);
101
102        if !self.parsing_extra && !self.panic {
103            self.add_extra();
104        }
105    }
106}
107
108impl State {
109    pub fn push_extra(&mut self, extra: std::sync::Arc<dyn Parser>) {
110        self.extras.push(Some(extra));
111    }
112
113    pub fn push_atomic(&mut self) {
114        self.extras.push(None);
115    }
116
117    pub fn pop_extra(&mut self) {
118        self.extras.pop();
119    }
120
121    pub(crate) fn add_node_inner(&mut self, node: Node) {
122        let parent = self.node().expect("At least root");
123
124        if node.is(NodeId::VIRTUAL) {
125            for mut child in node.children {
126                if !child.is(NodeId::EXTRA) {
127                    child.add_aliases(node.alias.as_slice());
128                }
129                parent.children.push(child);
130            }
131            return;
132        }
133
134        parent.children.push(node);
135    }
136
137    pub(crate) fn last_error(&mut self) -> Option<&mut Node> {
138        self.node()
139            .and_then(|root| root.children.last_mut())
140            .and_then(|node| {
141                if node.is(NodeId::ERROR) {
142                    Some(node)
143                } else {
144                    None
145                }
146            })
147    }
148
149    pub(crate) fn pop_node(&mut self) -> Option<Node> {
150        self.node().and_then(|root| root.children.pop())
151    }
152}
153
154impl State {
155    fn node(&mut self) -> Option<&mut Node> {
156        self.nodes.last_mut()
157    }
158
159    fn add_extra(&mut self) {
160        if let Some(Some(extra)) = self.extras.last() {
161            self.parsing_extra = true;
162            let extra = extra.clone();
163            let mut extra_node = extra.parse(self);
164            extra_node.add_alias(NodeId::EXTRA);
165            self.add_node_inner(extra_node);
166            self.parsing_extra = false;
167        }
168    }
169}