Skip to content

Commit d5cc009

Browse files
committed
Introduce the slow_bruteforce_interpreter.
1 parent 4b3730d commit d5cc009

10 files changed

+1483
-119
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ readme = "README.md"
1313
description = "Grammar framework."
1414

1515
[dependencies]
16+
cyclotron = "0.0.3"
17+
elsa = "1.3.2"
1618
indexmap = "1"
1719
indexing = "0.3.2"
1820
proc-macro2 = "0.4.30"
19-
elsa = "1.3.2"
2021

2122
[lib]
2223
doctest = false

src/forest.rs

+94-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::collections::{BTreeSet, HashMap, HashSet, VecDeque};
66
use std::fmt;
77
use std::hash::{Hash, Hasher};
88
use std::io::{self, Write};
9+
use std::iter;
10+
use std::rc::Rc;
911
use std::str;
1012

1113
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -241,9 +243,12 @@ impl<'i, G: GrammarReflector, I: Input> ParseForest<'i, G, I> {
241243
}
242244
}
243245

244-
pub fn dump_graphviz(&self, out: &mut dyn Write) -> io::Result<()> {
246+
pub fn dump_graphviz(&self, root: Option<Node<'i, G>>, out: &mut dyn Write) -> io::Result<()> {
245247
writeln!(out, "digraph forest {{")?;
246-
let mut queue: VecDeque<_> = self.possibilities.keys().cloned().collect();
248+
let mut queue: VecDeque<_> = match root {
249+
Some(root) => iter::once(root).collect(),
250+
None => self.possibilities.keys().cloned().collect(),
251+
};
247252
let mut seen: HashSet<_> = queue.iter().cloned().collect();
248253
let mut p = 0;
249254
let node_name = |Node { kind, range }| {
@@ -304,6 +309,93 @@ impl<'i, G: GrammarReflector, I: Input> ParseForest<'i, G, I> {
304309
}
305310
}
306311

312+
// TODO(eddyb) remove this entirely, only user of it left is `ListHandle`.
313+
#[derive(Clone)]
314+
pub struct DynExpandedTree<'i, G: GrammarReflector> {
315+
pub node: Node<'i, G>,
316+
pub kind: DynExpandedTreeKind<'i, G>,
317+
}
318+
319+
#[derive(Clone)]
320+
pub enum DynExpandedTreeKind<'i, G: GrammarReflector> {
321+
Leaf,
322+
Or(G::NodeKind, Rc<DynExpandedTree<'i, G>>),
323+
Opt(Option<Rc<DynExpandedTree<'i, G>>>),
324+
Concat([Rc<DynExpandedTree<'i, G>>; 2]),
325+
}
326+
327+
impl<'i, G: GrammarReflector> DynExpandedTree<'i, G> {
328+
pub fn one_from_node<I>(
329+
forest: &ParseForest<'i, G, I>,
330+
node: Node<'i, G>,
331+
) -> Result<Rc<Self>, MoreThanOne>
332+
where
333+
I: Input,
334+
{
335+
let kind = match forest.grammar.node_shape(node.kind) {
336+
NodeShape::Opaque | NodeShape::Alias(_) => DynExpandedTreeKind::Leaf,
337+
NodeShape::Choice(_) => {
338+
let child = forest.one_choice(node)?;
339+
DynExpandedTreeKind::Or(child.kind, Self::one_from_node(forest, child)?)
340+
}
341+
NodeShape::Opt(_) => DynExpandedTreeKind::Opt(match forest.unpack_opt(node) {
342+
Some(child) => Some(Self::one_from_node(forest, child)?),
343+
None => None,
344+
}),
345+
NodeShape::Split(..) => {
346+
let (left, right) = forest.one_split(node)?;
347+
DynExpandedTreeKind::Concat([
348+
Self::one_from_node(forest, left)?,
349+
Self::one_from_node(forest, right)?,
350+
])
351+
}
352+
};
353+
Ok(Rc::new(DynExpandedTree { node, kind }))
354+
}
355+
356+
pub fn all_from_node<I>(forest: &ParseForest<'i, G, I>, node: Node<'i, G>) -> Vec<Rc<Self>>
357+
where
358+
I: Input,
359+
{
360+
let new = |kind| Rc::new(DynExpandedTree { node, kind });
361+
match forest.grammar.node_shape(node.kind) {
362+
NodeShape::Opaque | NodeShape::Alias(_) => vec![new(DynExpandedTreeKind::Leaf)],
363+
NodeShape::Choice(_) => forest
364+
.all_choices(node)
365+
.flat_map(|child| {
366+
Self::all_from_node(forest, child)
367+
.into_iter()
368+
.map(move |child_tree| new(DynExpandedTreeKind::Or(child.kind, child_tree)))
369+
})
370+
.collect(),
371+
NodeShape::Opt(_) => match forest.unpack_opt(node) {
372+
Some(child) => Self::all_from_node(forest, child)
373+
.into_iter()
374+
.map(|child_tree| new(DynExpandedTreeKind::Opt(Some(child_tree))))
375+
.collect(),
376+
None => vec![new(DynExpandedTreeKind::Opt(None))],
377+
},
378+
NodeShape::Split(..) => forest
379+
.all_splits(node)
380+
.flat_map(|(left, right)| {
381+
Self::all_from_node(forest, left)
382+
.into_iter()
383+
.flat_map(move |left_tree| {
384+
Self::all_from_node(forest, right)
385+
.into_iter()
386+
.map(move |right_tree| {
387+
new(DynExpandedTreeKind::Concat([
388+
left_tree.clone(),
389+
right_tree,
390+
]))
391+
})
392+
})
393+
})
394+
.collect(),
395+
}
396+
}
397+
}
398+
307399
pub mod typed {
308400
use super::{GrammarReflector, MoreThanOne, Node, ParseForest};
309401
use crate::input::Input;

src/lib.rs

+4-98
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ pub mod forest;
1414
#[forbid(unsafe_code)]
1515
pub mod input;
1616
#[forbid(unsafe_code)]
17+
pub mod lyg;
18+
#[forbid(unsafe_code)]
1719
pub mod parser;
1820
#[forbid(unsafe_code)]
1921
pub mod proc_macro;
2022
#[forbid(unsafe_code)]
2123
pub mod rule;
2224
#[forbid(unsafe_code)]
2325
pub mod scannerless;
26+
#[forbid(unsafe_code)]
27+
pub mod slow_bruteforce_interpreter;
2428

2529
// HACK(eddyb) this contains impls for types in `proc_macro`, which depend on
2630
// `input`, collapse this back into `proc_macro`.
@@ -78,101 +82,3 @@ impl Grammar {
7882
}
7983
}
8084
}
81-
82-
/// Construct a (meta-)grammar for parsing a grammar.
83-
pub fn grammar_grammar<Pat: Eq + Hash + From<&'static str>>(cx: &Context<Pat>) -> Grammar {
84-
use crate::rule::*;
85-
86-
// HACK(eddyb) more explicit subset of the grammar, for bootstrapping.
87-
macro_rules! rule {
88-
({ $start:tt ..= $end:tt }) => {
89-
eat($start..=$end)
90-
};
91-
({ ! $pat:tt }) => {
92-
negative_lookahead($pat)
93-
};
94-
({ ! $start:tt ..= $end:tt }) => {
95-
negative_lookahead($start..=$end)
96-
};
97-
($rule:ident) => {
98-
call(stringify!($rule))
99-
};
100-
({ $name:ident : $rule:tt }) => {
101-
rule!($rule).field(stringify!($name))
102-
};
103-
({ $rule:tt ? }) => {
104-
rule!($rule).opt()
105-
};
106-
({ $elem:tt * }) => {
107-
rule!($elem).repeat_many()
108-
};
109-
({ $elem:tt + }) => {
110-
rule!($elem).repeat_more()
111-
};
112-
({ $elem:tt + % $sep:tt }) => {
113-
rule!($elem).repeat_more_sep(rule!($sep), SepKind::Simple)
114-
};
115-
({ $rule0:tt $(| $rule:tt)+ }) => {
116-
rule!($rule0) $(| rule!($rule))+
117-
};
118-
({ $rule0:tt $($rule:tt)* }) => {
119-
rule!($rule0) $(+ rule!($rule))*
120-
};
121-
($pat:expr) => {
122-
eat($pat)
123-
};
124-
}
125-
126-
macro_rules! grammar {
127-
($($rule_name:ident = $($rule:tt)|+;)*) => ({
128-
let mut grammar = Grammar::new();
129-
$(grammar.define(
130-
cx.intern(stringify!($rule_name)),
131-
rule!({ $($rule)|+ }).finish(cx),
132-
);)*
133-
grammar
134-
})
135-
}
136-
137-
// Main grammar.
138-
let mut grammar = grammar! {
139-
Grammar = { FileStart {rules:{RuleDef*}} FileEnd };
140-
RuleDef = { {name:Ident} "=" {rule:Or} ";" };
141-
Or = {{"|"?} {rules:{Concat+ % "|"}}};
142-
Concat = {rules:{Rule+}};
143-
Rule = { {{ {field:Ident} ":" }?} {rule:Primary} {{modifier:Modifier}?} };
144-
Primary =
145-
{Eat:Pattern} |
146-
{Call:Ident} |
147-
{Group:{ "{" {{or:Or}?} "}" }};
148-
Modifier =
149-
{Opt:"?"} |
150-
{Repeat:{ {repeat:Repeat} {{ {kind:SepKind} {sep:Primary} }?} }};
151-
Repeat =
152-
{Many:"*"} |
153-
{More:"+"};
154-
SepKind =
155-
{Simple:"%"} |
156-
// HACK(eddyb) should be "%%", but `rustc`'s `proc_macro` server doesn't
157-
// always preserve jointness, except within multi-character Rust operators.
158-
{Trailing:{"%" "%"}};
159-
Pattern =
160-
{Str:StrLit} |
161-
{CharRange:{ {{start:CharLit}?} ".." {{end:CharLit}?} }} |
162-
{CharRangeInclusive:{ {{start:CharLit}?} "..=" {end:CharLit} }};
163-
};
164-
165-
// Lexical fragment of the grammar.
166-
grammar.extend(grammar! {
167-
FileStart = "";
168-
FileEnd = "";
169-
170-
Ident = IDENT;
171-
172-
// FIXME(eddyb) restrict literals, once `proc_macro` allows it.
173-
StrLit = LITERAL;
174-
CharLit = LITERAL;
175-
});
176-
177-
grammar
178-
}

0 commit comments

Comments
 (0)