コード例 #1
0
        private void AddActionEntry(Item item, Func <ActionParsingTableEntry, bool> action, string actionDescription, ItemSet set, TerminalExpressionDefinition expressionDefinition)
        {
            ParsingTableSegment segment = GetOrCreateSegment(set);

            ActionParsingTableEntry existingEntry = (ActionParsingTableEntry)segment.Entries.FirstOrDefault(x =>
                                                                                                            x is ActionParsingTableEntry apte &&
                                                                                                            apte.ActionDescription == actionDescription &&
                                                                                                            apte.ExpressionDefinition.IsEqualTo(expressionDefinition));

            if (existingEntry == null)
            {
                segment.Entries.Add(new ActionParsingTableEntry
                {
                    ItemSet = set,
                    ExpressionDefinition = expressionDefinition,
                    Items = new List <Item> {
                        item
                    },
                    ActionDescription = actionDescription,
                    Action            = action
                });
            }
            else
            {
                existingEntry.Items.Add(item);
            }
        }
コード例 #2
0
        public ParsingTable(List <ItemSet> C,
                            List <ExpressionDefinition> symbols,
                            Func <ActionParsingTableEntry, bool> shift,
                            Func <ActionParsingTableEntry, bool> accept,
                            Func <ActionParsingTableEntry, bool> reduce)
        {
            Dictionary <string, ExpressionSet> follows = new Dictionary <string, ExpressionSet>();

            // Actions
            foreach (ItemSet set in C)
            {
                foreach (Item item in set)
                {
                    if (item.ExpressionAfterDot != null &&
                        item.ExpressionAfterDot is TerminalExpressionDefinition ted)
                    {
                        AddActionEntry(item, shift, "s", set, item.ExpressionAfterDot as TerminalExpressionDefinition);
                    }
                    else if (item.SubProduction.Production.Identifier == ParserConstants.Initial)
                    {
                        TerminalExpressionDefinition expressionDefinition = item.ExpressionAfterDot as TerminalExpressionDefinition;
                        expressionDefinition = expressionDefinition ?? new TerminalExpressionDefinition()
                        {
                            TokenType = TokenType.EndMarker
                        };

                        AddActionEntry(item, accept, "a", set, expressionDefinition);
                    }
                    else if (item.IsDotIndexAtEnd())
                    {
                        string        identifier = item.SubProduction.Production.Identifier;
                        ExpressionSet follow;

                        if (!follows.TryGetValue(identifier, out follow))
                        {
                            follow = new NonTerminalExpressionDefinition()
                            {
                                Identifier = identifier
                            }.Follow();
                            follows.Add(identifier, follow);
                        }

                        foreach (TerminalExpressionDefinition ted1 in follow)
                        {
                            AddActionEntry(item, reduce, "r", set, ted1);
                        }
                    }
                }
            }

            // Goto's
            foreach (ItemSet set in C)
            {
                foreach (NonTerminalExpressionDefinition symbol in symbols.Where(x => x is NonTerminalExpressionDefinition))
                {
                    if (set.Transitions.Any(x => x.Key.IsEqualTo(symbol)))
                    {
                        GetOrCreateSegment(set).Entries.Add(new GotoParsingTableEntry
                        {
                            ExpressionDefinition = symbol,
                            ItemSet     = set,
                            Destination = set.Transitions[symbol]
                        });
                    }
                }
            }
        }