예제 #1
0
        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;
        }
예제 #2
0
파일: Form1.cs 프로젝트: danthomas/Parsing
 public OneOfTreeNode(OneOf oneOf)
 {
     OneOf = oneOf;
     Text = "One Of";
 }