Innovenergy_trunk/csharp/Lib/SrcGen/Trees/PrefixTree.cs

42 lines
1.2 KiB
C#

using Sawmill;
namespace InnovEnergy.Lib.SrcGen.Trees;
using T = ForwardTree<String>;
public static class PrefixTree
{
public static Tree<String> Create(IEnumerable<String> strings, String root = "")
{
var children = strings.Select(s => new T(s)).ToList();
var tree = new T(root, children);
var forwardTree = tree
.Rewrite(GroupByPrefix)
.Rewrite(ConcatUnaryNodes);
return new Tree<String>(forwardTree);
}
private static T GroupByPrefix(T tree)
{
var newChildren = tree
.Children
.Where(s => s.Node.Length > 0)
.GroupBy(s => s.Node[..1], s => new T(s.Node[1..]))
.Select(g => GroupByPrefix(new T(g.Key, g.ToList())))
.ToList();
return newChildren.Count == 0
? tree // leaf
: new T(tree.Node, newChildren);
}
private static T ConcatUnaryNodes(ForwardTree<String> tree)
{
return tree.Children.Count == 1 && tree.Children[0] is var child
? new T(tree.Node + child.Node, child.Children)
: tree;
}
}