gll/
grammar.rs

1use ordermap::{orderset, OrderMap, OrderSet};
2use std::collections::hash_map::Entry;
3use std::collections::HashMap;
4use std::fmt;
5use std::hash::Hash;
6use std::iter;
7use std::ops::{Add, BitAnd, BitOr, Deref};
8
9// HACK(eddyb) newtype to avoid needing `arbitrary_self_types`
10#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct Rc<T>(::std::rc::Rc<T>);
12
13impl<T> Rc<T> {
14    pub fn new(x: T) -> Self {
15        Rc(::std::rc::Rc::new(x))
16    }
17}
18
19impl<T> Clone for Rc<T> {
20    fn clone(&self) -> Self {
21        Rc(self.0.clone())
22    }
23}
24
25impl<T> Deref for Rc<T> {
26    type Target = T;
27    fn deref(&self) -> &T {
28        &self.0
29    }
30}
31
32impl<T: fmt::Debug> fmt::Debug for Rc<T> {
33    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34        self.0.fmt(f)
35    }
36}
37
38pub struct Grammar<Pat> {
39    pub(crate) rules: OrderMap<String, RuleWithNamedFields<Pat>>,
40}
41
42impl<Pat> Grammar<Pat> {
43    pub fn new() -> Self {
44        Grammar {
45            rules: OrderMap::new(),
46        }
47    }
48    pub fn define(&mut self, name: &str, rule: RuleWithNamedFields<Pat>) {
49        self.rules.insert(name.to_string(), rule);
50    }
51    pub fn extend(&mut self, other: Self) {
52        self.rules.extend(other.rules);
53    }
54    pub fn insert_whitespace(self, whitespace: RuleWithNamedFields<Pat>) -> Self
55    where
56        Pat: Clone,
57    {
58        assert!(whitespace.fields.is_empty());
59
60        struct WhitespaceInserter<Pat> {
61            whitespace: RuleWithNamedFields<Pat>,
62        }
63
64        impl<Pat: Clone> Folder<Pat> for WhitespaceInserter<Pat> {
65            // FIXME(eddyb) this will insert too many whitespace rules,
66            // e.g. `A B? C` becomes `A WS B? WS C`, which when `B` is
67            // missing, is `A WS WS C`. Even worse, `A? B` ends up as
68            // `A? WS B`, which has an incorrect leading whitespace.
69            fn fold_concat(
70                &mut self,
71                left: RuleWithNamedFields<Pat>,
72                right: RuleWithNamedFields<Pat>,
73            ) -> RuleWithNamedFields<Pat> {
74                left.fold(self) + self.whitespace.clone() + right.fold(self)
75            }
76            fn fold_repeat_many(
77                &mut self,
78                elem: RuleWithNamedFields<Pat>,
79                sep: Option<RuleWithNamedFields<Pat>>,
80            ) -> RuleWithNamedFields<Pat> {
81                elem.fold(self).repeat_many(Some(
82                    sep.map_or_else(empty, |sep| self.whitespace.clone() + sep.fold(self))
83                        + self.whitespace.clone(),
84                ))
85            }
86            fn fold_repeat_more(
87                &mut self,
88                elem: RuleWithNamedFields<Pat>,
89                sep: Option<RuleWithNamedFields<Pat>>,
90            ) -> RuleWithNamedFields<Pat> {
91                elem.fold(self).repeat_more(Some(
92                    sep.map_or_else(empty, |sep| self.whitespace.clone() + sep.fold(self))
93                        + self.whitespace.clone(),
94                ))
95            }
96        }
97
98        let mut inserter = WhitespaceInserter { whitespace };
99        Grammar {
100            rules: self
101                .rules
102                .into_iter()
103                .map(|(name, rule)| (name, rule.fold(&mut inserter)))
104                .collect(),
105        }
106    }
107}
108
109#[derive(Clone)]
110pub struct RuleWithNamedFields<Pat> {
111    pub(crate) rule: Rc<Rule<Pat>>,
112    pub(crate) fields: OrderMap<String, OrderSet<Vec<usize>>>,
113}
114
115pub fn empty<Pat>() -> RuleWithNamedFields<Pat> {
116    RuleWithNamedFields {
117        rule: Rc::new(Rule::Empty),
118        fields: OrderMap::new(),
119    }
120}
121pub fn eat<Pat>(pat: impl Into<Pat>) -> RuleWithNamedFields<Pat> {
122    RuleWithNamedFields {
123        rule: Rc::new(Rule::Eat(pat.into())),
124        fields: OrderMap::new(),
125    }
126}
127pub fn negative_lookahead<Pat>(pat: impl Into<Pat>) -> RuleWithNamedFields<Pat> {
128    RuleWithNamedFields {
129        rule: Rc::new(Rule::NegativeLookahead(pat.into())),
130        fields: OrderMap::new(),
131    }
132}
133pub fn call<Pat>(name: &str) -> RuleWithNamedFields<Pat> {
134    RuleWithNamedFields {
135        rule: Rc::new(Rule::Call(name.to_string())),
136        fields: OrderMap::new(),
137    }
138}
139
140impl<Pat> RuleWithNamedFields<Pat> {
141    pub fn field(mut self, name: &str) -> Self {
142        let path = match &*self.rule {
143            Rule::RepeatMany(rule, _) | Rule::RepeatMore(rule, _) => match **rule {
144                Rule::Eat(_) | Rule::Call(_) => vec![],
145                _ => unimplemented!(),
146            },
147            Rule::Opt(_) => vec![0],
148            _ => vec![],
149        };
150        self.fields.insert(name.to_string(), orderset![path]);
151        self
152    }
153    pub fn opt(mut self) -> Self {
154        self.fields = self
155            .fields
156            .into_iter()
157            .map(|(name, paths)| {
158                (
159                    name,
160                    paths
161                        .into_iter()
162                        .map(|mut path| {
163                            path.insert(0, 0);
164                            path
165                        })
166                        .collect(),
167                )
168            })
169            .collect();
170        self.rule = Rc::new(Rule::Opt(self.rule));
171        self
172    }
173    pub fn repeat_many(mut self, sep: Option<Self>) -> Self {
174        self.fields = self
175            .fields
176            .into_iter()
177            .map(|(name, paths)| {
178                (
179                    name,
180                    paths
181                        .into_iter()
182                        .map(|mut path| {
183                            path.insert(0, 0);
184                            path
185                        })
186                        .collect(),
187                )
188            })
189            .collect();
190        if let Some(sep) = &sep {
191            assert!(sep.fields.is_empty());
192        }
193        self.rule = Rc::new(Rule::RepeatMany(self.rule, sep.map(|sep| sep.rule)));
194        self
195    }
196    pub fn repeat_more(mut self, sep: Option<Self>) -> Self {
197        self.fields = self
198            .fields
199            .into_iter()
200            .map(|(name, paths)| {
201                (
202                    name,
203                    paths
204                        .into_iter()
205                        .map(|mut path| {
206                            path.insert(0, 0);
207                            path
208                        })
209                        .collect(),
210                )
211            })
212            .collect();
213        if let Some(sep) = &sep {
214            assert!(sep.fields.is_empty());
215        }
216        self.rule = Rc::new(Rule::RepeatMore(self.rule, sep.map(|sep| sep.rule)));
217        self
218    }
219}
220
221impl<Pat> Add for RuleWithNamedFields<Pat> {
222    type Output = Self;
223
224    fn add(mut self, other: Self) -> Self {
225        match (&*self.rule, &*other.rule) {
226            (Rule::Empty, _) if self.fields.is_empty() => return other,
227            (_, Rule::Empty) if other.fields.is_empty() => return self,
228            _ => {}
229        }
230
231        self.fields = self
232            .fields
233            .into_iter()
234            .map(|(name, paths)| {
235                (
236                    name,
237                    paths
238                        .into_iter()
239                        .map(|mut path| {
240                            path.insert(0, 0);
241                            path
242                        })
243                        .collect(),
244                )
245            })
246            .collect();
247        for (name, paths) in other.fields {
248            assert!(!self.fields.contains_key(&name), "duplicate field {}", name);
249            self.fields.insert(
250                name,
251                paths
252                    .into_iter()
253                    .map(|mut path| {
254                        path.insert(0, 1);
255                        path
256                    })
257                    .collect(),
258            );
259        }
260        self.rule = Rc::new(Rule::Concat([self.rule, other.rule]));
261        self
262    }
263}
264
265impl<Pat> BitOr for RuleWithNamedFields<Pat> {
266    type Output = Self;
267
268    fn bitor(self, other: Self) -> Self {
269        let (old_rules, this, mut fields) = match &*self.rule {
270            Rule::Or(rules) => (&rules[..], None, self.fields),
271            _ => (
272                &[][..],
273                // HACK(eddyb) replace with `Some(self)` post-NLL
274                Some(Self {
275                    rule: self.rule.clone(),
276                    fields: self.fields,
277                }),
278                OrderMap::new(),
279            ),
280        };
281
282        // HACK(eddyb) remove awkward scope post-NLL
283        let rules = {
284            let new_rules =
285                this.into_iter()
286                    .chain(iter::once(other))
287                    .enumerate()
288                    .map(|(i, rule)| {
289                        for (name, paths) in rule.fields {
290                            fields.entry(name).or_insert_with(OrderSet::new).extend(
291                                paths.into_iter().map(|mut path| {
292                                    path.insert(0, old_rules.len() + i);
293                                    path
294                                }),
295                            );
296                        }
297
298                        rule.rule
299                    });
300            old_rules.iter().cloned().chain(new_rules).collect()
301        };
302
303        RuleWithNamedFields {
304            rule: Rc::new(Rule::Or(rules)),
305            fields,
306        }
307    }
308}
309
310#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
311pub enum Rule<Pat> {
312    Empty,
313    Eat(Pat),
314    NegativeLookahead(Pat),
315    Call(String),
316
317    Concat([Rc<Rule<Pat>>; 2]),
318    Or(Vec<Rc<Rule<Pat>>>),
319
320    Opt(Rc<Rule<Pat>>),
321    RepeatMany(Rc<Rule<Pat>>, Option<Rc<Rule<Pat>>>),
322    RepeatMore(Rc<Rule<Pat>>, Option<Rc<Rule<Pat>>>),
323}
324
325impl<Pat> Rule<Pat> {
326    pub(crate) fn field_pathset_is_refutable(&self, paths: &OrderSet<Vec<usize>>) -> bool {
327        if paths.len() > 1 {
328            true
329        } else {
330            self.field_is_refutable(paths.get_index(0).unwrap())
331        }
332    }
333    pub(crate) fn field_is_refutable(&self, path: &[usize]) -> bool {
334        match self {
335            Rule::Empty
336            | Rule::Eat(_)
337            | Rule::NegativeLookahead(_)
338            | Rule::Call(_)
339            | Rule::RepeatMany(..)
340            | Rule::RepeatMore(..) => false,
341            Rule::Concat(rules) => rules[path[0]].field_is_refutable(&path[1..]),
342            Rule::Or(..) | Rule::Opt(_) => true,
343        }
344    }
345}
346
347impl<Pat: Ord + Hash + MatchesEmpty> Rc<Rule<Pat>> {
348    fn can_be_empty(
349        &self,
350        cache: &mut HashMap<Self, MaybeKnown<bool>>,
351        grammar: &Grammar<Pat>,
352    ) -> MaybeKnown<bool> {
353        match cache.entry(self.clone()) {
354            Entry::Occupied(entry) => return *entry.get(),
355            Entry::Vacant(entry) => {
356                entry.insert(MaybeKnown::Unknown);
357            }
358        }
359        let r = match &**self {
360            Rule::Empty | Rule::NegativeLookahead(_) | Rule::Opt(_) | Rule::RepeatMany(..) => {
361                MaybeKnown::Known(true)
362            }
363            Rule::Eat(pat) => pat.matches_empty(),
364            Rule::Call(rule) => grammar.rules[rule].rule.can_be_empty(cache, grammar),
365            Rule::Concat([left, right]) => {
366                left.can_be_empty(cache, grammar) & right.can_be_empty(cache, grammar)
367            }
368            Rule::Or(rules) => rules.iter().fold(MaybeKnown::Known(false), |prev, rule| {
369                prev | rule.can_be_empty(cache, grammar)
370            }),
371            Rule::RepeatMore(elem, _) => elem.can_be_empty(cache, grammar),
372        };
373        match r {
374            MaybeKnown::Known(_) => *cache.get_mut(self).unwrap() = r,
375            MaybeKnown::Unknown => {
376                cache.remove(self);
377            }
378        }
379        r
380    }
381
382    fn check_non_empty_opt(
383        &self,
384        cache: &mut HashMap<Self, MaybeKnown<bool>>,
385        grammar: &Grammar<Pat>,
386    ) {
387        match &**self {
388            Rule::Empty | Rule::Eat(_) | Rule::NegativeLookahead(_) | Rule::Call(_) => {}
389            Rule::Concat([left, right]) => {
390                left.check_non_empty_opt(cache, grammar);
391                right.check_non_empty_opt(cache, grammar);
392            }
393            Rule::Or(rules) => {
394                for rule in rules {
395                    rule.check_non_empty_opt(cache, grammar);
396                }
397            }
398            Rule::Opt(rule) => {
399                assert_eq!(rule.can_be_empty(cache, grammar), MaybeKnown::Known(false));
400                rule.check_non_empty_opt(cache, grammar)
401            }
402            Rule::RepeatMany(elem, sep) | Rule::RepeatMore(elem, sep) => {
403                assert_eq!(elem.can_be_empty(cache, grammar), MaybeKnown::Known(false));
404                elem.check_non_empty_opt(cache, grammar);
405                if let Some(sep) = sep {
406                    sep.check_non_empty_opt(cache, grammar);
407                }
408            }
409        }
410    }
411
412    fn check_call_names(&self, grammar: &Grammar<Pat>) {
413        match &**self {
414            Rule::Empty | Rule::Eat(_) | Rule::NegativeLookahead(_) => {}
415            Rule::Call(rule) => {
416                assert!(grammar.rules.contains_key(rule), "no rule named `{}`", rule);
417            }
418            Rule::Concat([left, right]) => {
419                left.check_call_names(grammar);
420                right.check_call_names(grammar);
421            }
422            Rule::Or(rules) => {
423                for rule in rules {
424                    rule.check_call_names(grammar);
425                }
426            }
427            Rule::Opt(rule) => rule.check_call_names(grammar),
428            Rule::RepeatMany(elem, sep) | Rule::RepeatMore(elem, sep) => {
429                elem.check_call_names(grammar);
430                if let Some(sep) = sep {
431                    sep.check_call_names(grammar);
432                }
433            }
434        }
435    }
436}
437
438#[derive(Copy, Clone, Debug, PartialEq, Eq)]
439pub enum MaybeKnown<T> {
440    Known(T),
441    Unknown,
442}
443
444impl BitOr for MaybeKnown<bool> {
445    type Output = Self;
446
447    fn bitor(self, rhs: Self) -> Self {
448        match (self, rhs) {
449            (MaybeKnown::Known(true), _) | (_, MaybeKnown::Known(true)) => MaybeKnown::Known(true),
450            (MaybeKnown::Known(false), x) | (x, MaybeKnown::Known(false)) => x,
451            (MaybeKnown::Unknown, MaybeKnown::Unknown) => MaybeKnown::Unknown,
452        }
453    }
454}
455
456impl BitAnd for MaybeKnown<bool> {
457    type Output = Self;
458
459    fn bitand(self, rhs: Self) -> Self {
460        match (self, rhs) {
461            (MaybeKnown::Known(false), _) | (_, MaybeKnown::Known(false)) => {
462                MaybeKnown::Known(false)
463            }
464            (MaybeKnown::Known(true), x) | (x, MaybeKnown::Known(true)) => x,
465            (MaybeKnown::Unknown, MaybeKnown::Unknown) => MaybeKnown::Unknown,
466        }
467    }
468}
469
470pub trait MatchesEmpty {
471    fn matches_empty(&self) -> MaybeKnown<bool>;
472}
473
474impl<Pat: Ord + Hash + MatchesEmpty> Grammar<Pat> {
475    pub(crate) fn check(&self) {
476        for rule in self.rules.values() {
477            rule.rule.check_call_names(self);
478        }
479
480        let mut can_be_empty_cache = HashMap::new();
481        for rule in self.rules.values() {
482            rule.rule.check_non_empty_opt(&mut can_be_empty_cache, self);
483        }
484    }
485}
486
487pub trait Folder<Pat>: Sized {
488    fn fold_leaf(&mut self, rule: RuleWithNamedFields<Pat>) -> RuleWithNamedFields<Pat> {
489        rule
490    }
491    fn fold_concat(
492        &mut self,
493        left: RuleWithNamedFields<Pat>,
494        right: RuleWithNamedFields<Pat>,
495    ) -> RuleWithNamedFields<Pat> {
496        left.fold(self) + right.fold(self)
497    }
498    fn fold_or(
499        &mut self,
500        rules: impl Iterator<Item = RuleWithNamedFields<Pat>>,
501    ) -> RuleWithNamedFields<Pat> {
502        let mut rules = rules.map(|rule| rule.fold(self));
503        let first = rules.next().unwrap();
504        rules.fold(first, |or, rule| or | rule)
505    }
506    fn fold_opt(&mut self, rule: RuleWithNamedFields<Pat>) -> RuleWithNamedFields<Pat> {
507        rule.fold(self).opt()
508    }
509    fn fold_repeat_many(
510        &mut self,
511        elem: RuleWithNamedFields<Pat>,
512        sep: Option<RuleWithNamedFields<Pat>>,
513    ) -> RuleWithNamedFields<Pat> {
514        elem.fold(self).repeat_many(sep.map(|sep| sep.fold(self)))
515    }
516    fn fold_repeat_more(
517        &mut self,
518        elem: RuleWithNamedFields<Pat>,
519        sep: Option<RuleWithNamedFields<Pat>>,
520    ) -> RuleWithNamedFields<Pat> {
521        elem.fold(self).repeat_more(sep.map(|sep| sep.fold(self)))
522    }
523}
524
525impl<Pat> RuleWithNamedFields<Pat> {
526    // HACK(eddyb) this is pretty expensive, find a better way
527    fn filter_fields<'a>(
528        &'a self,
529        field: Option<usize>,
530    ) -> impl Iterator<Item = (String, OrderSet<Vec<usize>>)> + 'a {
531        self.fields.iter().filter_map(move |(name, paths)| {
532            let paths: OrderSet<_> = paths
533                .iter()
534                .filter_map(move |path| {
535                    if path.first().cloned() == field {
536                        Some(path.get(1..).unwrap_or(&[]).to_vec())
537                    } else {
538                        None
539                    }
540                })
541                .collect();
542            if !paths.is_empty() {
543                Some((name.clone(), paths))
544            } else {
545                None
546            }
547        })
548    }
549
550    pub fn fold(self, folder: &mut impl Folder<Pat>) -> Self {
551        // HACK(eddyb) remove separate pattern-matching post-NLL
552        let is_leaf = match &*self.rule {
553            Rule::Empty | Rule::Eat(_) | Rule::NegativeLookahead(_) | Rule::Call(_) => true,
554            _ => false,
555        };
556        if is_leaf {
557            return folder.fold_leaf(self);
558        }
559        let field_rule = |rule: &Rc<Rule<Pat>>, i| RuleWithNamedFields {
560            rule: rule.clone(),
561            fields: self.filter_fields(Some(i)).collect(),
562        };
563        let mut rule = match &*self.rule {
564            Rule::Empty | Rule::Eat(_) | Rule::NegativeLookahead(_) | Rule::Call(_) => {
565                unreachable!()
566            }
567            Rule::Concat([left, right]) => {
568                folder.fold_concat(field_rule(left, 0), field_rule(right, 1))
569            }
570            Rule::Or(rules) => folder.fold_or(
571                rules
572                    .iter()
573                    .enumerate()
574                    .map(|(i, rule)| field_rule(rule, i)),
575            ),
576            Rule::Opt(rule) => folder.fold_opt(field_rule(rule, 0)),
577            Rule::RepeatMany(elem, sep) => folder.fold_repeat_many(
578                field_rule(elem, 0),
579                sep.as_ref().map(|sep| field_rule(sep, 1)),
580            ),
581            Rule::RepeatMore(elem, sep) => folder.fold_repeat_more(
582                field_rule(elem, 0),
583                sep.as_ref().map(|sep| field_rule(sep, 1)),
584            ),
585        };
586        rule.fields.extend(self.filter_fields(None));
587        rule
588    }
589}
590
591// HACK(eddyb) moved here so bootstrap (build.rs) doesn't need
592// to include the runtime. Should maybe be in a different module?
593
594#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
595pub enum ParseNodeShape<P> {
596    Opaque,
597    Alias(P),
598    Choice,
599    Opt(P),
600    Split(P, P),
601}
602
603impl<P: fmt::Display> fmt::Display for ParseNodeShape<P> {
604    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605        match self {
606            ParseNodeShape::Opaque => write!(f, "Opaque"),
607            ParseNodeShape::Alias(inner) => write!(f, "Alias({})", inner),
608            ParseNodeShape::Choice => write!(f, "Choice"),
609            ParseNodeShape::Opt(inner) => write!(f, "Opt({})", inner),
610            ParseNodeShape::Split(left, right) => write!(f, "Split({}, {})", left, right),
611        }
612    }
613}