コード例 #1
0
        public Tuple <StackElement <SYMBOL_ENUM, TREE_NODE>, IEnumerable <StackElement <SYMBOL_ENUM, TREE_NODE> > > TakeLast(int count)
        {
            StackElement <SYMBOL_ENUM, TREE_NODE> leaf = currentStackLeaf;
            IEnumerable <StackElement <SYMBOL_ENUM, TREE_NODE> > tail = takeLast(ref leaf, count).ToList();

            return(Tuple.Create(leaf, tail));
        }
コード例 #2
0
        private StackElement <SYMBOL_ENUM, TREE_NODE> addToStack(Command <SYMBOL_ENUM, TREE_NODE> command,
                                                                 AttachPoint <SYMBOL_ENUM, TREE_NODE> attachPoint,
                                                                 SYMBOL_ENUM symbol,
                                                                 int markWith,
                                                                 string text, Option <object> userObject, bool recovered)
        {
            // if stack is empty and we are adding start symbol (meaning full, successful parse)
            if (attachPoint.Stack == null && symbol.Equals(StartSymbol) && IsEndOfInput)
            {
                return(stackMaster.Add(command.IsShift, attachPoint,
                                       new StackElement <SYMBOL_ENUM, TREE_NODE>()
                {
                    Symbol = StartSymbol,
                    MarkedWith = markWith,
                    UserObject = userObject,
                    NodeIndex = actionTable.StartNodeIndex,
                    IsRecovered = recovered,
                    RecorderLink = new CommandRecorder <SYMBOL_ENUM, TREE_NODE>(command, messages)
                }));
            }
            else
            {
                int target_id;
                IEnumerable <NfaCell <SYMBOL_ENUM, TREE_NODE> > recovery_items;

                // compute where we will go with the symbol in DFA
                if (actionTable.TryGetTarget(anchoredDfaNode(attachPoint.Stack), symbol, out target_id, out recovery_items))
                {
                    StackElement <SYMBOL_ENUM, TREE_NODE> added = stackMaster.Add(command.IsShift, attachPoint,
                                                                                  new StackElement <SYMBOL_ENUM, TREE_NODE>()
                    {
                        Symbol       = symbol,
                        MarkedWith   = markWith,
                        TextInfo     = text,
                        UserObject   = userObject,
                        Coordinates  = Coordinates,
                        NodeIndex    = target_id,
                        IsRecovered  = recovered,
                        RecorderLink = new CommandRecorder <SYMBOL_ENUM, TREE_NODE>(command, messages)
                    });

                    added.RecoveryItems = recovery_items;

                    return(added);
                }
                else
                {
                    if (options.Trace)
                    {
                        System.IO.File.WriteAllLines("parser_history.dump", ParseLog.Select(it => it.ToString() + Environment.NewLine));
                    }

                    throw new Exception("Internal parser error on symbol: " + this.symbolsRep.Get(symbol) + " at node: " + anchoredDfaNode(attachPoint.Stack)
                                        + " with stack: " + stackToString(attachPoint.Stack));
                }
            }
        }
コード例 #3
0
 protected int anchoredDfaNode(StackElement <SYMBOL_ENUM, TREE_NODE> stackAnchor)
 {
     if (stackAnchor == null)
     {
         return(actionTable.StartNodeIndex);
     }
     else
     {
         return(stackAnchor.NodeIndex);
     }
 }
コード例 #4
0
        public bool RemoveStack()
        {
            if (currentStackLeaf != null)
            {
                currentStackLeaf.RemoveTail();
            }

            currentStackLeaf = null;

            return(stackLeaves.Count > 0);
        }
コード例 #5
0
        internal void RemoveTail()
        {
            if (PreviousElement == null || ChildrenCount > 0)
            {
                return;
            }

            StackElement <SYMBOL_ENUM, TREE_NODE> prev = PreviousElement;

            TryDetach();
            prev.RemoveTail();
        }
コード例 #6
0
 private IEnumerable <StackElement <SYMBOL_ENUM, TREE_NODE> > removeLastWhile(ref StackElement <SYMBOL_ENUM, TREE_NODE> leaf, Func <StackElement <SYMBOL_ENUM, TREE_NODE>, bool> predicate)
 {
     if (leaf == null || !predicate(leaf))
     {
         return(emptyStack);
     }
     else
     {
         var last = leaf;
         leaf = leaf.PreviousElement;
         last.TryDetach();
         return(removeLastWhile(ref leaf, predicate).Concat(last));
     }
 }
コード例 #7
0
        // in current form, Add assumes there will be added something because of shift, and then because of reduce
        // i.e. it won't handle correctly two reduces in a row (for the same stack -- currentLeaf)
        public StackElement <SYMBOL_ENUM, TREE_NODE> Add(bool inputAdvance,
                                                         AttachPoint <SYMBOL_ENUM, TREE_NODE> attachPoint,
                                                         StackElement <SYMBOL_ENUM, TREE_NODE> stackElement)
        {
            attachPoint.FixNulls(inputAdvance, currentStackLeaf);

            if (attachPoint.Recorder != null)
            {
                attachPoint.Recorder.RecorderLink.Add(stackElement.RecorderLink);
            }

            // do not change real input index, because we might fork
            // however, after this we cannot really do anything with input now, do we?
            stackElement.InputIndex = input.Offset + (inputAdvance ? 1 : 0);
            stackElement.Id         = ++stackElementIdCounter;



            if (attachPoint.Stack == null)
            {
                if (currentStackForkId.HasValue)
                {
                    stackElement.ForkId = currentStackForkId.Value;
                }
                else
                {
                    stackElement.ForkId = ++totalForkCounter;
                }
            }
            else
            {
                attachPoint.Stack.Add(stackElement);
                if (attachPoint.Stack.ChildrenCount == 1)
                {
                    // it could be Add after reduce (removing),
                    // so we don't want to get id from middle of stack, instead we use current id
                    stackElement.ForkId = currentStackForkId.Value;
                    currentStackForkId  = null; // mark current stack id as used (because we can have fork after that)
                }
                else
                {
                    stackElement.ForkId = ++totalForkCounter;
                }
            }

            // store new stack
            stackLeaves.Enqueue(stackElement);
            return(stackElement);
        }
コード例 #8
0
 public void LoopOverStacks()
 {
     if (stackLeaves.Count == 0)
     {
         currentStackLeaf   = null;
         input.Offset       = 0;
         currentStackForkId = 0;
     }
     else
     {
         currentStackLeaf   = stackLeaves.Dequeue();
         input.Offset       = currentStackLeaf.InputIndex;
         currentStackForkId = currentStackLeaf.ForkId;
     }
 }
コード例 #9
0
 private string stackToString(StackElement <SYMBOL_ENUM, TREE_NODE> stackAnchor)
 {
     if (stackAnchor == null)
     {
         return("[0]");
     }
     else
     {
         return("[" + stackAnchor.ForkId + "] "
                + String.Join(" ", stackAnchor.Iterate().TakeTail(historyHorizon).Select(it =>
                                                                                         (it.IsRecoverable ? "@" : "")
                                                                                         + (it.IsRecovered ? "!" : "")
                                                                                         + symbolsRep.Get(it.Symbol)
                                                                                         + (it.ValueContent != null ? "=" + it.ValueContent : "")
                                                                                         + "(" + it.NodeIndex + ")")));
     }
 }
コード例 #10
0
        public void FixNulls(bool inputAdvance, StackElement <SYMBOL_ENUM, TREE_NODE> currentStackLeaf)
        {
            // Stack can be null for reduce move as well, but if it is for reduce we cannot "fix" null
            // because we are reducing stack to zero, so we cannot attach to anything
            if (Stack == null && inputAdvance) // comes from shift move
            {
                Stack = currentStackLeaf;
            }

            // since recorder increases in all cases (shift, reduce) we can always fix the null
            // btw. null is the effect the parser stack tail was empty
            // (because we reduced by empty rule or because we just started parsing)
            if (Recorder == null)
            {
                Recorder = currentStackLeaf;
            }
        }
コード例 #11
0
 private IEnumerable <StackElement <SYMBOL_ENUM, TREE_NODE> > takeLast(ref StackElement <SYMBOL_ENUM, TREE_NODE> leaf, int count)
 {
     if (count == 0)
     {
         return(emptyStack);
     }
     else if (leaf == null)
     {
         throw new ArgumentException("PARSER INTERNAL ERROR: Stack is not that long: " + Stack.Count() + " vs. " + count);
     }
     else
     {
         StackElement <SYMBOL_ENUM, TREE_NODE> last = leaf;
         leaf = leaf.PreviousElement;
         return(takeLast(ref leaf, count - 1).Concat(last));
     }
 }
コード例 #12
0
        private bool makeReduction(ActionRecoveryEnum findAction, NfaCell <SYMBOL_ENUM, TREE_NODE> reduceItem,
                                   AttachPoint <SYMBOL_ENUM, TREE_NODE> attachPoint,
                                   IEnumerable <StackElement <SYMBOL_ENUM, TREE_NODE> > stackTail)
        {
            // if taboo symbol was used, ignore this reduction
            if (reduceItem.ProductionTabooSymbols != null &&
                reduceItem.ProductionTabooSymbols.SyncZip(stackTail.Select(it => it.MarkedWith)).Any(it => it.Item1.Contains(it.Item2)))
            {
                if (options.Trace)
                {
                    parseLog.Last.Value.Reduced.Add(ParseHistory.Reduce + " rejected (taboo filter)");
                }
                return(false);
            }

            string trace = null;

            if (options.Trace)
            {
                trace = ParseHistory.Reduce + " " + symbolsRep.Get(reduceItem.LhsSymbol);
            }

            // no recovery from reduce (reduce cannot be recovered by itself, only by prior recovery point)
            StackElement <SYMBOL_ENUM, TREE_NODE> added = addToStack(Command.Reduced(reduceItem),
                                                                     attachPoint: attachPoint,
                                                                     symbol: reduceItem.LhsSymbol,
                                                                     markWith: reduceItem.ProductionMark,
                                                                     text: String.Join(textInfoSep, stackTail.Select(it => it.TextInfo)),
                                                                     userObject: new Option <object>(),
                                                                     recovered: findAction == ActionRecoveryEnum.Recovered);

            if (options.Trace)
            {
                parseLog.Last.Value.Reduced.Add(trace + "[" + added.ForkId + "]");
            }

            return(true);
        }
コード例 #13
0
        private void makeShift(ActionRecoveryEnum findAction)
        {
            if (options.Trace)
            {
                parseLog.Last.Value.Shifted = ParseHistory.Shift;
            }

            // do not advance input here, because we can fork after that
            ITokenMatch <SYMBOL_ENUM> input_head = stackMaster.InputHead;

            StackElement <SYMBOL_ENUM, TREE_NODE> added = addToStack(Command.Shifted <SYMBOL_ENUM, TREE_NODE>(),
                                                                     attachPoint: new AttachPoint <SYMBOL_ENUM, TREE_NODE>(lastOfStackOrNull, //this makes it compatible with anchor of reduction
                                                                                                                           lastOfStackOrNull),
                                                                     symbol: input_head.Token,
                                                                     markWith: Productions.NoMark,
                                                                     text: input_head.Text,
                                                                     userObject: new Option <object>(input_head.Value),
                                                                     recovered: findAction == ActionRecoveryEnum.Recovered);

            if (options.Trace)
            {
                parseLog.Last.Value.Shifted += "[" + added.ForkId + "]";
            }
        }
コード例 #14
0
 public AttachPoint(StackElement <SYMBOL_ENUM, TREE_NODE> stack,
                    StackElement <SYMBOL_ENUM, TREE_NODE> recorder)
 {
     this.Stack    = stack;
     this.Recorder = recorder;
 }
コード例 #15
0
 internal void Add(StackElement <SYMBOL_ENUM, TREE_NODE> child)
 {
     ++ChildrenCount;
     child.PreviousElement = this;
 }