Skip to main content

titan_ast_runtime_lib/
ast.rs

1use std::convert::TryFrom;
2use std::hash::{Hash, Hasher};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub(crate) enum GrammarAction {
6    Text = 0,
7    Skip = 1,
8}
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum GrammarType {
12    TerminalFragment = 0,
13    Terminal = 1,
14    Nonterminal = 2,
15}
16
17#[derive(Debug, Clone)]
18pub(crate) struct NonterminalGrammar {
19    pub(crate) index: usize,
20    pub(crate) name: String,
21    pub(crate) type_: GrammarType,
22    pub(crate) action: GrammarAction,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub(crate) enum LookaheadMatchingMode {
27    Greediness = 0,
28    Laziness = 1,
29}
30
31#[derive(Debug, Clone)]
32pub(crate) struct TerminalGrammar {
33    pub(crate) index: usize,
34    pub(crate) name: String,
35    pub(crate) type_: GrammarType,
36    pub(crate) action: GrammarAction,
37    pub(crate) lookahead_matching_mode: LookaheadMatchingMode,
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Hash)]
41pub(crate) enum Grammar {
42    TerminalGrammar(TerminalGrammar),
43    NonterminalGrammar(NonterminalGrammar),
44}
45
46#[derive(Debug, Clone)]
47pub struct AstToken {
48    pub start: usize,
49    pub data: TokenData,
50}
51
52#[derive(Debug, PartialEq, Eq, Clone)]
53pub(crate) enum TokenType {
54    Text = 0,
55    Skip = 1,
56}
57
58impl From<GrammarAction> for TokenType {
59    fn from(value: GrammarAction) -> Self {
60        match value {
61            GrammarAction::Text => TokenType::Text,
62            GrammarAction::Skip => TokenType::Skip,
63        }
64    }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Hash)]
68pub struct TokenData {
69    pub data: Vec<u8>,
70}
71
72#[derive(Debug, Clone)]
73pub(crate) struct Token {
74    pub(crate) start: usize,
75    pub(crate) text: TokenData,
76    pub(crate) terminal: Grammar,
77    pub(crate) type_: TokenType,
78}
79
80impl Grammar {
81    pub(crate) fn is_greediness(&self) -> bool {
82        return match self {
83            Grammar::TerminalGrammar(terminal) => {
84                terminal.lookahead_matching_mode == LookaheadMatchingMode::Greediness
85            }
86            Grammar::NonterminalGrammar(_) => false,
87        };
88    }
89
90    pub(crate) fn get_action(&self) -> GrammarAction {
91        match self {
92            Grammar::TerminalGrammar(terminal) => terminal.action.clone(),
93            Grammar::NonterminalGrammar(nonterminal) => nonterminal.action.clone(),
94        }
95    }
96
97    pub(crate) fn get_index(&self) -> usize {
98        match self {
99            Grammar::TerminalGrammar(terminal) => terminal.index,
100            Grammar::NonterminalGrammar(nonterminal) => nonterminal.index,
101        }
102    }
103
104    pub(crate) fn get_ast_grammar(&self) -> AstGrammar {
105        match self {
106            Grammar::TerminalGrammar(terminal) => AstGrammar {
107                name: terminal.name.clone(),
108                type_: terminal.type_.clone(),
109            },
110            Grammar::NonterminalGrammar(nonterminal) => AstGrammar {
111                name: nonterminal.name.clone(),
112                type_: nonterminal.type_.clone(),
113            },
114        }
115    }
116}
117
118#[derive(Debug, Clone)]
119pub struct AstGrammar {
120    pub name: String,
121    pub type_: GrammarType,
122}
123
124#[derive(Debug, Clone)]
125pub struct Ast {
126    pub grammar: AstGrammar,
127    pub alias: Option<String>,
128    pub token: Option<AstToken>,
129    pub children: Vec<Ast>,
130}
131
132impl Default for Ast {
133    fn default() -> Self {
134        Ast {
135            grammar: Default::default(),
136            alias: Default::default(),
137            token: Default::default(),
138            children: Default::default(),
139        }
140    }
141}
142
143impl Default for AstGrammar {
144    fn default() -> Self {
145        Self {
146            name: "".to_string(),
147            type_: GrammarType::Terminal,
148        }
149    }
150}
151
152impl Default for Grammar {
153    fn default() -> Self {
154        Grammar::TerminalGrammar(Default::default())
155    }
156}
157
158impl Default for TerminalGrammar {
159    fn default() -> Self {
160        Self {
161            index: 0,
162            name: Default::default(),
163            type_: GrammarType::Terminal,
164            action: GrammarAction::Skip,
165            lookahead_matching_mode: LookaheadMatchingMode::Greediness,
166        }
167    }
168}
169
170impl Default for NonterminalGrammar {
171    fn default() -> Self {
172        Self {
173            index: 0,
174            name: Default::default(),
175            type_: GrammarType::Nonterminal,
176            action: GrammarAction::Skip,
177        }
178    }
179}
180
181impl PartialEq for TerminalGrammar {
182    fn eq(&self, other: &Self) -> bool {
183        self.index == other.index
184    }
185}
186impl Eq for TerminalGrammar {}
187impl Hash for TerminalGrammar {
188    fn hash<H: Hasher>(&self, hasher: &mut H) {
189        self.index.hash(hasher);
190    }
191}
192
193impl PartialEq for NonterminalGrammar {
194    fn eq(&self, other: &Self) -> bool {
195        self.index == other.index
196    }
197}
198impl Eq for NonterminalGrammar {}
199impl Hash for NonterminalGrammar {
200    fn hash<H: Hasher>(&self, hasher: &mut H) {
201        self.index.hash(hasher);
202    }
203}
204
205impl TryFrom<i32> for GrammarType {
206    type Error = ();
207
208    fn try_from(value: i32) -> Result<Self, Self::Error> {
209        match value {
210            v if v == GrammarType::TerminalFragment as i32 => Ok(GrammarType::TerminalFragment),
211            v if v == GrammarType::Terminal as i32 => Ok(GrammarType::Terminal),
212            v if v == GrammarType::Nonterminal as i32 => Ok(GrammarType::Nonterminal),
213            _ => Err(()),
214        }
215    }
216}
217
218impl TryFrom<i32> for GrammarAction {
219    type Error = ();
220
221    fn try_from(value: i32) -> Result<Self, Self::Error> {
222        match value {
223            v if v == GrammarAction::Text as i32 => Ok(GrammarAction::Text),
224            v if v == GrammarAction::Skip as i32 => Ok(GrammarAction::Skip),
225            _ => Err(()),
226        }
227    }
228}
229
230impl TryFrom<i32> for LookaheadMatchingMode {
231    type Error = ();
232
233    fn try_from(value: i32) -> Result<Self, Self::Error> {
234        match value {
235            v if v == LookaheadMatchingMode::Greediness as i32 => {
236                Ok(LookaheadMatchingMode::Greediness)
237            }
238            v if v == LookaheadMatchingMode::Laziness as i32 => Ok(LookaheadMatchingMode::Laziness),
239            _ => Err(()),
240        }
241    }
242}