Example #1
0
        public bool FindErrorRecoveryState() {
            // pop states until one found that accepts error token
            while (true) {

                // shift
                int action;
                if (_currentState.Actions != null && _currentState.Actions.TryGetValue(_errorToken, out action) && action > 0) {
                    return true;
                }

                // LogState("Error, popping state", _stateStack.Peek(1));

                _stack.Pop();

                if (_stack.IsEmpty) {
                    // Log("Aborting: didn't find a state that accepts error token");
                    return false;
                } else {
                    _currentState = _stack.PeekState(1);
                }
            }
        }
Example #2
0
        private void Shift(int stateId) {
            _currentState = _states[stateId];

            _stack.Push(_currentState, GetTokenValue(), GetTokenSpan());

            if (_recovering) {
                if (_nextToken != _errorToken) {
                    _tokensSinceLastError++;
                }

                if (_tokensSinceLastError > 5) {
                    _recovering = false;
                }
            }

            if (_nextToken != _eofToken) {
                _nextToken = 0;
            }
        }
Example #3
0
        private void Reduce(int ruleId) {
            int ruleDef = _rules[ruleId];
            int rhsLength = GetRuleRhsLength(ruleDef);

            LogBeforeReduction(ruleId, rhsLength);

            if (rhsLength == 0) {
                // The location span for an empty production will start with the
                // beginning of the next lexeme, and end with the finish of the
                // previous lexeme.  This gives the correct behaviour when this
                // nonsense value is used in later Merge operations.
                yyloc = MergeLocations(_lastTokenSpan, GetTokenSpan());
            } else if (rhsLength == 1) {
                yyloc = _stack.PeekLocation(1);
            } else {
                TLocation at1 = GetLocation(rhsLength);
                TLocation atN = GetLocation(1);
                yyloc = MergeLocations(at1, atN);
            }

            DoAction(ruleId);

            _stack.Pop(rhsLength);

            var currentState = _stack.PeekState(1);

            int gotoState;
            if (currentState.GotoStates.TryGetValue(GetRuleLhsNonterminal(ruleDef), out gotoState)) {
                LogBeforeGoto(gotoState, ruleId);
                currentState = _states[gotoState];
            }

            _stack.Push(currentState, yyval, yyloc);

            _currentState = currentState;
        }
Example #4
0
        private bool Parse() {

            _nextToken = 0;
            _currentState = _states[0];
            _lastTokenSpan = GetTokenSpan();

            _stack.Push(_currentState, yyval, yyloc);

            while (true) {

                LogStateEntered();
                
                int action = _currentState.DefaultAction;

                if (_currentState.Actions != null) {
                    if (_nextToken == 0) {

                        // We save the last token span, so that the location span
                        // of production right hand sides that begin or end with a
                        // nullable production will be correct.
                        _lastTokenSpan = GetTokenSpan();
                        _nextToken = GetNextToken();
                    }

                    LogNextToken(_nextToken);

                    _currentState.Actions.TryGetValue(_nextToken, out action);
                }

                if (action > 0) {
                    LogBeforeShift(action, _nextToken, false);
                    Shift(action);
                } else if (action < 0) {
                    Reduce(-action - 1);

                    // accept
                    if (action == -1) {
                        return true;
                    }
                } else if (action == 0) {
                    // error
                    if (!ErrorRecovery()) {
                        return false;
                    }
                }
            }
        }
Example #5
0
        // TODO: possible optimization: build a single dictionary mapping all goto and actions for all states.
        // This (custom) dict might be precomputed by generator and allocated in a single array.
        // This would safe rellocation of ~650kB of Dictionary.Entry[] since the array would be considered a large object.
        private State[]/*!*/ BuildStates(short[]/*!*/ data) {
            Debug.Assert(data != null && data.Length > 0);

            // 
            // serialized structure:
            //
            // length, 
            // (
            //   (action_count: positive short, goto_count: positive short) | (action_count: negative short), 
            //   (key: short, value: short){action_count} | (defaultAction: short), 
            //   (key: short, value: short){goto_count} 
            // ){length}
            //
            // where action_count is 
            //   > 0  ... a number of items in actions hashtable 
            //   == 0 ... there is no action hashtable, but there is a single integer default action id
            //   < 0  ... there is no action hashtable and no goto table, the value is default action id
            // goto_count is a number of items in gotos hashtable,
            //   zero means there is no goto hashtable
            //

            int offset = 0;
            State[] states = new State[data[offset++]];

            for (int i = 0; i < states.Length; i++) {
                int actionCount = data[offset++];

                Dictionary<int, int> actions = null;
                Dictionary<int, int> gotos = null;
                int defaultAction = 0;

                if (actionCount >= 0) {
                    int gotoCount = data[offset++];
                    Debug.Assert(gotoCount >= 0);

                    if (actionCount > 0) {
                        actions = new Dictionary<int, int>(actionCount);
                        for (int j = 0; j < actionCount; j++) {
                            actions.Add(data[offset++], data[offset++]);
                        }
                    } else {
                        defaultAction = data[offset++];
                    }

                    if (gotoCount > 0) {
                        gotos = new Dictionary<int, int>(gotoCount);
                        for (int j = 0; j < gotoCount; j++) {
                            Debug.Assert(data[offset] < 0);
                            gotos.Add(-data[offset++], data[offset++]);
                        }
                    }
                } else {
                    defaultAction = actionCount;
                }

                states[i] = new State(actions, gotos, defaultAction);
#if DEBUG
                states[i].Id = i;
#endif
            }

            return states;
        }
Example #6
0
        internal void InitializeMembersFrom(RubyModule/*!*/ module) {
            ContractUtils.RequiresNotNull(module, "module");

#if !SILVERLIGHT // missing Clone on Delegate
            if (module.DeclaresGlobalConstants || module._clrConstants != null && _constants == null) {
#endif
                EnsureInitialized();
                module.EnsureInitialized();
#if !SILVERLIGHT
            } else {
                _state = module._state;
                _initializer = (module._initializer != null) ? (Action<RubyModule>)module._initializer.Clone() : null;
            }
#endif

            if (module.DeclaresGlobalConstants) {
                Debug.Assert(module._constants == null && module._clrConstants == null);
                Debug.Assert(_constants != null);
                _constants.Clear();
                foreach (KeyValuePair<SymbolId, object> constant in _context.TopGlobalScope.Items) {
                    _constants.Add(SymbolTable.IdToString(constant.Key), constant.Value);
                }
            } else {
                _constants = (module._constants != null) ? new Dictionary<string, object>(module._constants) : null;

                // copy namespace members:
                if (module._clrConstants != null) {
                    Debug.Assert(_constants != null);
                    foreach (KeyValuePair<SymbolId, object> constant in module._clrConstants.SymbolAttributes) {
                        _constants.Add(SymbolTable.IdToString(constant.Key), constant.Value);
                    }
                }
            }

            _methods = (module._methods != null) ? new Dictionary<string, RubyMemberInfo>(module._methods) : null;
            _classVariables = (module._classVariables != null) ? new Dictionary<string, object>(module._classVariables) : null;
            _mixins = ArrayUtils.Copy(module._mixins);

            // dependentModules - skip
            // tracker - skip, .NET members not copied

            Updated("InitializeFrom");
        }
Example #7
0
        private void InitializeMembers() {
            Debug.Assert(_state == State.Uninitialized);
            Debug.Assert(_constants == null && _methods == null, "Tables are null until initialized");

            Debug.Assert(_context.ObjectClass != null, "ObjectClass should already be initialized");

            if (DeclaresGlobalConstants) {
                _constants = null;
            } else {
                _constants = new Dictionary<string, object>();
            }

            _methods = new Dictionary<string, RubyMemberInfo>();

            Utils.Log(_name ?? "<anonymous>", "INITED");
            
            _state = State.Initializing;
            try {
                if (_initializer != null) {
                    _initializer(this);
                }
            } finally {
                _initializer = null;
                _state = State.Initialized;
            }
        }
Example #8
0
        internal RubyModule(RubyContext/*!*/ context, string name, Action<RubyModule> initializer,
            IAttributesCollection clrConstants, TypeTracker tracker) {
            Assert.NotNull(context);

            _context = context;
            _name = name;
            _state = State.Uninitialized;
            _mixins = EmptyArray;
            _initializer = initializer;
            _version = Interlocked.Increment(ref _globalVersion);
            _clrConstants = clrConstants;
            _tracker = tracker;
        }