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}