public new static void SetUp(Module module, Grammar grammar)
 {
     if (pattern == null)
     {
         string expression = "o((recursive false) s(l(label 0) ':' l(body 1)))";
         Pattern[] patterns = {Name.pattern, PatternExpression.pattern};
     
         ParseGraphNode parseGraph = BootstrapParser.Parse(expression, patterns);
 
         pattern = new ConcretePattern(null, "LabelPatternExpression", parseGraph);
         pattern.SetType(typeof(LabelPatternExpression));
     
         PatternExpression.pattern.AddAltPattern(pattern);
     }
     
     module.SetName("LabelPatternExpression", typeof(LabelPatternExpression));
     grammar.PatternDefined(pattern);
 }
예제 #2
0
 public ParserMemoryKey(ConcretePattern pattern, int position)
 {
     this.pattern = pattern;
     this.position = position;
 }
예제 #3
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);
        }
예제 #4
0
        public override ParseTree Parse(Lexer lexer, ParserState state)
        {
            int start = lexer.Position;

            state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Pattern " + Type.Name);

            /*state.RuntimeState.Runtime.ParseTrace.Enter(this, lexer.CurrentSource(), "Excluded:");
             *
             * foreach (Pattern excluded in state.Excluded)
             *  state.RuntimeState.Runtime.ParseTrace.Single(excluded.Type.Name);
             *
             * state.RuntimeState.Runtime.ParseTrace.Leave(this);*/

            if (state.Excluded.Contains(this))
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.CurrentSource(), "Excluded");
                return(ParseTree.No);
            }

            ParserMemoryKey key = new ParserMemoryKey(this, start);

            bool oldSkipMemoryForLeftRecursion = state.SkipMemoryForLeftRecursion;

            if (state.SkipMemoryForLeftRecursion)
            {
                state.SkipMemoryForLeftRecursion = false;
            }
            else
            {
                ParserMemoryEntry entry;

                if (state.Memory.TryGetValue(key, out entry))
                {
                    state.RuntimeState.Runtime.ParseTrace.LinkNext(entry.Tag);

                    if (entry.Tree == ParseTree.No)
                    {
                        state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start), "From memory");
                    }
                    else
                    {
                        state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start), "From memory");
                        lexer.Position = entry.End;
                    }

                    return(entry.Tree);
                }
            }

            ConcretePattern oldRecursionExclude = state.RecursionExclude;

            if (RecursionBehaviour != RecursionBehaviour.Recursive)
            {
                if (state.RecursionExclude != null)
                {
                    state.Excluded.Remove(state.RecursionExclude);
                }

                state.RecursionExclude = this;

                state.Excluded.Add(this);
            }

            RecursionBehaviour oldRecursionBehaviour = state.RecursionBehaviour;

            state.RecursionBehaviour = RecursionBehaviour;

            Precedence oldCurrentPrecedence = state.CurrentPrecedence;

            if (Precedence.Overwrites(state.CurrentPrecedence))
            {
                state.CurrentPrecedence = Precedence;
            }

            bool oldPrecedenceCanEqualCurrent = state.PrecedenceCanEqualCurrent;

            state.PrecedenceCanEqualCurrent = RecursionBehaviour == RecursionBehaviour.Recursive;

            ParseTree tree = ParseGraph.Parse(lexer, state);

            state.CurrentPrecedence          = oldCurrentPrecedence;
            state.PrecedenceCanEqualCurrent  = oldPrecedenceCanEqualCurrent;
            state.RecursionBehaviour         = oldRecursionBehaviour;
            state.RecursionExclude           = oldRecursionExclude;
            state.SkipMemoryForLeftRecursion = oldSkipMemoryForLeftRecursion;

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

                state.Excluded.Remove(this);
            }

            if (tree != ParseTree.No)
            {
                lexer.Whitespace(state.RuntimeState);
                tree = Instantiate(lexer, state, start, tree);
            }

            object nextTag = new object();

            state.RuntimeState.Runtime.ParseTrace.TagNext(nextTag);

            if (tree == ParseTree.No)
            {
                state.RuntimeState.Runtime.ParseTrace.No(this, lexer.SourceFrom(start));
            }
            else
            {
                state.RuntimeState.Runtime.ParseTrace.Yes(this, lexer.SourceFrom(start));

                if (RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                {
                    tree = LeftRecurse(lexer, state, start, tree);
                }
            }

            // TODO - can remove some other code if not remembering

            if (ShouldRemember)
            {
                state.Memory[key] = new ParserMemoryEntry(tree, lexer.Position, nextTag);
            }

            return(tree);
        }