spdl 0.0.1

API for compiling and using SPDL, a language to assist with parsing code into syntax trees.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
/*!
This crate contains an API to compiling and using the SPDL programming language. SPDL (pronounced spiddle) stands for the Structured Parsing Description Language, and is used
to make parsing in a compiler much easier. This crate contains a function to compile SPDL into a parser, which can be used to turn code into syntax trees.

A syntactical instance, in this compiler's terms, is a syntactical structure describing parsing at a given point. This generated SPDL parser contains a root 
syntactical instance for the whole file, along with a set of syntactical instances for variables. Each of these syntactical instances has its own function for 
parsing at a point. 

The SPDLParser structure wraps around a root syntactical instance that parses at the start of the code and is expected to cover the whole of it. It also wraps
an array of all of the variables in the root syntactical instance. The SPDLParser structure contains a get_syntax_tree function which gets the syntax tree of 
input code based on the description of it's root syntactical instance, and returns a result that either contains errors or the output syntax tree.

Each syntactical instance has a certain syntactical instance type, and gives its resulting output of parsing at a point in input code. There are many types of 
syntactical instances currently available for usage in SPDL:

1. `Set(&[SyntacticalInstance])`

The "Set" syntactical instance type contains a set of syntactical instances to parse in order.

2. `ZeroOrMore(&SyntacticalInstance)`

The "ZeroOrMore" syntactical instance type asks the parser to parse a syntactical instance as many times as it can before giving up.

3. `OneOrMore(&SyntacticalInstance)`

Like ZeroOrMore, except for the fact that it requires a minimum of one iteration of successful parsing to succeed.

4. `Either(&[SyntacticalInstance])`

This allows for any one syntactical instances in a set to have parsed successfully at a point. This fails if none in the set are successful.

5. `Not(&SyntacticalInstance)`

The "Not" syntactical instance type disallows a certain syntactical instance to successfully parse at a point.

6. `Regular(&str)`

The "Regular" syntactical instance type parses successfully at a point if the current point starts with the string described in this syntactical instance type.

7. `Search(&str)`

The "Search" syntactical instance type serves as a runtime search for a syntactical instance with a specific name. Any invalid variable name in this will 
be detected at compile-time. This is needed when two or more variables are mutually dependent on each other, and hence can be used for recursion.

8. `Regex(Regex)`

The "Regex" syntactical instance type parses successfully if the current point in the input matches this regex.

9. `Questioned(&str, &SyntacticalInstance)`

This captures the result of parsing a syntactical instance (as in the second field), and parses the result with another syntactical instance (the name of this is in the first field).

An example of this crate's usage, parsing 300,000 print statements within less than a second on some computers, is as follows:

```rust
fn main() {
   let code = r#"
   print "Hello, world!";
   "#.repeat(300_000);

   let spdl_code = r##"
   freeform true
   string = /"[^"]*"/
   printStmt = print #string#;
   seterror printStmt Invalid print statement!
   parse printStmt
   "##;
   let parser = spdl::process_spdl(spdl_code);
   if parser.is_err() {
       let errors = parser.unwrap_err();
       for err in errors {
           println!("{}", err);
       }
       panic!("Failed test!");
   }
   let parser = parser.unwrap();

   let time = std::time::Instant::now();
   parser.get_syntax_tree(Box::leak(Box::new(code.into_boxed_str())), false).unwrap();
   println!("{:?}", time.elapsed());
}
```


The actual syntax of valid SPDL code consists of comments, variable declarations, freeform configurations, custom error-handling configurations, and a single parsing configuration.
SPDL is not a free-form language, except for with line breaks. Every line in SPDL code is trimmed on both ends before processing. Every comment in SPDL is a line 
that starts with a hashtag after being trimmed. Every line in SPDL must start and complete exactly one of these descriptions, or just be completely empty after trimming.

Every line that starts with a hashtag after trimming is a comment and is ignored. Every empty line after trimming is also ignored.

Every variable declaration has this rigid syntax:

`varName = sequence`

The sequence in the declaration can either be empty, or be one of the following syntactical descriptions:

`*sequenceGoesHere*` (This desribes a zero or more statement for a syntactical instance with the ZeroOrMore type)

`+sequenceGoesHere+` (This describes a one or more statement for a syntactical instance with the OneOrMore type)

`|sequenceGoesHere$maybeAnotherHere|` (This describes an either statement for a syntactical instance with the Either type)

`/regexGoesHere/` (This describes a regex statement for a syntactical instance with the Regex type)

`^sequenceGoesHere^` (This desribes a not statement for a syntactical instance with the Not type)

`&variableName&` (This describes a search statement for a syntactical instance with the Search type)

`?parseAs:sequenceGoesHere?` (This describes a parse statement for a syntactical instance with the Questioned type)

`#variableName#` (This includes a previously declared variable's syntax in the variable declaration)

`\punctuationGoesHere` (This describes an escape. No escape is invalid, but if a backslash is not followed by punctuation or a backslash, then it gets interpreted as a regular backslash followed by a regular character)

`regularSyntacticalInstance` (This describes a syntactical instance with the Regular type, consisting of a continous set of one or more escapes or non-punctuation characters)

Punctuation as mentioned above can be any of these characters separated by commas: *, +, |, /, ^. &, #, ?
Punctuation is used to specify the start of a different kind of syntactical instance in the sequence of syntactical instances in a variable declaration. Escapes give a way to remove their meaning.

Every custom error handling configuration in SPDL, which sets up a custom error to throw when parsing a variable fails, has the following syntax:

`seterror varName message`

The parsing configuration for SPDL code describing an SPDL parser tells which variable should be parsed recursively until the end of the input to the parser is reached. The syntax of such is as follows:

`parse varName`

Every freeform configuration in SPDL consists of the "freeform" keyword, followed by a single space, followed by true or false. This is to configure whether or not free-formedness 
is enabled after a certain line. Free-formedness is disabled by default, but has the effect of surrounding every regular syntactical instance in a variable declaration with regexes
to capture optional whitespace.
!*/

use regex::Regex;

#[derive(Clone, Copy, Debug)]
#[allow(missing_docs)]
/// All types of syntactical instances are described within this enum. Refer to the crate root docs and spdl_docs module's docs for more info.
pub enum SyntacticalInstanceKind {
    Questioned(&'static str, &'static SyntacticalInstance),
    ZeroOrMore(&'static SyntacticalInstance),
    OneOrMore(&'static SyntacticalInstance),
    Either(&'static [SyntacticalInstance]),
    Set(&'static [SyntacticalInstance]),
    Not(&'static SyntacticalInstance),
    Regular(&'static str),
    Search(&'static str),
    Regex(&'static Regex)
}

#[derive(Debug)]
enum Section {
    Hashtagged(usize, usize),
    Questioned(usize, usize),
    Starred(usize, usize),
    Regular(usize, usize),
    Plussed(usize, usize),
    Barred(usize, usize),
    Anded(usize, usize),
    Regex(usize, usize),
    Not(usize, usize),
}

trait Leak<T: ?Sized> {
    fn leak(self) -> &'static T; 
}

trait LeakBox<T: ?Sized> {
    fn leak_box(self) -> &'static T; 
}

impl<T: ?Sized> LeakBox<T> for Box<T> {
    fn leak_box(self) -> &'static T {
        Box::leak(self)
    }
}

impl Leak<str> for String {
    fn leak(self) -> &'static str {
        Box::leak(self.into_boxed_str())
    }
}

impl<T: Sized> Leak<[T]> for Vec<T> {
    fn leak(self) -> &'static [T] {
        Box::leak(self.into_boxed_slice())
    }
}

#[derive(Clone, Copy, Debug)]
/// This represents a syntactical instance.
pub struct SyntacticalInstance {
    /// The name of the syntactical instance.
    pub name: &'static str,
    /// The type of this syntactical instance.
    pub kind: SyntacticalInstanceKind,
    /// The error that this syntactical instance gives when it fails to parse, aside from the regular errors for invalid syntax.
    /// An empty string, which is the default value, means that no custom error is given.
    pub error_on_fail: &'static str
}

#[derive(Clone, Copy, Debug)]
/// This represents a SPDL parser.
pub struct SPDLParser {
    /// The root syntactical instance is a tree of syntactical instances that are parsed in order, to accomplish exhaustive parsing of the file.
    pub root: SyntacticalInstance,
    /// This is an array of all variables declared in the parser. This is used for syntactical instances with the type "Search" as a place to search for things in.
    pub vars: &'static [SyntacticalInstance]
}

#[derive(Clone, Copy, Debug)]
/// This represents a syntax tree.
pub struct SyntaxTree {
    /// The name of this branch of the syntax tree.
    pub branch: &'static str,
    /// The raw value of this branch of the syntax tree.
    pub branch_value: &'static str,
    /// An array of all branches that branch off this one in the syntax tree.
    pub branches: &'static [SyntaxTree]
}

#[derive(Clone, Copy, PartialEq)]
/// This represents an error output by a SPDL parser.
pub struct SPDLError {
    /// The value of the error.
    pub value: &'static str,
    /// The line on which the error occurred.
    pub line: usize,
    /// The column on which the error occurred.
    pub column: usize
}

impl std::fmt::Debug for SPDLError {
    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(formatter, "On line {}, column {}: {}", self.line, self.column, self.value)
    }
}

impl SPDLParser {
    /// This is a function that gets a syntax tree for input code based on the description of this parser.
    /// The trace parameter determines whether or not every step of parsing should be traced and printed out.
    pub fn get_syntax_tree(&self, input: &'static str, trace: bool) -> Result<SyntaxTree, Vec<SPDLError>> {
        let mut cpos = 0usize;
        let mut line = 1usize;
        let mut column = 0usize;
        let mut branches = Vec::new();
        let mut last_line_pos = 0usize;
        let mut parsed = SyntaxTree {
            branch: "Root",
            branch_value: input,
            branches: &[]
        };

        while cpos < input.len() - 1 {
            let now_parsed = self.root.parse_on(input, &mut cpos, &self.root.name, &mut line, &mut last_line_pos, &mut column, self, trace);
            if now_parsed.is_ok() {
                branches.push(now_parsed.unwrap());
            } else {
                return now_parsed;
            }
        }

        parsed.branches = branches.leak();
        Ok(parsed)
    }
}

impl SyntacticalInstance  {
    fn parse_on(&self, input: &'static str, cpos: &mut usize, branch: &'static str, line: &mut usize, last_lpos: &mut usize, column: &mut usize, top_level: &SPDLParser, trace: bool) -> Result<SyntaxTree, Vec<SPDLError>> {
        let mut branches = Vec::new();
        let mut errors: Vec<&'static str> = Vec::new();
        let mut positioned_errors: Vec<SPDLError> = Vec::new();
        let mut parsed: SyntaxTree = SyntaxTree {
            branch: branch,
            branch_value: "",
            branches: &[],
        };
        if trace {
            println!("At position {}: {}", cpos, self.name);
        }
        let origlen = errors.len();
        let orig_cpos: usize = *cpos;
        let orig_line: usize = *line;
        let orig_column: usize = *column;
        let mut branch_value = String::new();

        match self.kind {
            SyntacticalInstanceKind::ZeroOrMore(instance) => {
                let mut parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                while parsing.is_ok() {
                    branches.push(parsing.unwrap());
                    parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                }
            },

            SyntacticalInstanceKind::OneOrMore(instance) => {
                let mut parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                if parsing.is_err() {
                    positioned_errors = parsing.unwrap_err();
                } else {
                    while parsing.is_ok() {
                        branches.push(parsing.unwrap());
                        parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                    }
                }
            },

            SyntacticalInstanceKind::Either(instances) => {
                let mut hparsed = false;
                let mut parse_errs: Option<Vec<SPDLError>> = None;
                let mut min_pos = 0usize;
                
                for instance in instances.iter() {
                    let parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                    if parsing.is_ok() {
                        branches.push(parsing.unwrap());
                        hparsed = true;
                        break;
                    } else {
                        let errs = parsing.unwrap_err();
                        let current = errs.iter().max_by_key(|err| *last_lpos + err.column).unwrap().column + *last_lpos;
                        if current >= min_pos {
                            min_pos = current;
                            parse_errs = Some(errs);
                        }
                    }
                }

                if !hparsed {
                    positioned_errors.extend(parse_errs.unwrap().into_iter());
                }
            },

            SyntacticalInstanceKind::Set(instances) => {
                for instance in instances.iter() {
                    let parsing = instance.parse_on(input, cpos, &instance.name, line, last_lpos, column, top_level, trace);
                    if parsing.is_ok() {
                        branches.push(parsing.unwrap());
                    } else {
                        positioned_errors = parsing.unwrap_err();
                        break;
                    }
                }
            },

            SyntacticalInstanceKind::Regular(section) => {
                if input[*cpos..].starts_with(section) {
                    branch_value += section;
                    parsed.branches = Box::new([SyntaxTree {
                        branch: "Raw Syntax",
                        branch_value: section,
                        branches: &[]
                    }]).leak_box();
                    *cpos += section.len();
                } else {
                    errors.push(format!("Expected this: \"{}\"", section).leak());
                }
            },

            SyntacticalInstanceKind::Questioned(top, section) => {
                let res = section.parse_on(input, cpos, &section.name, line, last_lpos, column, top_level, trace);
                if res.is_ok() {
                    let finding = top_level.vars.iter().find(|x| x.name == top);
                    if finding.is_none() {
                        errors.push(format!("The variable {} does not exist in this file!", top).leak())
                    } else {
                        let branch = res.unwrap();
                        let res = SPDLParser {
                            root: finding.unwrap().clone(),
                            vars: &[]
                        }.get_syntax_tree(&branch.branch_value, trace);
                        if res.is_err() {
                            positioned_errors = res.unwrap_err();
                        } else {
                            parsed.branches = Box::new([branch, res.unwrap()]).leak_box();
                        }
                    }
                } else {
                    positioned_errors = res.unwrap_err();
                }
            },

            SyntacticalInstanceKind::Search(name) => {
                let finding = top_level.vars.iter().find(|x| x.name == name);
                if finding.is_none() {
                    panic!("Internal Parser Error: The syntactical instance \"{}\" doesn't exist in the parsing variable, but it was searched for!", name);
                } else {
                    let syntax = finding.unwrap();
                    let res = syntax.parse_on(input, cpos, name, line, last_lpos, column, top_level, trace);
                    if res.is_ok() {
                        parsed.branches = Box::new([res.unwrap()]).leak_box();
                    } else {
                        positioned_errors = res.unwrap_err();
                    }
                }
            },

            SyntacticalInstanceKind::Not(section) => {
                let parsing = section.parse_on(input, cpos, &section.name, line, last_lpos, column, top_level, trace);
                if parsing.is_err() {
                    parsed.branches = Box::new([SyntaxTree {
                        branch: "Not Statement",
                        branch_value: format!("{:#?}", section).leak(),
                        branches: &[]
                    }]).leak_box();
                } else {
                    errors.push(format!("Expected something thats isn't this syntactical instance: {}", section.name).leak());
                }
            },

            SyntacticalInstanceKind::Regex(regex) => {
                let find = regex.find_at(input, *cpos);
                if find.is_none() {
                    errors.push(format!("Expected something that fits this regex: {:?}", regex).leak());
                } else {
                    let finding = find.unwrap().as_str();
                    branch_value += finding;
                    parsed.branches = Box::new([SyntaxTree {
                        branch: "Regex Finding",
                        branch_value: finding.to_string().leak(),
                        branches: &[]
                    }]).leak_box();
                    *cpos += finding.len();
                }
            },
        }

        if parsed.branches.len() == 1 {
            parsed = parsed.branches[0].clone();
            parsed.branch = branch;
        }

        if errors.len() - origlen > 0 || positioned_errors.len() > 0 {
            positioned_errors.extend(errors.into_iter().map(|x| {
                SPDLError {
                    value: x,
                    column: *column,
                    line: *line,
                }
            }));

            *cpos = orig_cpos;
            *line = orig_line;
            *column = orig_column;
            Err(positioned_errors)
        } else {
            if parsed.branches.len() == 0 {
                parsed.branches = branches.leak();
            }
            if parsed.branches.len() != 0 {
                parsed.branch_value = parsed.branches.iter().map(|x| x.branch_value).collect::<String>().leak();
            } else {
                parsed.branch_value = branch_value.leak();
            }
            
            if *cpos < input.len() && input[orig_cpos..*cpos].contains("\n") {
                *last_lpos = *cpos;
                *column = 0;
                *line += 1;
            } else {
                *column = *cpos - orig_cpos;
            }
            Ok(parsed)
        }
    }
}

fn parse_instance(instances: &[SyntacticalInstance], inp: &'static str, name: &'static str, error_on_fail: &'static str, instnames: &'static [&'static str], freeform: bool) -> Result<SyntacticalInstance, &'static str> {
    let punctuation = ['*', '|', '+', '\\', '#', '/', '^', '?', '&'];

    let mut regular: Vec<(usize, usize)> = Vec::new();
    let mut hashtagged: Vec<usize> = Vec::new();
    let mut questioned: Vec<usize> = Vec::new();
    let mut starred: Vec<usize> = Vec::new();
    let mut plussed: Vec<usize> = Vec::new();
    let mut regexed: Vec<usize> = Vec::new();
    let mut notted: Vec<usize> = Vec::new();
    let mut barred: Vec<usize> = Vec::new();
    let mut anded: Vec<usize> = Vec::new();

    let valid_name = |name: &str| name.chars().all(char::is_alphanumeric);
    let unescape = |val: &str| val.replace("\\*", "*").replace("\\/", "/").replace("\\#", "#").replace("\\+", "+")
    .replace("\\?", "?").replace("\\|", "|").replace("\\^", "^").replace("\\&", "&").replace("\\b", "\\");
    let mut current_start = 0usize;
    let mut continuing = false;
    let mut in_section;

    let mut in_question = false;
    let mut in_hashtag = false;
    let mut in_plussed = false;
    let mut in_starred = false;
    let mut in_regged = false;
    let mut in_barred = false;
    let mut in_anded = false;
    let mut in_not = false;

    for (n, x) in inp.chars().enumerate() {
        if continuing {
            continuing = false;
            continue;
        }

        if punctuation.contains(&x) {
            in_section = in_hashtag || in_plussed || in_starred || in_regged || in_barred || in_not || in_question || in_anded;
            if current_start < n && !in_section {
                regular.push((current_start, n));
            }
            current_start = n + 1;
            if x != '\\' {
                let last = n;
                match x {
                    '#' => {
                        if in_hashtag || !in_section {
                            hashtagged.push(last);
                            in_hashtag = !in_hashtag;
                        }
                    },
                    '?' => {
                        if in_question && !in_section {
                            in_question = !in_question;
                            questioned.push(last);
                        }
                    },
                    '&' => {
                        if in_anded || !in_section {
                            anded.push(last);
                            in_anded = !in_anded;
                        }
                    },
                    '+' => {
                        if in_plussed || !in_section {
                            plussed.push(last);
                            in_plussed = !in_plussed;
                        }
                    },
                    '/' => {
                        if in_regged || !in_section {
                            regexed.push(last);
                            in_regged = !in_regged;
                        }
                    },
                    '*' => {
                        if in_starred || !in_section {
                            starred.push(last);
                            in_starred = !in_starred;
                        }
                    },
                    '|' => {
                        if in_barred || !in_section {
                            barred.push(last);
                            in_barred = !in_barred;
                        }
                    },
                    '^' => {
                        if in_not || !in_section {
                            notted.push(last);
                            in_not = !in_not;
                        }
                    },
                    _ => {
                        unreachable!();
                    }
                }
            } else if n == inp.len() - 1 {
                return Err("Invalid escape!");
            } else {
                continuing = true;
            }
        } else if n == inp.len() - 1 && current_start != n + 1 {
            regular.push((current_start, n + 1));
        }
    }

    let mut sections = Vec::new();

    if starred.len() % 2 != 0 {
        return Err("Unclosed zero-or-more statement!");
    }
    if plussed.len() % 2 != 0 {
        return Err("Unclosed one-or-more statement!");
    }
    if barred.len() % 2 != 0 {
        return Err("Unclosed either statement!");
    }
    if regexed.len() % 2 != 0 {
        return Err("Unclosed regex!");
    }
    if anded.len() % 2 != 0 {
        return Err("Unclosed search statement!");
    }
    if hashtagged.len() % 2 != 0 {
        return Err("Unclosed variable inclusion!");
    }
    if questioned.len() % 2 != 0 {
        return Err("Unclosed parse statement!");
    }
    if notted.len() % 2 != 0 {
        return Err("Unclosed not statement!");
    }

    let mut set: Vec<SyntacticalInstance> = Vec::new();

    if hashtagged.len() != 0 {
        for n in (0..hashtagged.len() - 1).step_by(2) {
            let start = hashtagged[n];
            let end = hashtagged[n + 1];
    
            sections.push(Section::Hashtagged(start + 1, end));
        }
    }

    if questioned.len() != 0 {
        for n in (0..questioned.len() - 1).step_by(2) {
            let start = questioned[n];
            let end = questioned[n + 1];
    
            sections.push(Section::Questioned(start + 1, end));
        }
    }

    if regexed.len() != 0 {
        for n in (0..regexed.len() - 1).step_by(2) {
            let start = regexed[n];
            let end = regexed[n + 1];
    
            sections.push(Section::Regex(start + 1, end));
        }
    }

    if starred.len() != 0 {
        for n in (0..starred.len() - 1).step_by(2) {
            let start = starred[n];
            let end = starred[n + 1];
    
            sections.push(Section::Starred(start + 1, end));
        }
    }
    
    if plussed.len() != 0 {
        for n in (0..plussed.len() - 1).step_by(2) {
            let start = plussed[n];
            let end = plussed[n + 1];
    
            sections.push(Section::Plussed(start + 1, end));
        }
    }

    if barred.len() != 0 {
        for n in (0..barred.len() - 1).step_by(2) {
            let start = barred[n];
            let end = barred[n + 1];
    
            sections.push(Section::Barred(start + 1, end));
        }    
    }

    if anded.len() != 0 {
        for n in (0..anded.len() - 1).step_by(2) {
            let start = anded[n];
            let end = anded[n + 1];
    
            sections.push(Section::Anded(start + 1, end));
        }    
    }

    if notted.len() != 0 {
        for n in (0..notted.len() - 1).step_by(2) {
            let start = notted[n];
            let end = notted[n + 1];
    
            sections.push(Section::Not(start + 1, end));
        }
    }

    if regular.len() != 0 {
        for r in regular.iter() {
            sections.push(Section::Regular(r.0, r.1));
        }
    }

    sections.sort_by(|a, b| {
        let measure = |x: &Section| -> usize {
            match x {
                Section::Hashtagged(x, _) | Section::Questioned(x, _) | Section::Regex(x, _) | Section::Anded(x, _) | 
                Section::Starred(x, _) | Section::Plussed(x, _) | Section::Barred(x, _) | Section::Regular(x, _) | 
                Section::Not(x, _) => {
                    *x
                }
            }
        };
        measure(a).cmp(&measure(b))
    });

    let optional_whitespace: SyntacticalInstance = SyntacticalInstance {
        name: "Freeform Whitespace",
        error_on_fail: "",
        kind: SyntacticalInstanceKind::Regex(Box::new(Regex::new(r"\s*").unwrap()).leak_box())
    };

    for sect in sections.iter() {
        match *sect {
            Section::Starred(start, end) => {
                let parsed = parse_instance(instances, &inp[start..end], name, "", instnames, freeform);
                if parsed.is_err() {
                    return parsed;
                } else {
                    let mut parsed = parsed.unwrap();
                    parsed.kind = SyntacticalInstanceKind::ZeroOrMore(Box::new(parsed.clone()).leak_box());
                    parsed.name = "Zero or More Statement";
                    parsed.error_on_fail = "";
                    set.push(parsed);
                }
            },

            Section::Plussed(start, end) => {
                let parsed = parse_instance(instances, &inp[start..end], name, "", instnames, freeform);
                if parsed.is_err() {
                    return parsed;
                } else {
                    let mut parsed = parsed.unwrap();
                    parsed.kind = SyntacticalInstanceKind::OneOrMore(Box::new(parsed.clone()).leak_box());
                    parsed.name = "One or More Statement";
                    parsed.error_on_fail = "";
                    set.push(parsed);
                }
            },

            Section::Barred(start, end) => {
                let section = &inp[start..end];
                let split = section.split("$");

                if split.clone().count() < 2 {
                    return Err("Invalid either statement! There must be a dollar sign splitting it.");
                }

                let mut parsed = Vec::new();
                for (n, slice) in split.enumerate() {
                    parsed.push(parse_instance(instances, slice, format!("Argument #{} of Either Statement", n).leak(), "", instnames, freeform));
                }
                let err = parsed.iter().find(|x| x.is_err());

                if err.is_some() {
                    return Err(err.as_ref().unwrap().as_ref().unwrap_err());
                } else {
                    set.push(SyntacticalInstance {
                        name: "Either Statement",
                        error_on_fail: "",
                        kind: SyntacticalInstanceKind::Either(
                            parsed.into_iter().map(|x| x.unwrap()).collect::<Vec<SyntacticalInstance>>().leak()
                        )
                    });
                }
            },

            Section::Regex(start, end) => {
                let section = &(inp[start..end].replace("\\/", "/"));
                let regex = Regex::new(&section);
                if regex.is_err() {
                    return Err(format!("Invalid regex due to error \"{}\": {}", regex.unwrap_err(), section).leak());
                } else {
                    let regex = regex.unwrap();
                    set.push(SyntacticalInstance {
                        name: format!("Regex Statement: {:?}", regex).leak(),
                        error_on_fail: "",
                        kind: SyntacticalInstanceKind::Regex(Box::new(regex).leak_box())
                    });
                }
            },

            Section::Hashtagged(start, end) => {
                let section = &inp[start..end];
                if !valid_name(&section) {
                    return Err(format!("Invalid variable name in variable inclusion: \"{}\"", section).leak());
                }

                let finding = instances.iter().position(|x| x.name == section);
                if finding.is_none() {
                    return Err(format!("No such valid variable has been declared yet in variable inclusion: {}", section).leak());
                }

                set.push(instances[finding.unwrap()].clone());
            },

            Section::Questioned(start, end) => {
                let section = &inp[start..end];
                let split = section.split(":").collect::<Vec<&str>>();
                if split.len() != 2 {
                    return Err(format!("Invalid parse statement, expected a colon to split it: {}", section).leak());
                }
                let res = parse_instance(instances, split[1], "Not Statement Innards", "", instnames, freeform);
                if res.is_err() {
                    return res;
                }
                set.push(SyntacticalInstance {
                    name: format!("Raw Syntax for Not Statement: {}", &inp[start..end]).leak(),
                    error_on_fail: "",
                    kind: SyntacticalInstanceKind::Questioned(split[0], Box::new(res.unwrap()).leak_box())
                });
            },

            Section::Anded(start, end) => {
                let section = &inp[start..end];
                if !instnames.contains(&section) {
                    return Err(format!("Invalid search statement: The variable \"{}\" is never declared!", section).leak());
                }
                set.push(SyntacticalInstance {
                    name: format!("Search Statement for \"{}\"", section).leak(),
                    error_on_fail: "",
                    kind: SyntacticalInstanceKind::Search(section)
                });
            },

            Section::Regular(start, end) => {
                let section = &inp[start..end];
                if freeform && !section.chars().all(|x| x.is_whitespace()) {
                    set.push(optional_whitespace.clone());
                }
                set.push(SyntacticalInstance {
                    name: format!("Raw Syntax: {}", &inp[start..end]).leak(),
                    error_on_fail: "",
                    kind: SyntacticalInstanceKind::Regular(unescape(section).leak())
                });
                if freeform {
                    set.push(optional_whitespace.clone());
                }
            },

            Section::Not(start, end) => {
                let res = parse_instance(instances, &inp[start..end], "Not Statement Innards", "", instnames, freeform);
                if res.is_err() {
                    return res;
                }
                set.push(SyntacticalInstance {
                    name: format!("Raw Syntax for Not Statement: {}", &inp[start..end]).leak(),
                    error_on_fail: "",
                    kind: SyntacticalInstanceKind::Not(Box::new(res.unwrap()).leak_box())
                });
            }
        }
    }

    if set.len() == 1 {
        set[0].name = name;
        set[0].error_on_fail = error_on_fail;
        Ok(set[0].clone())
    } else {
        Ok(SyntacticalInstance {
            name: name,
            error_on_fail: error_on_fail,
            kind: SyntacticalInstanceKind::Set(set.leak())
        })
    }
}

/// This turns SPDL code into an SPDL parser. If that fails, it returns an Err value containing a vector of errors.
pub fn process_spdl(spdl: &str) -> Result<SPDLParser, Vec<String>> {
    let mut errors: Vec<String> = Vec::new();
    let mut instances: Vec<SyntacticalInstance> = Vec::new();
    let mut parsing: Option<SyntacticalInstance> = None;
    let mut parsed = false;

    let mut instnames: Vec<&'static str> = Vec::new();
    for line in spdl.lines() {
        let line = line.trim();
        let split: Vec<&str> = line.split_whitespace().collect();
        if split.len() == 0 {
            continue;
        }
        match split[0] {
            "seterror" | "parse" | "freeform" => {},
            x => {
                instnames.push(Box::leak(x.to_string().into_boxed_str()));
            }
        }
    }

    let instnames: &'static [&'static str] = Box::leak(instnames.into_boxed_slice());
    let mut freeform = false;

    for (n, line) in spdl.lines().enumerate() {
        let line_trimmed = line.trim();
        let mut line = String::new();
        for character in line_trimmed.chars() {
            if character.is_whitespace() {
                line.push(' ');
            } else {
                line.push(character);
            }
        }
        let line: &'static str = line.leak();

        let mut line_err = |err: &str| errors.push(format!("Error on line {}: {}", n + 1, err));
        let valid_name = |name: &str| name.chars().all(|x| x.is_ascii_alphabetic());

        let split: Vec<&str> = line.split_whitespace().collect();
        let mut inds: Vec<usize> = Vec::new();
        let mut counter = 0usize;
        for x in split.iter() {
            counter += x.len() + 1;
            inds.push(counter);
        }

        if split.len() == 0 || line.starts_with("#") {
            continue;
        }

        match split[0] {
            "seterror" => {
                if split.len() < 2 {
                    line_err("Expected variable name after seterror keyword, got nothing!");
                    continue;
                }

                let name = split[1];
                if !valid_name(name) {
                    line_err("Invalid variable name for seterror!");
                    continue;
                }

                let finding = instances.iter_mut().find(|x| x.name == name);
                if finding.is_none() {
                    line_err(&format!("No such valid variable has been declared yet in seterror command: {}", name));
                    continue;
                }

                let mut finding: &mut SyntacticalInstance = finding.unwrap();
                finding.error_on_fail = if split.len() > 2 {
                    line[inds[1]..].to_string().leak()
                } else {
                    format!("Expected syntactical structure \"{}\"!", finding.name).leak()
                };
            },

            "parse" => {
                if split.len() < 2 {
                    line_err("Nothing specified after parse keyword!");
                    continue;
                }

                let res = instances.iter().find(|x| x.name == line[inds[0]..].to_string());
                if res.is_none() {
                    line_err("Expected a variable after parse keyword!");
                    continue;
                }
                parsed = true;
                parsing = Some(res.unwrap().clone());
            },

            "freeform" => {
                if split.len() != 2 {
                    line_err("Expected a boolean and nothing else after the freeform keyword!");
                }
                match split[1] {
                    "true" => {
                        freeform = true;
                    },
                    "false" => {
                        freeform = false;
                    },
                    _ => line_err("Invalid boolean after freeform keyword!")
                }
            },

            x => {
                if split.len() < 3 {
                    line_err("Too short of a variable declaration!");
                    continue;
                }

                if !valid_name(x) {
                    line_err(&format!("Invalid variable name for declaration: {}", x));
                    continue;
                }

                if split[1] != "=" {
                    line_err("Expected \"=\" after variable name in declaration with spaces around it.");
                    continue;
                }

                let res = parse_instance(
                    &instances, &line[inds[1]..], x, "", instnames, freeform
                );
                if res.is_err() {
                    line_err(&res.unwrap_err());
                    continue;
                }
                let mut res = res.unwrap();
                res.name = x;
                instances.push(res);
            }
        }
    }

    if !parsed {
        errors.push("Fatal Error: Nothing specified for parsing!".to_string());
    }
    
    if errors.len() > 0 {
        Err(errors)
    } else {
        Ok(SPDLParser {
            root: parsing.unwrap(),
            vars: instances.leak()
        })
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn printing_language() {
        let code = r#"
        print "Hello, world!";
        "#.repeat(300_000);

        let spdl = r##"
        freeform true
        string = /"[^"]*"/
        printStmt = print #string#;
        seterror printStmt Invalid print statement!
        parse printStmt
        "##;
        let parser = crate::process_spdl(spdl);
        if parser.is_err() {
            let errors = parser.unwrap_err();
            for err in errors {
                println!("{}", err);
            }
            panic!("Failed test!");
        }
        let parser = parser.unwrap();

        let time = std::time::Instant::now();
        parser.get_syntax_tree(Box::leak(Box::new(code.into_boxed_str())), false).unwrap();
        println!("{:?}", time.elapsed());
    }
}