public Grammar BuildGrammar(Node<NodeType> root) { Grammar grammar = new Grammar { Name = root.Children.Single(x => x.NodeType == NodeType.Identifier).Text, CaseSensitive = root.Children.Any(x => x.NodeType == NodeType.CaseSensitive) }; var patternsNode = root.Children.SingleOrDefault(x => x.NodeType == NodeType.Patterns); if (patternsNode != null) { foreach (var patternNode in patternsNode.Children.Where(x => x.NodeType == NodeType.Pattern && x.Children.Count > 0)) { var children = patternNode.Children.Where(x => x.NodeType == NodeType.Identifier).ToArray(); var pattern = new Pattern { Name = children[0].Text, Texts = children.Skip(1).Select(x => x.Text).ToArray() }; grammar.Patterns.Add(pattern); } } var defsNode = root.Children.SingleOrDefault(x => x.NodeType == NodeType.Defs); if (defsNode != null) { foreach (var defNode in defsNode.Children.Where(x => x.NodeType == NodeType.Def && x.Children.Count > 0)) { var children = defNode.Children.Where(x => x.NodeType == NodeType.Identifier).ToArray(); var def = new Def { Name = children[0].Text }; grammar.Defs.Add(def); } foreach (var defNode in defsNode.Children.Where(x => x.NodeType == NodeType.Def)) { var def = grammar.Defs.Single(x => x.Name == defNode.Children.Single(y => y.NodeType == NodeType.Identifier).Text); foreach (var partNode in defNode.Children.Where(x => x.NodeType == NodeType.Part)) { Element element = null; if (partNode.Children.Count == 1 && partNode.Children[0].NodeType == NodeType.Optional) { var optionalIdents = partNode.Children[0].Children.SingleOrDefault(x => x.NodeType == NodeType.OptionalIdents); var requiredIdents = partNode.Children[0].Children.SingleOrDefault(x => x.NodeType == NodeType.RequiredIdents); Element subElement; if (optionalIdents != null) { subElement = new OneOf(GetIdentifiers(grammar, optionalIdents.Children.Where(x => x.NodeType != NodeType.Pipe).ToList())); } else if (requiredIdents != null) { subElement = new AllOf(GetIdentifiers(grammar, requiredIdents.Children)); } else { throw new Exception(); } element = new Optional(subElement); } else { List<Element> identifiers = new List<Element>(); foreach (var elementNode in partNode.Children.Where(x => x.NodeType == NodeType.Element)) { Element identifier; if (grammar.Patterns.Any(x => x.Name == elementNode.Children[0].Text)) { identifier = new PatternIdentifier { Name = elementNode.Children[0].Text }; } else { identifier = new DefIdentifier { Name = elementNode.Children[0].Text }; } element = identifier; if (elementNode.Children.Any(x => x.NodeType == NodeType.Plus)) { element = new OneOrMore (element); } else if (elementNode.Children.Any(x => x.NodeType == NodeType.Star)) { element = new ZeroOrMore(element); } identifiers.Add(identifier); } if (identifiers.Count > 1) { element = new OneOf(identifiers); } } if (element == null) { throw new Exception(); } if (partNode.Children.Count == 1 && partNode.Children[0].NodeType == NodeType.Optional) { if (partNode.Children[0].Children.Any(x => x.NodeType == NodeType.Plus)) { element = new OneOrMore(element); } else if (partNode.Children[0].Children.Any(x => x.NodeType == NodeType.Star)) { element = new ZeroOrMore(element); } } else { if (partNode.Children.Any(x => x.NodeType == NodeType.Plus)) { element = new OneOrMore(element); } else if (partNode.Children.Any(x => x.NodeType == NodeType.Star)) { element = new ZeroOrMore(element); } } def.Elements.Add(element); } } } var ignoresNode = root.Children.SingleOrDefault(x => x.NodeType == NodeType.Ignores); if (ignoresNode != null) { foreach (var ignoreNode in ignoresNode.Children) { grammar.Ignores.Add(new Ignore { Name = ignoreNode.Text }); } } var discardsNode = root.Children.SingleOrDefault(x => x.NodeType == NodeType.Discards); if (discardsNode != null) { foreach (var discardNode in discardsNode.Children) { grammar.Discards.Add(new Discard { Name = discardNode.Text }); } } SetParents(grammar); return grammar; }
public OptionalTreeNode(Optional optional) { Optional = optional; Text = "Optional"; }