1use super::lexer::{
2 Token,
3 TokenValue,
4 DefinitionType as TokenDefinitionType,
5 DirectiveType as TokenDirectiveType,
6 IdentifierType as TokenIdentifierType,
7 TypeIdentifierType as TokenTypeIdentifierType
8};
9use std::path::Path;
10use std::ops::Range;
11
12#[derive(Debug, Clone)]
15pub struct Property {
16 pub internal_type: TokenTypeIdentifierType,
17 pub name: String,
18 pub definition_type: TokenDefinitionType
19}
20
21#[derive(Debug, Clone)]
22pub enum DefinitionType {
23 Raw,
24 Collective,
25 Root(String)
26}
27
28#[derive(Debug, Clone)]
29pub struct Definition {
30 pub name: String,
31 pub children: Vec<Statement>,
32 pub inherits: Vec<String>,
33 pub definition_type: DefinitionType
34}
35
36#[derive(Debug, Clone)]
37pub struct Setter {
38 pub name: String,
39 pub value: Token,
40 pub range: Range<usize>
41}
42
43#[derive(Debug, Clone)]
44pub struct Object {
45 pub name: String,
46 pub children: Vec<Statement>,
47 pub arguments: Vec<Token>,
48 pub setters: Vec<Setter>
49}
50
51#[derive(Debug, Clone)]
52pub enum StatementValue {
53 Property(Property),
54 Definition(Definition),
55 Object(Object),
56 Header(String),
57 Include(String)
58}
59
60#[derive(Debug, Clone)]
61pub struct Statement {
62 pub value: StatementValue,
63 pub range: Range<usize>
64}
65
66impl Statement {
67 pub fn to_string(&self) -> &str {
68 match &self.value {
69 StatementValue::Property(_) => "Property",
70 StatementValue::Definition(_) => "Definition",
71 StatementValue::Object(_) => "Object",
72 StatementValue::Header(_) => "Header",
73 StatementValue::Include(_) => "Include"
74 }
75 }
76}
77
78pub struct Parser {
81 pub statements: Vec<Statement>,
82 index: usize,
83 tokens: Vec<Token>,
84 filename: String
85}
86
87impl Parser {
88 fn block(&mut self) -> Result<(Vec<Statement>, Range<usize>), (String, Range<usize>)> {
91 if let Some(token) = self.tokens.get(self.index) {
92 let token_range = token.range.clone();
93 if let TokenValue::StartBlock = token.value {
94 self.index += 1;
95 let mut statements = Vec::new();
96 loop {
97 if let Some(token) = self.tokens.get(self.index) {
98 if let TokenValue::EndBlock = token.value {
99 self.index += 1;
100 break;
101 }
102 match self.parse_statement() {
103 Some(result) => {
104 match result {
105 Ok(statement) => {
106 match &statement.value {
107 StatementValue::Property(_) | StatementValue::Object(_) => statements.push(statement),
108 _ => return Err((format!("found {} inside block. Only properties and objects are allowed here.", statement.to_string()), statement.range)),
109 }
110 },
111 Err(err) => return Err(err)
112 }
113 }
114 None => continue
115 }
116 }
117 }
118 Ok(( statements, token_range ))
119 } else {
120 Err((format!("expected the start of a block, found {}", token.to_string()), token.range.clone()))
121 }
122 } else {
123 Err((format!("expected the start of a block, found nothing"), self.statements[self.statements.len()-1].range.clone()))
124 }
125 }
126
127 fn arglist(&mut self) -> Result<(Vec<Token>, Range<usize>), (String, Range<usize>)> {
128 if let Some(token) = self.tokens.get(self.index) {
129 if let TokenValue::StartArgList = token.value {
130 let mut args: Vec<Token> = Vec::new();
131 loop {
132 self.index += 1;
133 if let Some(token) = self.tokens.get(self.index) {
134 match &token.value {
135 TokenValue::Number(_) | TokenValue::String(_) | TokenValue::Bool(_) => args.push(token.clone()),
136 TokenValue::Identifier(_identifier) => {
137 args.push(token.clone())
138 },
139 _ => return Err((format!("found {}, expected Number, String, Bool, or type identifier", token.to_string()), token.range.clone()))
140 }
141
142 self.index += 1;
143 if let Some(token) = self.tokens.get(self.index) {
144 match token.value {
145 TokenValue::ArgListDeliminator => continue,
146 TokenValue::EndArgList => break,
147 _ => return Err((format!("found '{}', expected ','", token.to_string()), token.range.clone()))
148 }
149 } else {
150 return Err((format!("expected ',', found nothing"), token.range.clone()));
151 }
152 } else {
153 return Err((format!("expected Number, String, Bool, or type identifier, found nothing"), token.range.clone()));
154 }
155 }
156 self.index += 1;
157 Ok(( args, token.range.clone() ))
158 } else {
159 Err((format!("expected start of argument list, found {}", token.to_string()), token.range.clone()))
160 }
161 } else {
162 Err((format!("expected start of argument list, found nothing"), self.statements[self.statements.len()-1].range.clone()))
163 }
164 }
165
166 fn definition(&mut self, definition_type: TokenDefinitionType, range: Range<usize>) -> Result<Statement, (String, Range<usize>)> {
167 self.index += 1;
168 if let TokenDefinitionType::Object(name) = definition_type {
169 if let Some(token) = self.tokens.get(self.index) {
170 let mut inherits: Vec<String> = Vec::new();
171 match &token.value {
172 TokenValue::StartBlock => (),
173 TokenValue::Inherits => {
174 self.index += 1;
175 if let Some(token) = self.tokens.get(self.index) {
176 match &token.value {
177 TokenValue::StartArgList => {
178 match self.arglist() {
179 Ok(arglist) => {
180 for token in arglist.0 {
181 if let TokenValue::Identifier(TokenIdentifierType::Generic(parent)) = &token.value {
182 inherits.push(parent.clone());
183 } else {
184 return Err((String::from("argument list of parents must only contain definitions"), arglist.1.clone()));
185 }
186 }
187 },
188 Err(err) => {
189 return Err(err);
190 }
191 }
192 },
193 TokenValue::Identifier(TokenIdentifierType::Generic(parent)) => {
194 inherits.push(parent.clone());
195 self.index += 1;
196 },
197 _ => return Err((format!("expected an argument list or definition, found {}", token.to_string()), token.range.clone()))
198 }
199 } else {
200 return Err((format!("expected an argument list or definition, found nothing"), token.range.clone()));
201 }
202 },
203 _ => return Err((format!("expected a '->' or '{{', found '{}'", token.to_string()), token.range.clone()))
204 }
205 match self.block() {
206 Ok(block) => {
207 let definition_type = {
208 if block.0.iter().all(|x| matches!(&x.value, StatementValue::Property(_))) {
209 DefinitionType::Raw
210 } else if block.0.iter().all(|x| matches!(&x.value, StatementValue::Object(_))) {
211 if name == "root" {
212 let path = Path::new(&self.filename);
213 DefinitionType::Root(path.file_stem().expect("invalid file path").to_str().expect("failed to unwrap file path string").to_string())
214 } else {
215 DefinitionType::Collective
216 }
217 } else {
218 return Err((String::from("a definition can only have all property definitions or all objects"), block.1));
219 }
220 };
221
222 let definition = Definition {
223 name: name.to_string(),
224 children: block.0,
225 definition_type,
226 inherits
227 };
228
229 Ok(Statement {
230 value: StatementValue::Definition(definition),
231 range: range.clone()
232 })
233 },
234 Err(err) => return Err(err)
235 }
236 } else {
237 Err((format!("expected block or inherit statement, found nothing"), range))
238 }
239 } else {
240 match self.arglist() {
241 Ok(arglist) => {
242 if arglist.0.len() != 2 {
243 return Err((format!("expected only 2 arguments, found {} args", arglist.0.len()), arglist.1));
244 }
245
246 let name = &arglist.0[0];
247 if let TokenValue::String(name) = &name.value {
248 let internal_type = &arglist.0[1];
249 if let TokenValue::Identifier(TokenIdentifierType::Type(internal_type)) = &internal_type.value {
250 let property = Property {
251 name: name.clone(),
252 internal_type: internal_type.clone(),
253 definition_type: definition_type.clone()
254 };
255 Ok(Statement {
256 value: StatementValue::Property(property),
257 range: range.clone()
258 })
259 } else {
260 return Err((format!("expected type identifier, found {}", internal_type.to_string()), internal_type.range.clone()));
261 }
262 } else {
263 return Err((format!("expected String, found {}", name.to_string()), name.range.clone()));
264 }
265 },
266 Err(err) => return Err(err)
267 }
268 }
269 }
270
271 fn directive(&mut self, directive_type: TokenDirectiveType, range: Range<usize>) -> Result<Statement, (String, Range<usize>)> {
272 self.index += 1;
273 if let Some(token) = self.tokens.get(self.index) {
274 if let TokenValue::String(arg) = &token.value {
275 self.index += 1;
276 let value = match directive_type {
277 TokenDirectiveType::Header => {
278 StatementValue::Header(arg.clone())
279 },
280 TokenDirectiveType::Include => {
281 StatementValue::Include(arg.clone())
282 }
283 };
284 Ok(Statement {
285 value,
286 range: range.clone()
287 })
288 } else {
289 Err((format!("expected string, found {}", token.to_string()), token.range.clone()))
290 }
291 } else {
292 Err((format!("expected string, found nothing"), range))
293 }
294 }
295
296 fn object(&mut self, identifier_type: TokenIdentifierType, range: Range<usize>) -> Result<Statement, (String, Range<usize>)> {
297 if let TokenIdentifierType::Generic(name) = identifier_type {
298 self.index += 1;
299 if let Some(token) = self.tokens.get(self.index) {
300 let mut arguments = Vec::new();
301 let mut children = Vec::new();
302 let mut setters = Vec::new();
303 let token_range = token.range.clone(); match token.value {
306 TokenValue::StartArgList => {
307 match self.arglist() {
308 Ok(args) => {
309 arguments = args.0;
310 if let Some(token) = self.tokens.get(self.index) {
311 if let TokenValue::StartBlock = token.value {
312 match self.block() {
313 Ok(c) => children = c.0,
314 Err(e) => return Err(e)
315 }
316 }
317 } else {
318 return Err((format!("expected block, found nothing"), token_range))
319 }
320 },
321 Err(err) => return Err(err)
322 }
323 },
324 TokenValue::StartBlock => {
325 match self.block() {
326 Ok(c) => children = c.0,
327 Err(e) => return Err(e)
328 }
329 },
330 _ => return Err((format!("expected the start of an argument list or block, found '{}'", token.to_string()), token.range.clone()))
331 }
332
333 loop {
334 if let Some(token) = self.tokens.get(self.index) {
335 let token_range = token.range.clone();
336 match &token.value {
337 TokenValue::Identifier(_) | TokenValue::EndBlock => break,
338 TokenValue::Setter(name) => {
339 self.index += 1;
340 let name = name.clone();
341
342 match self.arglist() {
343 Ok(args) => {
344 if args.0.len() != 1 {
345 return Err((format!("expected 1 argument, got {}", args.0.len()), args.1));
346 }
347
348 let value = &args.0[0];
349
350 match &value.value {
351 TokenValue::Number(_) | TokenValue::String(_) | TokenValue::Bool(_) => {
352 setters.push(Setter {
353 name: name,
354 value: value.clone(),
355 range: token_range
356 })
357 },
358 _ => return Err((format!("expected Number, String, or Bool, found {}", value.to_string()), value.range.clone()))
359 }
360 },
361 Err(err) => return Err(err)
362 }
363 },
364 _ => {
365 return Err((format!("expected setter, found {}", token.to_string()), token_range));
366 }
367 }
368 }
369 }
370
371 Ok(Statement {
372 value: StatementValue::Object(
373 Object {
374 arguments,
375 name: name.clone(),
376 children,
377 setters
378 }
379 ),
380 range: range.clone()
381 })
382 } else {
383 Err((format!("expected argument list or block, found nothing"), range))
384 }
385 } else {
386 Err((format!("expected generic identifier, found type identifier"), range))
387 }
388 }
389
390 fn parse_statement(&mut self) -> Option<Result<Statement, (String, Range<usize>)>> {
391 if let Some(token) = self.tokens.get(self.index) {
392 match &token.value {
393 TokenValue::Definition(definition) => {
394 let definition = definition.clone();
395 Some(self.definition(definition, token.range.clone()))
396 },
397 TokenValue::Directive(directive) => {
398 let directive = directive.clone();
399 Some(self.directive(directive, token.range.clone()))
400 },
401 TokenValue::Identifier(identifier) => {
402 let identifier = identifier.clone();
403 Some(self.object(identifier, token.range.clone()))
404 },
405 TokenValue::Comment => None,
406 _ => Some(Err(( format!("unexpected {}", token.to_string()), token.range.clone() )))
407 }
408 } else {
409 Some(Err((format!("expected definition, directive, or identifier, found nothing"), self.statements[self.statements.len()-1].range.clone())))
410 }
411 }
412
413 pub fn new(tokens: Vec<Token>, filename: String) -> Parser {
415 return Parser {
416 statements: Vec::new(),
417 index: 0,
418 tokens,
419 filename
420 }
421 }
422
423 pub fn parse(&mut self) -> Result<(), (String, Range<usize>)> {
424 loop {
425 if self.index >= self.tokens.len() {
426 break Ok(())
427 }
428 match self.parse_statement() {
429 Some(result) => {
430 match result {
431 Ok(statement) => {
432 match &statement.value {
433 StatementValue::Definition(_) | StatementValue::Header(_) | StatementValue::Include(_) => self.statements.push(statement),
434 _ => return Err(( format!("found {} on top level. Only object definitions and directives are allowed here.", statement.to_string()), statement.range )),
435 }
436 },
437 Err(err) => return Err(err)
438 }
439 },
440 None => continue
441 }
442 }
443 }
444}