Пример #1
0
 private void btnShowFirst_Click(object sender, EventArgs e)
 {
     firstForm = new FirstForm(_semantic.GetFirstList());
     firstForm.ShowDialog();
 }
Пример #2
0
        public void Closure(LRStateProduction p, ref LRState actualState, List <SingleProduction> productions)
        {
            //VERIFICO SE PRECISO ANDAR COM O FECHO E INCREMENTO O INDEX
            p.Marked.Index++;
            if (p.Marked.Index < p.Production.Produced.Count)
            {
                p.Marked.Symbol = p.Production.Produced.ElementAt(p.Marked.Index);
            }
            //Verifica se existe um simbolo nesse index. Caso não, é uma redução
            if ((p.Marked.Index >= p.Production.Produced.Count) || ((p.Marked.Symbol.Type == SymbolType.Empty) && (p.Marked.Index + 1 == p.Production.Produced.Count)))
            {
                p.Action       = ActionType.Reduction;
                p.ActionNumber = p.Production.Number;
            }
            else
            {
                p.Marked.Symbol = p.Production.Produced.ElementAt(p.Marked.Index);
                p.Action        = ActionType.State;
                //ANDEI COM O FECHO, VERIFICO SE É UM NÃO TERMINAL
                var s = p.Marked.Symbol;
                if (s.Type == SymbolType.NonTerminal)
                {
                    //PEGO AS PRODUÇÕES DESSE NÃO TERMINAL
                    var nonTerminalProductions = productions.Where(t => t.Producer.Value == s.Value);
                    //DECIDO QUAL VAI SER O FOLLOW

                    var localFollow = new List <Symbol>();
                    if (p.Marked.Index + 1 < p.Production.Produced.Count)
                    {
                        //Pego o first desse simbolo
                        var nextSymbol = p.Production.Produced.ElementAt(p.Marked.Index + 1);
                        if (nextSymbol.Type == SymbolType.Terminal)
                        {
                            localFollow.Add(new Symbol()
                            {
                                Type = nextSymbol.Type, Value = nextSymbol.Value
                            });
                        }
                        if (nextSymbol.Type == SymbolType.NonTerminal)
                        {
                            localFollow.AddRange(_semantic.GetFirstList()
                                                 .Find(e => e.NonTerminal.Value == nextSymbol.Value).Terminals);
                        }
                    }
                    else
                    {
                        //Follow local é igual ao follow atual
                        localFollow.AddRange(p.LocalFolow);
                    }

                    //Já tenho o Follow local, verifico se preciso atualizar o follow de alguém
                    if (actualState.ClosureSymbols.Exists(i => i.Value == s.Value))
                    {
                        var actualStateNumber        = actualState.Number;
                        var pendingUpdateProductions =
                            actualState.Productions.Where(r =>
                                                          r.Production.Producer.Value == s.Value && r.GeneratorStateNumber == actualStateNumber);
                        foreach (var lrp in pendingUpdateProductions)
                        {
                            foreach (var followSymbol in localFollow)
                            {
                                if (!lrp.LocalFolow.Exists(e => e.Value == followSymbol.Value))
                                {
                                    lrp.LocalFolow.Add(followSymbol);
                                }
                            }
                        }
                    }
                    else
                    {
                        //CRIEI UM NOVO LRStateProduction para o estado, que é igual à production desse não terminal
                        foreach (var VARIABLE in nonTerminalProductions)
                        {
                            LRStateProduction sp = new LRStateProduction();
                            sp.Production = VARIABLE;
                            sp.LocalFolow.AddRange(localFollow);
                            sp.GeneratorStateNumber = actualState.Number;
                            actualState.Productions.Add(sp);
                        }
                        //SALVA QUE JÁ GEROU O FECHO DESSE NÃO TERMINAL
                        actualState.ClosureSymbols.Add(s);
                    }
                }
            }
            p.Checked = true;
            //MARCO QUE TERMINEI O FECHO DESSE
        }