morgana_core/syntax/parser/rules/
mod.rs1macro_rules! want {
2 ($self: ident, $test: expr, $msg: expr) => {
3 match $self.lex.peek() {
4 Err(e) => {
5 log::debug!("want in {}, found error {}", function_name!(), e);
6 _ = $self.lex.eat();
10 Err(e)
13 }
14 Ok(t) => {
15 log::debug!(
16 "want in {}, found token {} @ {}",
17 function_name!(),
18 t.kind,
19 t.range
20 );
21 let f = $test;
22 if f(t.kind.clone()) {
23 _ = $self.lex.eat();
24 Ok(())
25 } else {
26 Err(anyhow::anyhow!(
27 crate::syntax::parser::error::ParseError::new(
28 format!(concat!("expected ", $msg, ", found {}"), t.kind),
29 t.range
30 )
31 ))
32 }
33 }
34 }
35 };
36
37 ($self: ident, $kind: ident, $var: ident, $msg: expr) => {
38 match $self.lex.peek() {
39 Err(e) => {
40 _ = $self.lex.eat();
42 Err(e)
45 }
46
47 Ok(t) => match t.kind {
48 crate::syntax::lexer::token::TokenKind::$kind($var) => {
49 _ = $self.lex.eat();
50 Ok($var)
51 }
52 _ => Err(anyhow::anyhow!(
53 crate::syntax::parser::error::ParseError::new(
54 format!(concat!("expected ", $msg, ", found {}"), t.kind),
55 t.range
56 )
57 )),
58 },
59 }
60 };
61}
62
63macro_rules! ifis {
64 ($self: ident, $kind: ident, $var: ident, $then: expr) => {
65 if let Ok(t) = $self.lex.peek() {
66 log::trace!("ifis -- ok");
67 match t.kind {
68 crate::syntax::lexer::token::TokenKind::$kind(
69 crate::syntax::lexer::token::$kind::$var,
70 ) => {
71 _ = $self.lex.eat();
72 Some($then)
73 }
74 _ => None,
75 }
76 } else {
77 log::trace!("ifis -- Err");
78 None
79 }
80 };
81}
82
83macro_rules! route {
84 ($self: ident, $msg:expr, ($($case1:expr),+), $then1:ident,
85 $(($($case:expr),+), $then:ident),*) => {
86 match $self.lex.peek() {
87 Err(e) => {
88 _ = $self.lex.eat();
89 Err(e)
90 }
91 Ok(t) => {
92 if t.kind.is_in(vec![$($case1),*].into_iter().collect()) {
93 Ok($self.$then1())
94 }
95
96 $(
97 else if t.kind.is_in(vec![$($case),*].into_iter().collect()) {
98 Ok($self.$then())
99 }
100 )*
101
102 else {
103 Err(anyhow::anyhow!(crate::syntax::parser::error::ParseError::new(
104 format!("expected {}, found {}", $msg, t.kind),
105 t.range
106 )))
107 }
108
109 }
110 }
111 };
112
113 ($self: ident, $msg:expr, $case1:expr, $then1:ident,
114 $($case:expr, $then:ident),*) => {
115 match $self.lex.peek() {
116 Err(e) => {
117 _ = $self.lex.eat();
118 Err(e)
119 }
120 Ok(t) => {
121
122 if ($case1)(t.kind.clone()) {
123 Ok($self.$then1())
124 }
125
126 $(
127 else if ($case)(t.kind.clone()) {
128 Ok($self.$then())
129 }
130 )*
131
132 else {
133 Err(anyhow::anyhow!(crate::syntax::parser::error::ParseError::new(
134 format!("expected {}, found {}", $msg, t.kind),
135 t.range
136 )))
137 }
138
139 }
140 }
141 };
142
143
144}
145
146use super::grammar::ast::{ConcreteMorg, Statement};
147
148use crate::syntax::{
149 lexer::token::*,
150 parser::{error::ParseError, grammar::ast::*, Parser},
151};
152
153use stdext::function_name;
154
155mod constructor;
156mod expression;
157mod statement;
158
159impl Parser {
160 pub(super) fn morg(&mut self) -> ConcreteMorg {
161 log::trace!("{}", function_name!());
162
163 let morg_name: Option<MorgName> = ifis!(self, Keyword, Morg, self.morg_name());
164 log::trace!("morg name is {:?}", morg_name);
165
166 let start_statement: Option<StartStatement> =
167 ifis!(self, Keyword, Start, self.start_statement());
168 log::trace!("start statement is {:?}", morg_name);
169
170 let mut res = ConcreteMorg {
171 morg_name,
172 start_statement,
173 statements: vec![],
174 };
175
176 loop {
177 match self.lex.peek() {
178 Err(e) => {
179 _ = self.lex.eat();
180 self.errs.push(e);
181 }
182 Ok(t) => match t.kind {
183 TokenKind::EOF => break,
184 TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Node)
185 | TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Skip)
186 | TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Squash)
187 | TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Special) => {
188 res.statements.push(self.statement())
189 }
190 _ => {
191 log::trace!("unexpected from morg: {} @ {}", t.kind, t.range);
192 self.errs.push(anyhow::anyhow!(ParseError::new(
193 format!("unexpected token {}", t.kind),
194 t.range
195 )));
196 _ = self.lex.eat();
197 }
198 },
199 }
200 }
201
202 res
203 }
204
205 fn morg_name(&mut self) -> MorgName {
206 log::trace!("{}", function_name!());
207 want!(self, Identifier, id, "identifier to name the Morg,")
208 }
209
210 fn start_statement(&mut self) -> StartStatement {
211 log::trace!("{}", function_name!());
212 want!(
213 self,
214 Identifier,
215 id,
216 "identifier to name the initial symbol"
217 )
218 }
219
220 fn statement(&mut self) -> Statement {
221 log::trace!("{} with token {:?}", function_name!(), self.lex.peek());
222 match self.lex.peek() {
223 Ok(t) => match t.kind {
224 TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Node)
225 | TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Squash) => {
226 Statement::Definition(self.definition())
227 }
228 TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Skip) => {
229 Statement::Skip(self.skip())
230 }
231 TokenKind::Keyword(crate::syntax::lexer::token::Keyword::Special) => {
232 Statement::Special(self.special())
233 }
234
235 _ => unreachable!(),
236 },
237 Err(_) => unreachable!(),
238 }
239 }
240}