@@ -6,6 +6,8 @@ use std::collections::{BTreeSet, HashMap, HashSet, VecDeque};
6
6
use std:: fmt;
7
7
use std:: hash:: { Hash , Hasher } ;
8
8
use std:: io:: { self , Write } ;
9
+ use std:: iter;
10
+ use std:: rc:: Rc ;
9
11
use std:: str;
10
12
11
13
#[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
@@ -241,9 +243,12 @@ impl<'i, G: GrammarReflector, I: Input> ParseForest<'i, G, I> {
241
243
}
242
244
}
243
245
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 < ( ) > {
245
247
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
+ } ;
247
252
let mut seen: HashSet < _ > = queue. iter ( ) . cloned ( ) . collect ( ) ;
248
253
let mut p = 0 ;
249
254
let node_name = |Node { kind, range } | {
@@ -304,6 +309,93 @@ impl<'i, G: GrammarReflector, I: Input> ParseForest<'i, G, I> {
304
309
}
305
310
}
306
311
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
+
307
399
pub mod typed {
308
400
use super :: { GrammarReflector , MoreThanOne , Node , ParseForest } ;
309
401
use crate :: input:: Input ;
0 commit comments