pag_parser/
core_syntax.rs

1// Copyright (c) 2023 Paguroidea Developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use std::{collections::HashMap, fmt::Display};
10
11use pest::Span;
12
13use crate::{frontend::WithSpan, utilities::Symbol};
14
15#[derive(Debug, Clone)]
16pub enum Term<'src, 'a> {
17    Epsilon,
18    Sequence(&'a WithSpan<'src, Self>, &'a WithSpan<'src, Self>),
19    LexerRef(Symbol<'src>),
20    Bottom,
21    Alternative(&'a WithSpan<'src, Self>, &'a WithSpan<'src, Self>),
22    // Star(&'a WithSpan<'src, Self>),
23    Fix(Symbol<'src>, &'a WithSpan<'src, Self>),
24    ParserRef(Symbol<'src>),
25}
26
27pub type TermPtr<'src, 'a> = &'a WithSpan<'src, Term<'src, 'a>>;
28pub type TermArena<'src, 'a> = typed_arena::Arena<WithSpan<'src, Term<'src, 'a>>>;
29
30pub fn allocate_term<'src, 'a>(
31    arena: &'a TermArena<'src, 'a>,
32    node: Term<'src, 'a>,
33    span: Span<'src>,
34) -> TermPtr<'src, 'a> {
35    arena.alloc(WithSpan { span, node })
36}
37
38pub struct ParserRule<'src, 'a> {
39    pub active: bool,
40    pub term: TermPtr<'src, 'a>,
41}
42
43pub type BindingContext<'src, 'a> = HashMap<Symbol<'src>, ParserRule<'src, 'a>>;
44
45impl<'src, 'a> Display for Term<'src, 'a> {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        match self {
48            Term::Epsilon => {
49                write!(f, "ε")
50            }
51            Term::Sequence(x, y) => {
52                write!(f, "({x} ~ {y})",)
53            }
54            Term::LexerRef(x) => {
55                write!(f, "{x}")
56            }
57            Term::Bottom => {
58                write!(f, "⊥")
59            }
60            Term::Alternative(x, y) => {
61                write!(f, "({x} | {y})")
62            }
63            Term::Fix(x, y) => {
64                write!(f, "(μ {x} . {y})",)
65            }
66            Term::ParserRef(x) => {
67                write!(f, "{x}")
68            }
69        }
70    }
71}