Пример #1
0
        private DotState[] BuildLr0ItemSets()
        {
            var result = new List <DotState>();

            var initialItemSet = ClosureLr0(new MutableDotItemSet
            {
                new DotItem(grammar.AugmentedProduction, 0)
                {
                    LA = TokenSet.Mutable()
                }
            });

            result.Add(new DotState(0, initialItemSet));

            bool addedStatesInRound;

            do
            {
                addedStatesInRound = false;

                for (int i = 0; i != result.Count; ++i)
                {
                    var itemSet = result[i].Items;

                    foreach (var token in GetOutTokens(itemSet))
                    {
                        var nextStateItems = GoTo(itemSet, token);

                        CollectClosureLookaheads(nextStateItems, grammar);
                        if (nextStateItems.Count == 0)
                        {
                            throw new InvalidOperationException("Internal error: next state cannot be empty");
                        }

                        var nextState = result.Find(state => state.Items.Equals(nextStateItems));
                        if (nextState == null)
                        {
                            addedStatesInRound = true;
                            nextState          = new DotState(result.Count, nextStateItems);
                            result.Add(nextState);
                        }

                        if (result[i].AddTransition(token, nextState, TokenSet))
                        {
                            addedStatesInRound = true;
                        }
                    }
                }
            }while (addedStatesInRound);

            StateSet = new BitSetType(result.Count);

            return(result.ToArray());
        }
Пример #2
0
        public bool AddTransition(int token, DotState to, IntSetType tokenSetType)
        {
            bool result;

            var existing = Transitions.FirstOrDefault(t => t.To == to);

            if (existing == null)
            {
                existing = new DotTransition(tokenSetType.Mutable(), to);
                Transitions.Add(existing);
                result = true;
            }
            else
            {
                result = !existing.Tokens.Contains(token);
            }

            existing.Tokens.Add(token);

            return(result);
        }
Пример #3
0
        private bool IsValueOnlyEpsilonReduceItem(DotItem item, DotState state, int lookahead)
        {
            if (item.Position != 0 ||
                grammar.IsStartProduction(item.ProductionId) ||
                !grammar.IsTailNullable(item) ||
                !item.LA.Contains(lookahead))
            {
                return(false);
            }

            int epsilonToken = item.Outcome;

            foreach (var parentItem in state.Items)
            {
                if (parentItem == item)
                {
                    continue;
                }

                if (parentItem.NextToken == epsilonToken)
                {
                    if (!grammar.IsTailNullable(parentItem))
                    {
                        // there is at least one rule which needs shift on epsilonToken
                        return(false);
                    }

                    if (grammar.HasFirst(parentItem.CreateNextItem(), lookahead))
                    {
                        // One of the subseqent non-terms in parentItem can start parsing with current lookahead.
                        // It means that we need tested epsilonToken production for continue parsing on parentItem.
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #4
0
 public DotTransition(MutableIntSet tokens, DotState to)
 {
     this.Tokens = tokens;
     this.To     = to;
 }