예제 #1
0
 public int GetHashCode(SingleState <SYMBOL_ENUM, TREE_NODE> obj)
 {
     return(obj.LhsSymbol.GetHashCode()
            ^ obj.RhsSeenCount // this is the number already
            ^ obj.RhsUnseenSymbols.SequenceHashCode()
            ^ (obj.Production.UserAction == null ? 0 : obj.Production.UserAction.GetHashCode()));
 }
예제 #2
0
        public static SingleState <SYMBOL_ENUM, TREE_NODE> CreateShiftStateFrom(int nodeId, int stateId, SingleState <SYMBOL_ENUM, TREE_NODE> source)
        {
            var result = new SingleState <SYMBOL_ENUM, TREE_NODE>(Tuple.Create(nodeId, stateId), source.RhsSeenCount + 1, source.Production);

            result.shiftParents.Add(source);
            return(result);
        }
예제 #3
0
        public bool Equals(SingleState <SYMBOL_ENUM, TREE_NODE> x, SingleState <SYMBOL_ENUM, TREE_NODE> y)
        {
            if (Object.ReferenceEquals(x, y))
            {
                return(true);
            }

            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            {
                return(false);
            }

            // this is classic take -- just compare production and stage of it, that's all
            if (x.Production == y.Production &&
                x.RhsSeenCount == y.RhsSeenCount)
            {
                return(true);
            }

            // this is custom compare (it is NOT a replacement!) -- it focuses on comparing the execution of the user action
            // please note, that the active parameters of the user action plays crucial role here
            if ((x.LhsSymbol.Equals(y.LhsSymbol)
                 // this condition can be dropped __WHEN__ parser recovery no longer relies on that data (the number of seen symbols)
                 && x.RhsSeenCount == y.RhsSeenCount
                 // only unseen symbols really matters, because what we've already saw is a history and does not influence present state
                 && x.RhsUnseenSymbols.SequenceEqual(y.RhsUnseenSymbols)
                 // user action EXECUTION has to be identical
                 && NaiveLanguageTools.Parser.UserActionInfo.ExecutionEquals(x.Production.UserAction, x.RhsSeenCount,
                                                                             y.Production.UserAction, y.RhsSeenCount)))
            {
                return(true);
            }

            return(false);
        }
예제 #4
0
        private void addClosures(SingleState <SYMBOL_ENUM, TREE_NODE> sourceState,
                                 Productions <SYMBOL_ENUM, TREE_NODE> productions,
                                 int lookaheadWidth)
        {
            if (!sourceState.HasIncomingSymbol)
            {
                return;
            }

            // find productions for that symbol
            foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions.FilterByLhs(sourceState.IncomingSymbol))
            {
                SingleState <SYMBOL_ENUM, TREE_NODE> existing;
                // getting "impostor" object just for sake of FAST comparison (no memory allocations)
                if (items.TryGetValue(SingleState <SYMBOL_ENUM, TREE_NODE> .CreateClosureComparisonStateFrom(prod), out existing)) // [@STATE_EQ]
                {
                    // switching closure links to existing state
                    existing.AddClosureParent(sourceState);
                }
                else
                {
                    // creating real state object
                    var state = SingleState <SYMBOL_ENUM, TREE_NODE> .CreateClosureStateFrom(InternalId, items.Count, sourceState, prod);

                    items.Add(state);
                    addClosures(state, productions, lookaheadWidth); // recursive call
                }
            }
        }
예제 #5
0
        public static SingleState <SYMBOL_ENUM, TREE_NODE> CreateClosureStateFrom(int nodeId,
                                                                                  int stateId,
                                                                                  SingleState <SYMBOL_ENUM, TREE_NODE> source,
                                                                                  Production <SYMBOL_ENUM, TREE_NODE> production)
        {
            var result = new SingleState <SYMBOL_ENUM, TREE_NODE>(Tuple.Create(nodeId, stateId), 0, production);

            result.closureParents.Add(source);
            return(result);
        }
예제 #6
0
        public bool Merge(SingleState <SYMBOL_ENUM, TREE_NODE> incoming, Func <int> timeStamp)
        {
            // here do not merge closure, because closures are inter-node links
            // and the incoming state will be deleted -- thus all inter-node links
            // would be invalid (in sense of grammar)
            shiftParents.AddRange(incoming.shiftParents);

            if (!AfterLookaheads.Add(incoming.AfterLookaheads))
            {
                return(false);
            }

            lookaheadsStamp = timeStamp();
            return(true);
        }
예제 #7
0
 public void AddClosureParent(SingleState <SYMBOL_ENUM, TREE_NODE> state)
 {
     this.closureParents.Add(state);
 }