Exemplo n.º 1
0
        static ParseItemSet Closure(SegmentSetProvider provider, ParseItemSet kernelItems)
        {
            var lookup     = new Dictionary <ParseItem, bool>();
            var itemsToAdd = new Queue <ParseItem>();

            EnqueueRange(itemsToAdd, kernelItems);

            while (itemsToAdd.Count > 0)
            {
                var item       = itemsToAdd.Dequeue();
                var production = item.Production;

                if (!lookup.ContainsKey(item))
                {
                    lookup.Add(item, true);

                    if (item.Position < production.Segments.Length)
                    {
                        var next = production.Segments[item.Position];

                        if (!next.IsTerminal)
                        {
                            EnqueueRange(itemsToAdd, provider.CreateParseItems(next));
                        }
                    }
                }
            }

            return(ParseItemSet.New(lookup.Keys));
        }
Exemplo n.º 2
0
        static ParseGraph ConstructGraph(Config config, SegmentSetProvider provider)
        {
            var graphBuilder = new Graph.Builder();
            var map          = new Dictionary <ParseItemSet, Graph.State>();
            var queue        = new Queue <Graph.State>();

            var startStates      = new List <Graph.State>();
            var topLevelSegments = new List <Segment>();

            foreach (var segment in provider.InitialSegments)
            {
                var initialKernel = ParseItemSet.New(provider.CreateParseItems(segment));
                var initialState  = graphBuilder.NewState(true, Closure(provider, initialKernel));
                map.Add(initialKernel, initialState);
                queue.Enqueue(initialState);
                startStates.Add(initialState);
                topLevelSegments.Add(new Segment(segment.Name, false));
            }

            while (queue.Count > 0)
            {
                var fromState = queue.Dequeue();

                foreach (var pair in fromState.Label.GetTransitionKernels())
                {
                    if (!map.TryGetValue(pair.Value, out var toState))
                    {
                        toState = graphBuilder.NewState(false, Closure(provider, pair.Value));
                        map.Add(pair.Value, toState);
                        queue.Enqueue(toState);
                    }

                    graphBuilder.AddTransition(fromState, toState, pair.Key);
                }
            }

            var graph = graphBuilder.Graph;

            PopulateLookaheads(provider, graph);
            ParseGraphOptimiser.Optimise(config, graphBuilder);

            return(new ParseGraph(graph, topLevelSegments.ToArray(), startStates.ToArray()));
        }