Exemplo n.º 1
0
        public void GenerateContinuations()
        {
            foreach (var continuation in Key.Where(x => !x.IsFinished).GroupBy(x => x.NextPattern))
            {
                var key = new StateKey(continuation.Select(x => x.NextProduction), AllProductions);
                Continuations.Add(continuation.Key, Machine.GetOrCreateNode(key));
            }

            var finished = Key.Where(x => x.IsFinished).ToArray();

            if (finished.Length == 1)
            {
                CompletedProduction = finished[0];
            }
            else if (finished.Length > 1)
            {
                var maxValue    = finished.Max(x => x.Precedence.Value);
                var maxFinished = finished.Where(x => x.Precedence.Value == maxValue).ToArray();
                if (maxFinished.Length == 1)
                {
                    CompletedProduction = finished.OrderBy(x => x.Precedence.Value).First();
                }
                else
                {
                    // TODO: better error message
                    throw new InvalidOperationException("Grammar is ambiguous");
                }
            }
        }
Exemplo n.º 2
0
 public void Closure(StateProduction p, ref State 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;
         //TODO: Colocar o número da redução
     }
     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 && !actualState.ClosureSymbols.Exists(i => i.Value == s.Value))
         {
             //PEGO AS PRODUÇÕES DESSE NÃO TERMINAL
             var nonTerminalProductions = productions.Where(t => t.Producer.Value == s.Value);
             //CRIEI UM NOVO StateProduction para o estado, que é igual à production desse não terminal
             foreach (var VARIABLE in nonTerminalProductions)
             {
                 StateProduction sp = new StateProduction();
                 sp.Production = VARIABLE;
                 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
 }
Exemplo n.º 3
0
        public void GenerateTable(DataGridView gridView)
        {
            int          NextStateNumber = 0;                                 //Número do próximo estado
            List <State> states          = new List <State>();                //Estados
            var          productions     = _syntactic.GetSingleProductions(); //Pega todas as produções
            var          firstProduction = productions.First();
            //Inicio com o primeiro estado (0)

            var firstState = new State();

            firstState.Number = NextStateNumber;
            NextStateNumber++;

            //Adiciona a primeira produção (Slinha)
            var firstStateProduction = new StateProduction();

            firstStateProduction.Production = firstProduction;
            //firstStateProduction.Marked.Symbol = firstProduction.Produced.First.Value;
            firstState.Productions.Add(firstStateProduction);
            states.Add(firstState);

            while (states.Exists(e => e.Done == false))
            {
                var actualState = states.First(w => w.Done == false);
                while (actualState.Productions.Exists(u => u.Checked == false))
                {
                    var p = actualState.Productions.First(i => i.Checked == false);
                    if (!p.Checked)
                    {
                        Closure(p, ref actualState, productions);
                    }
                }
                if (!actualState.Productions.Exists(g => g.Checked == false))
                {
                    actualState.Done = true;
                    //TERMINOU O FECHO, CRIA OS PRÓXIMOS ESTADOS
                }

                var grouped = actualState.Productions.Where(e => e.Action == ActionType.State).GroupBy(item => item.Marked.Symbol.Value);

                foreach (var item in grouped)
                {
                    bool similarTransitionFound = false;
                    //VERIFICA SE JÁ EXISTE ALGUMA TRANSIÇÃO SIMILAR
                    // item = transições para o mesmo estado, agrupadas
                    foreach (var VARIABLE in states.Where(e => !e.Equals(actualState)))
                    {
                        var stateGroupedProductions = VARIABLE.Productions.GroupBy(x => new { x.ActionNumber });
                        foreach (var gp in stateGroupedProductions)
                        {
                            if (gp.ToList().Count == item.ToList().Count() && gp.All(a => a.Action == ActionType.State))
                            {
                                bool flag = true;
                                //SÃO DO MESMO TAMANHO, POSSO VERIFICAR SE SÃO IGUAIS
                                for (int i = 0; i < gp.ToList().Count; i++)
                                {
                                    if (actualState.Number == 4)
                                    {
                                    }
                                    if (!(gp.ToList()[i].Production.Equals(item.ToList()[i].Production)) ||
                                        !(gp.ToList()[i].Marked.Index == item.ToList()[i].Marked.Index))
                                    {
                                        flag = false;
                                    }
                                }
                                if (flag)
                                {
                                    similarTransitionFound = true;
                                    foreach (var va in item)
                                    {
                                        va.ActionNumber = gp.First().ActionNumber;
                                    }
                                    break;
                                }
                            }
                        }
                        if (similarTransitionFound)
                        {
                            break;
                        }
                    }
                    if (!similarTransitionFound)
                    {
                        var newState = new State();
                        newState.Number = NextStateNumber;

                        foreach (var VARIABLE in item)
                        {
                            newState.Productions.Add(new StateProduction()
                            {
                                Production = VARIABLE.Production,
                                Marked     = new MarkedSymbol()
                                {
                                    Index  = VARIABLE.Marked.Index,
                                    Symbol = new Symbol()
                                    {
                                        Type = VARIABLE.Marked.Symbol.Type, Value = VARIABLE.Marked.Symbol.Value
                                    }
                                },
                                Checked = false
                            });
                        }
                        foreach (var pro in newState.Productions)
                        {
                            pro.Checked = false;
                        }
                        states.Add(newState);
                        foreach (var VARIABLE in item)
                        {
                            actualState.Productions.Find(w => w.Equals(VARIABLE)).ActionNumber = NextStateNumber;
                        }
                        NextStateNumber++;
                    }
                }
            }

            CreateTableMatches(states);
            Generated = true;
            //PrintTable(gridView, states);
        }
Exemplo n.º 4
0
 public ParserReduceOp(StateProduction reduction, int index)
 {
     ReduceWith = reduction;
     Index      = index;
 }