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"); } } }
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 }
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); }
public ParserReduceOp(StateProduction reduction, int index) { ReduceWith = reduction; Index = index; }