morgana_core/syntax/parser/rules/
mod.rs

1macro_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                // We are taking into consideration the lexing error
7                // arising from inspecting the next token, and we can
8                // conclude its analysis by simply eating the token.
9                _ = $self.lex.eat();
10                // --
11
12                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                // See above
41                _ = $self.lex.eat();
42                // --
43
44                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}