Пример #1
0
 public ConcretePattern(Source source, string name,
     ParseGraphNode parseGraph)
         : base(source, name)
 {
     SetParseGraph(parseGraph);
     
     recursionBehaviour = RecursionBehaviour.Recursive;
     
     OptionsNode options = ParseGraph as OptionsNode;
     
     while (options != null)
     {
         if (options.RecursionBehaviour.HasValue)
         {
             recursionBehaviour = options.RecursionBehaviour.Value;
             break;
         }
         
         options = options.Body as OptionsNode;
     }
     
     recurseNode = new PatternNode(source, this, true);
 }
Пример #2
0
        public ConcretePattern(Source source, string name,
                               ParseGraphNode parseGraph)
            : base(source, name)
        {
            SetParseGraph(parseGraph);

            recursionBehaviour = RecursionBehaviour.Recursive;

            OptionsNode options = ParseGraph as OptionsNode;

            while (options != null)
            {
                if (options.RecursionBehaviour.HasValue)
                {
                    recursionBehaviour = options.RecursionBehaviour.Value;
                    break;
                }

                options = options.Body as OptionsNode;
            }

            recurseNode = new PatternNode(source, this, true);
        }
Пример #3
0
 protected void SetParseGraph(ParseGraphNode parseGraph)
 {
     this.parseGraph = parseGraph;
     fields = parseGraph.GetFields();
     shouldRemember = parseGraph.GetShouldRemember();
 }
Пример #4
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);
        }
Пример #5
0
 protected void SetParseGraph(ParseGraphNode parseGraph)
 {
     this.parseGraph = parseGraph;
     fields          = parseGraph.GetFields();
     shouldRemember  = parseGraph.GetShouldRemember();
 }
Пример #6
0
 private void AddNode(TreeIter parent, ParseGraphNode node)
 {
     if (node is AnyNode)
         AddNode(parent, (AnyNode) node);
     else if (node is TextNode)
         AddNode(parent, (TextNode) node);
     else if (node is CharNode)
         AddNode(parent, (CharNode) node);
     else if (node is PatternNode)
         AddNode(parent, (PatternNode) node);
     else if (node is AltNode)
         AddNode(parent, (AltNode) node);
     else if (node is RepNode)
         AddNode(parent, (RepNode) node);
     else if (node is SeqNode)
         AddNode(parent, (SeqNode) node);
     else if (node is TokenNode)
         AddNode(parent, (TokenNode) node);
     else if (node is LabelNode)
         AddNode(parent, (LabelNode) node);
     else if (node is OptionsNode)
         AddNode(parent, (OptionsNode) node);
     else if (node is FailNode)
         AddNode(parent, (FailNode) node);
     else if (node is AndNode)
         AddNode(parent, (AndNode) node);
     else if (node is NotNode)
         AddNode(parent, (NotNode) node);
     else if (node is UserDefinedNode)
         AddNode(parent, (UserDefinedNode) node);
     else
         throw new Exception("Unsupported grammar node type " + node.GetType() + " in viewer");
 }
Пример #7
0
 public TokenNode(Source source, ParseGraphNode body)
     : base(source)
 {
     this.body = body;
 }
Пример #8
0
 public OptionsNode(Source source, ParseGraphNode body)
     : base(source)
 {
     this.body = body;
 }
Пример #9
0
 public RepNode(Source source, ParseGraphNode body, Reps reps)
     : base(source)
 {
     this.body = body;
     this.reps = reps;
 }
Пример #10
0
        public override ParseTree Parse(Lexer lexer, ParserState state)
        {
            int start = lexer.Position;

            ParseTree       oldLHS = state.LeftHandSide;
            bool            oldPrecedenceCanEqualCurrent = state.PrecedenceCanEqualCurrent;
            ConcretePattern oldRecursionExclude          = null;

            ParseTree tree = ParseTree.Yes;

            for (int n = 0; n < nodes.Count; n++)
            {
                ParseGraphNode node = nodes[n];

                ParseTree nodeTree = node.Parse(lexer, state);

                if (nodeTree == ParseTree.No)
                {
                    state.PrecedenceCanEqualCurrent = oldPrecedenceCanEqualCurrent;
                    state.LeftHandSide     = oldLHS;
                    state.RecursionExclude = oldRecursionExclude;

                    if (oldRecursionExclude != null)
                    {
                        state.Excluded.Add(oldRecursionExclude);
                    }

                    lexer.Position = start;
                    return(ParseTree.No);
                }

                tree = tree.Extend(nodeTree);

                if (n == 0)
                {
                    if (state.RecursionExclude != null)
                    {
                        oldRecursionExclude = state.RecursionExclude;
                        state.Excluded.Remove(state.RecursionExclude);
                        state.RecursionExclude = null;
                    }

                    if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
                    {
                        state.PrecedenceCanEqualCurrent = true;
                    }
                    else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                    {
                        state.LeftHandSide = null;
                    }
                }
            }

            state.PrecedenceCanEqualCurrent = oldPrecedenceCanEqualCurrent;
            state.LeftHandSide     = oldLHS;
            state.RecursionExclude = oldRecursionExclude;

            if (oldRecursionExclude != null)
            {
                state.Excluded.Add(oldRecursionExclude);
            }

            return(tree);
        }
Пример #11
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Comment("start of seq --------------------");

            block.BeginScope();

            // Save

            BlockLocal start = block.SavePosition();

            BlockLocal oldLeftHandSide = new BlockLocal(typeof(RuntimeObject));
            BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
            BlockLocal oldRecursionExclude          = new BlockLocal(typeof(Pattern));

            block.DeclareLocal(oldRecursionExclude);

            if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
            {
                block.DeclareLocal(oldPrecedenceCanEqualCurrent);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                block.StoreLocal(oldPrecedenceCanEqualCurrent);
            }

            if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
            {
                block.DeclareLocal(oldLeftHandSide);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                block.StoreLocal(oldLeftHandSide);
            }

            block.LoadYes();

            for (int n = 0; n < nodes.Count; n++)
            {
                ParseGraphNode node = nodes[n];

                // Parse the node

                block.Emit(node.Compile(runtime, state));

                // If no

                BlockLabel yes = new BlockLabel("yes");
                block.Dup();    // dup the body tree
                block.BranchIfNotNo(yes);

                block.Pop();    // pop body tree
                block.Pop();    // pop new tree

                Restore(state, block, oldLeftHandSide,
                        oldPrecedenceCanEqualCurrent, oldRecursionExclude);

                block.RestorePosition(start);

                block.LoadNo();
                block.Branch(returnLabel);

                block.MarkLabel(yes);

                // Extend

                block.Call(typeof(ParseTree).GetMethod("Extend"));

                if (n == 0)
                {
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.LoadNull();

                    BlockLabel recursionExcludeNull = new BlockLabel("recursionExcludeNull");
                    block.BranchIfEqual(recursionExcludeNull);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.StoreLocal(oldRecursionExclude);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) }));

                    block.LoadState();
                    block.LoadNull();
                    block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));

                    block.MarkLabel(recursionExcludeNull);

                    if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
                    {
                        block.Comment("right recursion");

                        block.LoadState();
                        block.Load(1);
                        block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                    }
                    else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                    {
                        block.Comment("left recursion");

                        block.LoadState();
                        block.LoadNull();
                        block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                    }
                }
            }

            Restore(state, block, oldLeftHandSide,
                    oldPrecedenceCanEqualCurrent, oldRecursionExclude);

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of seq --------------------");

            return(block);
        }
Пример #12
0
 public RepNode(Source source, ParseGraphNode body, Reps reps)
     : base(source)
 {
     this.body = body;
     this.reps = reps;
 }
Пример #13
0
 public LabelNode(Source source, string label, ParseGraphNode body)
     : base(source)
 {
     this.label = label;
     this.body = body;
 }
Пример #14
0
 public TokenNode(Source source, ParseGraphNode body)
     : base(source)
 {
     this.body = body;
 }
Пример #15
0
 public OptionsNode(Source source, ParseGraphNode body)
     : base(source)
 {
     this.body = body;
 }
Пример #16
0
 public LabelNode(Source source, string label, ParseGraphNode body)
     : base(source)
 {
     this.label = label;
     this.body  = body;
 }