private string DefChidren(Thing thing, string delimiter, ref string ret) { bool first = true; foreach (Thing child in thing.Children) { if (!first) { ret += delimiter; } if (child.ThingType == ThingType.Token || child.ThingType == ThingType.Text || child.ThingType == ThingType.Def) { ret += (child.Parent != null && child.Parent.ThingType == ThingType.Optional ? "" : " ") + child.Name; } else if (child.ThingType == ThingType.Optional) { ret += " ["; DefChidren(child, " ", ref ret); ret += "]"; } else if (child.ThingType == ThingType.OneOf || child.ThingType == ThingType.OneOrMore || child.ThingType == ThingType.ZeroOrMore) { DefChidren(child, " |", ref ret); if (child.ThingType == ThingType.OneOrMore) { ret += "+"; } else if (child.ThingType == ThingType.ZeroOrMore) { ret += "*"; } } first = false; } return ret; }
private void Walk(Thing parent, Action<Thing> action) { action(parent); foreach (Thing child in parent.Children) { Walk(child, action); } }
private List<Thing> GetThings(Thing parent, ThingType thingType) { List<Thing> things = new List<Thing>(); Walk(parent, thing => { if (thing.ThingType == thingType && !things.Contains(thing)) { things.Add(thing); } }); return things; }
private void GetPossibleTokens(Thing parent, ref string text) { if (parent.ThingType == ThingType.Token) { text += ", TokenType." + parent.Name.ToIdentifier(); } foreach (Thing child in parent.Children) { GetPossibleTokens(child, ref text); if (!new[] { ThingType.OneOf, ThingType.Optional }.Contains(parent.ThingType) && child.ThingType == ThingType.Def) { break; } if (parent.ThingType == ThingType.Def && child.ThingType == ThingType.Token) { break; } } }
/*private string GetChildTokens(Thing parent) { List<Thing> ret = new List<Thing>(); Walk(parent, child => { if ((child.ThingType == ThingType.Token || child.ThingType == ThingType.Text)) { ret.Add(child); } }); return String.Join(", ", ret.Take(1).Select(x => "TokenType." + x.Name.ToIdentifier())); } private List<List<Thing>> GetPaths(Thing parent) { List<Thing> leaves = new List<Thing>(); Walk(parent, thing => { if (thing.Children.Count == 0) { leaves.Insert(0, thing); } }); List<List<Thing>> paths = new List<List<Thing>>(); foreach (Thing leaf in leaves) { List<Thing> things = new List<Thing>(); Thing x = leaf; while (x != null && x != parent) { things.Add(x); x = x.Parent; } paths.Add(things); } return paths; }*/ private string GetPossibleTokens(Thing parent) { string text = ""; GetPossibleTokens(parent, ref text); return text.Substring(2); }
private void GenerateParserDef(Thing parent, string parentOrChild, StringBuilder stringBuilder, int level) { string indent = new string(' ', level * 4); if (level > 0 && new[] { ThingType.Token, ThingType.Text, ThingType.Def }.Contains(parent.ThingType)) { if (parent.ThingType == ThingType.Text || parent.ThingType == ThingType.Token) { stringBuilder.Append($@" {indent}Consume({parentOrChild}, TokenType.{parent.Name.ToIdentifier()}, NodeType.{parent.Name.ToIdentifier()});"); } else if (parent.ThingType == ThingType.Def) { stringBuilder.Append($@" {indent}{parent.Name}({parentOrChild});"); } } else { foreach (Thing child in parent.Children) { string tokens = GetPossibleTokens(child); if (child.ThingType == ThingType.Text || child.ThingType == ThingType.Token) { stringBuilder.Append($@" {indent}Consume({parentOrChild}, TokenType.{child.Name.ToIdentifier()}, NodeType.{child.Name.ToIdentifier()});"); } else if (child.ThingType == ThingType.Def) { stringBuilder.Append($@" {indent}{child.Name}({parentOrChild});"); } else if (child.ThingType == ThingType.ZeroOrMore) { stringBuilder.Append($@" {indent}while (IsTokenType({tokens})) {indent}{{"); GenerateParserDef(child, parentOrChild, stringBuilder, level + 1); stringBuilder.Append($@" {indent}}}"); } else if (child.ThingType == ThingType.OneOrMore) { GenerateParserDef(child, parentOrChild, stringBuilder, level); stringBuilder.Append($@" {indent}while (IsTokenType({tokens})) {indent}{{"); GenerateParserDef(child, parentOrChild, stringBuilder, level + 1); stringBuilder.Append($@" {indent}}}"); } else if (child.ThingType == ThingType.Optional) { stringBuilder.Append($@" {indent}if (IsTokenType({tokens})) {indent}{{"); GenerateParserDef(child, parentOrChild, stringBuilder, level + 1); stringBuilder.Append($@" {indent}}}"); } else if (child.ThingType == ThingType.OneOf) { string @else = ""; foreach (var grandChild in child.Children) { tokens = GetPossibleTokens(grandChild); stringBuilder.Append($@" {indent}{@else}if (IsTokenType({tokens})) {indent}{{"); GenerateParserDef(grandChild, "child", stringBuilder, level + 1); stringBuilder.Append($@" {indent}}}"); @else = "else "; } } } } }
private void RefreshGrammar(Thing parent, int indent = 0) { genGrammar.Text += Environment.NewLine + new String(' ', indent * 4) + parent.ThingType + " - " + parent.Name + " - " + parent.Text; if (indent == 0 || parent.ThingType != ThingType.Def) { foreach (var child in parent.Children) { RefreshGrammar(child, indent + 1); } } }