public static List<Node> Parse(ref Match m, string left, string right, string value) { List<Node> result; result = new List<Node>(); while (m.Success) { // left, down if (m.Groups[left].Success) { m = m.NextMatch(); Node tmp; tmp = new Node(); tmp.Branches = Parse(ref m, left, right, value); result.Add(tmp); } else if (m.Groups[right].Success) { // right, up m = m.NextMatch(); return result; } else if (m.Groups[value].Success) { // value, pluck Node tmp; tmp = new Node(); tmp.Leaf = m.Groups[value].Value; result.Add(tmp); m = m.NextMatch(); } } return result; }
public static void Walk(Node n, Action<Node> a) { if (n.Leaf != null) { a(n); } else if (n.Branches != null) { Walk(n.Branches, a); } }
public static List<Node> ParseFromIndent(List<string> inputs) { int idx; Node n; string ind, indpre; Match m; bool isSeparator = false; // object[0] -- indent, object[1] -- branches node Stack<object[]> stk = new Stack<object[]>(); n = new Node(new List<Node>()); // ignores heading empty lines. idx = inputs.FindIndex(delegate(string itm) { return Sty.NotNullOrEmpty(itm); }); if (idx < 0) return n.Branches; if (idx > 0) inputs = inputs.GetRange(idx, inputs.Count - idx); Func<string, string> indf = delegate(string s) { m = Regex.Match(s, @"^\s+"); return m.Success ? m.Value : ""; }; Func<string, Node, Node> push = delegate(string ind_, Node n_) { stk.Push(new object[] { ind_, n_ }); Node nn = new Node(new List<Node>()); n_.Branches.Add(nn); return nn; }; indpre = ""; ind = indf(inputs[0]); if (ind.Length > indpre.Length) { n = push(indpre, n); } n.Branches.Add(new Node(inputs[0].Trim())); indpre = ind; Action<string> newf = delegate(string s) { s = s.TrimEnd(); if (s != "") { ind = indf(s); if (ind.Length > indpre.Length) { n = push(indpre, n); } else if (ind.Length < indpre.Length) { object[] itm; n = null; while (stk.Count > 0) { itm = stk.Pop(); if ((itm[0] as string).Length == ind.Length) { n = itm[1] as Node; break; } } if (n == null) throw new Exception("Supplied text is wrong format."); } if (isSeparator) { if (stk.Count == 0) throw new Exception("Supplied text is wrong format."); // creates new brances if previous line is a separator. object[] itm = stk.Pop(); n = itm[1] as Node; Node nn = new Node(new List<Node>()); n.Branches.Add(nn); n = nn; stk.Push(itm); } n.Branches.Add(new Node(s.Trim())); indpre = ind; isSeparator = false; } else { isSeparator = true; } }; inputs.GetRange(1, inputs.Count - 1).ForEach(newf); while(stk.Count>0) n = (stk.Pop() as object[])[1] as Node; return n.Branches; }