Ejemplo n.º 1
0
        private ParseGraphNode ParseNode()
        {
            string token = Read();

            if ((token == "s") || (token == "a"))
            {
                Read("(");

                List <ParseGraphNode> nodes = new List <ParseGraphNode>();

                while (Peek() != ")")
                {
                    nodes.Add(ParseNode());
                }

                Read(")");

                if (token == "s")
                {
                    return(new SeqNode(null, nodes));
                }
                else if (token == "a")
                {
                    return(new AltNode(null, nodes, false));
                }
            }
            else if ((token == "?") || (token == "*") || (token == "+"))
            {
                Read("(");
                ParseGraphNode body = ParseNode();
                Read(")");

                return(new RepNode(null, body, Reps.ForName(token[0])));
            }
            else if (token == "&")
            {
                Read("(");
                ParseGraphNode body = ParseNode();
                Read(")");

                return(new AndNode(null, body));
            }
            else if (token == "!")
            {
                Read("(");
                ParseGraphNode body = ParseNode();
                Read(")");

                return(new NotNode(null, body));
            }
            else if (token == "r")
            {
                Read("(");

                char min = TextEscape.Unquote(Read())[0];
                char max = TextEscape.Unquote(Read())[0];

                Read(")");

                return(new CharNode(null, new CharRange(min, max)));
            }
            else if (token == "l")
            {
                Read("(");

                string         label = Read();
                ParseGraphNode body  = ParseNode();

                Read(")");

                return(new LabelNode(null, label, body));
            }
            else if (token == "t")
            {
                Read("(");

                ParseGraphNode body = ParseNode();

                Read(")");

                return(new TokenNode(null, body));
            }
            else if (token == "o")
            {
                Read("(");

                Dictionary <string, object> options = new Dictionary <string, object>();

                while (Peek() == "(")
                {
                    Read();

                    string optionName  = Read();
                    object optionValue = ReadValue();

                    options[optionName] = optionValue;

                    Read(")");
                }

                ParseGraphNode body = ParseNode();

                Read(")");

                OptionsNode optionsNode = new OptionsNode(null, body);

                foreach (string key in options.Keys)
                {
                    switch (key)
                    {
                    case "buildTextNodes":
                        optionsNode.BuildTextNodes.Value = (bool)options[key];
                        break;

                    case "dropPrecedence":
                        optionsNode.DropPrecedence.Value = (bool)options[key];
                        break;

                    case "recursive":
                    {
                        if ((bool)options[key])
                        {
                            optionsNode.RecursionBehaviour.Value = RecursionBehaviour.Recursive;
                        }
                        else
                        {
                            optionsNode.RecursionBehaviour.Value = RecursionBehaviour.None;
                        }
                    } break;

                    case "leftRecursive":
                        optionsNode.RecursionBehaviour.Value = RecursionBehaviour.LeftRecursive;
                        break;

                    case "rightRecursive":
                        optionsNode.RecursionBehaviour.Value = RecursionBehaviour.RightRecursive;
                        break;

                    case "whitespace":
                    {
                        object value = options[key];

                        if (value == null)
                        {
                            optionsNode.Whitespace.Value = null;
                        }
                        else
                        {
                            optionsNode.Whitespace.Value = Pattern.PatternForType((Type)value);
                        }
                    } break;

                    case "exclude":
                        optionsNode.Exclude.Value = Pattern.PatternForType((Type)options[key]);
                        break;
                    }
                }

                return(optionsNode);
            }
            else if (token == "any")
            {
                return(new AnyNode(null));
            }
            else if ((token[0] >= '0') && (token[0] <= '9'))
            {
                return(new PatternNode(null, patterns[Convert.ToInt32(token)], false));
            }
            else if (token[0] == '\'')
            {
                string text = TextEscape.Unquote(token);

                if (text.Length == 1)
                {
                    return(new CharNode(null, text[0]));
                }
                else
                {
                    return(new TextNode(null, text));
                }
            }

            throw new Exception(token);
        }