Esempio n. 1
0
        /// <summary> Recursive exploration for <see cref="Shifts"/>. </summary>
        private IEnumerable <KeyValuePair <int, ParserState.RulePosition> > AllShifts(ParserState.RulePosition rulepos, HashSet <int> alreadySeenRules)
        {
            if (alreadySeenRules != null)
            {
                if (rulepos.Position == 0 && alreadySeenRules.Contains(rulepos.Rule))
                {
                    // This rule was already seen during the recursive exploration
                    yield break;
                }
            }

            var rule = Rules.GetRule(rulepos.Rule);
            var pos  = rulepos.Position;

            // Reached the end of the rule, only reduce is allowed now
            if (rule.Steps.Count == pos)
            {
                yield break;
            }

            var step = rule.Steps[pos];

            // These values move us one step forward
            var next = new ParserState.RulePosition(rulepos.Rule, pos + 1);

            foreach (var v in step.Source)
            {
                yield return(new KeyValuePair <int, ParserState.RulePosition>(v, next));
            }

            if (step.IsTerminal)
            {
                yield break;
            }

            // Non-terminals allow stepping into any of their sub-rules, so consider
            // these as well using depth-first exploration using a hashset to avoid
            // infinite loops.

            if (alreadySeenRules == null)
            {
                alreadySeenRules = new HashSet <int>();
            }

            if (pos == 0)
            {
                alreadySeenRules.Add(rulepos.Rule);
            }

            foreach (var v in step.Source)
            {
                foreach (var kv in AllShifts(new ParserState.RulePosition(v, 0), alreadySeenRules))
                {
                    yield return(kv);
                }
            }
        }
Esempio n. 2
0
        /// <summary> All tokens that can cause this rule to reduce. </summary>
        private IEnumerable <int> Reduces(ParserState.RulePosition rulepos)
        {
            var rule = Rules.GetRule(rulepos.Rule);
            var pos  = rulepos.Position;

            // Reduce only allowed at end of rule
            if (rule.Steps.Count > pos)
            {
                return(new int[0]);
            }

            return(rule.ReducingTokens);
        }
Esempio n. 3
0
 /// <summary> Shifts for a specific position in a rule. </summary>
 /// <remarks>
 /// The value is the result of the shift, may be in the same rule or in
 /// another rule. The key is the shift source, can be either a token
 /// (in which case the action is a true SLR shift) or a rule (a SLR goto).
 /// </remarks>
 private IEnumerable <KeyValuePair <int, ParserState.RulePosition> > Shifts(ParserState.RulePosition rulepos)
 => AllShifts(rulepos, null);