/// <summary> /// Método para geração do automato baseando-se na gramática /// </summary> private void GenerateAutomata() { #region Gerar o primeiro nó do automato //Regra no formato //S:símbolo inicial string baseRule = ascendentSymbol + ":"; string ascendentRule = baseRule + NonTerminal.InitialSymbol; //Primeiro nó do automato é só S //Não é final InitialState = new State <string, Symbol>(ascendentSymbol); StateHash.Add(ascendentRule, InitialState); //Regra no fomato //S:. símbolo inicial //Trata-se da primeira regra com ponto string initialRule = baseRule + ". " + NonTerminal.InitialSymbol.Value; GrammarState initialSymbolState = new GrammarState(initialRule); StateHash.Add(initialRule, initialSymbolState); //Cria a transição em vazio do estado inicial para o estado do símbolo inicial //Adiciona a regra à lista de transições do estado inicial InitialState.AddTransiction(Terminal.Empty, initialSymbolState); //Chama o método que recursivamente vai gerar os outros estados GenerateTransictions(initialSymbolState, InitialState); //Gera a lista dos estados GenerateStateList(); #endregion }
public override bool Equals(object obj) { if (obj is GrammarState) { GrammarState anotherState = (GrammarState)obj; return(anotherState.StateValue.Equals(StateValue) && (anotherState.IsFinal == IsFinal)); } return(false); }
/// <summary> /// Retorna o estado correspondente ao fecho. /// </summary> /// <returns>O estado correspondente.</returns> new public GrammarState PowerSetToState() { GrammarState newState = new GrammarState(State); foreach (StateTransiction <string, Symbol> transiction in Transictions) { if (!transiction.Transiction.Value.Equals(Terminal.Empty)) { newState.AddTransiction(transiction); } } return(newState); }
/// <summary> /// Método para iterar sobre o hash de estados e adicioná-los à lista de estados /// </summary> public void GenerateStateList() { foreach (string key in StateHash.Keys) { GrammarState state = GrammarState.ConvertFrom(StateHash[key]); if (state != null) { if (!StateList.Contains(state)) { StateList.Add(state); } } } }
/// <summary> /// Converte um estado genérico com T = string e E = símbolo para um GrammarState /// </summary> /// <param name="state"></param> /// <returns></returns> public static GrammarState ConvertFrom(State <string, Symbol> state) { if (state == null) { return(null); } GrammarState newState = new GrammarState(state.StateValue, state.IsFinal); List <StateTransiction <string, Symbol> > transictions = state.Transictions; foreach (StateTransiction <string, Symbol> transiction in transictions) { newState.AddTransiction(transiction); } return(newState); }
public GrammarState(GrammarState anotherState) { StateValue = anotherState.StateValue; IsFinal = anotherState.IsFinal; }
/// <summary> /// Gera o fecho transitivo de um determinado estado. Realiza as inserções no hash. /// </summary> /// <param name="state">Estado do fecho transitivo</param> /// <param name="transictionList">Lista dos possíveis valores para a transição de estados</param> /// <param name="nullSymbol">Símbolo representando do nulo/vazio dos automatos</param> /// <param name="hash">Hash dos fechos já criados</param> /// <returns>Fecho transitivo do estado</returns> private static GrammarPowerSet GeneratePowerSet(GrammarState state, List <Symbol> transictionList, Terminal nullSymbol, Dictionary <GrammarState, GrammarPowerSet> hash) { GrammarPowerSet powerSet = new GrammarPowerSet(state); if (hash.ContainsKey(state)) { return(null); } hash.Add(state, powerSet); foreach (Symbol symbol in transictionList) { if (!symbol.Equals(Terminal.Empty)) { List <GrammarState> reachable = state.ReachableStatesBy(symbol); if (reachable != null) { if (reachable.Count > 1) { //Adiciona transições de estados com recursão if (!reachable[0].StateValue.Equals(reachable[1].StateValue)) { //Um pouco gambiarra //Busca os estados únicos na lista do reachable, porque as vezes o mesmo estado aparece mais de uma vez Dictionary <string, GrammarState> uniqueHash = new Dictionary <string, GrammarState>(); foreach (GrammarState reachableState in reachable) { if (!uniqueHash.ContainsKey(reachableState.StateValue)) { uniqueHash.Add(reachableState.StateValue, reachableState); } } //Sempre devem vir no estilo //A := B (final) //A := B C (não final) //ou ambos são finais, então eu pego o que tem a maior regra GrammarState unionState = null; //Itero o hash; A prioridade é o estado que não é final //Caso não tenha estado não-final, fica o com a maior regra foreach (string key in uniqueHash.Keys) { GrammarState reachableState = uniqueHash[key]; if (!reachableState.IsFinal) { unionState = reachableState; } if (unionState == null) { unionState = reachableState; } else { if (unionState.StateValue.Length < reachableState.StateValue.Length) { unionState = reachableState; } } } //Por garantia unionState.IsFinal = true; //Realiza o fecho a partir desse estado powerSet.AddTransictionToPowerSet(symbol, unionState); } else { //Se são iguais, então basta inserir um deles powerSet.AddTransictionToPowerSet(symbol, reachable[0]); } } else { //Adiciona transição no valor para o estaddo powerSet.AddTransictionToPowerSet(symbol, reachable[0]); } } } } //Itera sobre os estados que não contém fecho e os gera foreach (StateTransiction <string, Symbol> transiction in powerSet.Transictions) { GrammarState nextState = GrammarState.ConvertFrom(transiction.NextState); if (!hash.ContainsKey(nextState)) { GeneratePowerSet(nextState, transictionList, nullSymbol, hash); } } return(powerSet); }
/// <summary> /// Construtor default de um automato de gramática. Criado a partir da gramática setada em Symbol. /// </summary> public GrammarDeterministicAutomata() { GrammarNonDeterministicAutomata nonDeterministic = new GrammarNonDeterministicAutomata(); //Cria uma referência aos terminais para comparações Dictionary <string, Terminal> terminalHash = Symbol.TerminalHash; Dictionary <string, NonTerminal> nonTerminalHash = Symbol.NonTerminalHash; GrammarState initialState = GrammarState.ConvertFrom(nonDeterministic.InitialState); Dictionary <GrammarState, GrammarPowerSet> hash = new Dictionary <GrammarState, GrammarPowerSet>(); List <Symbol> transictionList = new List <Symbol>(); transictionList.AddRange(Symbol.TerminalList); transictionList.AddRange(Symbol.NonTerminalList); //Retorna com o hash completo com todos os fechos GrammarPowerSet initialPowerSet = GeneratePowerSet(initialState, transictionList, Terminal.Empty, hash); //Carrega o valor do estado do primeiro fecho transitivo initialState = initialPowerSet.PowerSetToState(); //Carrega a lista com os estados do fecho transitivo criado List <GrammarState> stateList = new List <GrammarState>(); foreach (GrammarState state in hash.Keys) { GrammarPowerSet powerSet = hash[state]; stateList.Add(powerSet.PowerSetToState()); } InitialState = initialPowerSet.PowerSetToState(); //StateList = stateList; foreach (GrammarState state in stateList) { StateList.Add(state.ConvertTo()); StateHash.Add(state.StateValue, state); } TransictionList = transictionList; NullSymbol = Terminal.Empty; #region código abandonado //List<Symbol> transictionList = new List<Symbol>(); //foreach (string name in terminalHash.Keys) //{ // transictionList.Add(terminalHash[name]); //} //foreach (string name in nonTerminalHash.Keys) //{ // transictionList.Add(nonTerminalHash[name]); //} //Automata<string, Symbol> afd = Automata<string, Symbol>.AFNtoAFD(afn, transictionList, Terminal.Empty); //InitialState = afd.InitialState; //StateList = afd.StateList; //TransictionList = afd.TransictionList; //NullSymbol = afd.NullSymbol; ////Popular o hash //foreach(State<string, Symbol> afdState in StateList) //{ // StateHash.Add(afdState.StateValue, afdState); //} #endregion }
public GrammarPowerSet(GrammarState state) : base(state) { _state = new GrammarState(state); }
/// <summary> /// Método para gerar as transições a partir de regra de um dado estado /// </summary> /// <param name="state">Novo estado</param> /// <param name="before">Estado que está apontando diretamente para este novo estado</param> private void GenerateTransictions(State <string, Symbol> state, State <string, Symbol> before) { //StateValue é, no caso, a regra com o ponto Symbol symbol = GetNextToPoint(state.StateValue); if (symbol != null) { //Preciso verificar se já existe transição para aquele símbolo, se já existir, não faz nada if (before.TransictionIn(symbol) != null) { return; } if (symbol is NonTerminal) { #region Regra 2 NonTerminal nonTerminal = (NonTerminal)symbol; //Regra 2 //Criar uma nova regra para as substituições do não terminal e adiciona as transições em vazio para elas string nonTerminalRule = nonTerminal.Rule; string[] parameters = new string[] { }; if (nonTerminalRule.Contains("|")) { parameters = nonTerminalRule.Split('|'); } else { parameters = new string[] { nonTerminalRule }; } bool exists = false; GrammarState newState = null; foreach (string ruleElement in parameters) { //Criar apenas um estado para a substituição do não terminal string pointedRule = nonTerminal.Value + ":. " + ruleElement; //Verifica se o estado já existe exists = false; newState = null; if (StateHash.ContainsKey(pointedRule)) { newState = (GrammarState)StateHash[pointedRule]; exists = true; } else { newState = new GrammarState(pointedRule); StateHash.Add(pointedRule, newState); } state.AddTransiction(Terminal.Empty, newState); //Se o estado não existia ainda, gerar as transições a partir dele if (!exists) { GenerateTransictions(newState, state); } //Mover o point string newRule = MovePointToRight(state.StateValue); exists = false; newState = null; if (StateHash.ContainsKey(newRule)) { newState = (GrammarState)StateHash[newRule]; exists = true; } else { newState = new GrammarState(newRule); StateHash.Add(newRule, newState); } if (!exists) { state.AddTransiction(nonTerminal, newState); GenerateTransictions(newState, state); } } if (nonTerminal.FirstContainsEmpty()) { state.IsFinal = true; } #endregion } else { Terminal terminal = (Terminal)symbol; if (terminal.Equals(Terminal.FinalPoint)) { //Estado de item completo state.IsFinal = true; } else { if (terminal.Equals(Terminal.Empty)) { //Estado anterior é final before.IsFinal = true; } #region Regra 3 //Regra 3 //Mover o ponto, criar um estado com a nova regra e a transição será neste terminal string newRule = MovePointToRight(state.StateValue); bool exists = false; GrammarState newState = null; if (StateHash.ContainsKey(newRule)) { newState = (GrammarState)StateHash[newRule]; exists = true; } else { newState = new GrammarState(newRule); StateHash.Add(newRule, newState); } state.AddTransiction(terminal, newState); if (!exists) { GenerateTransictions(newState, state); } } #endregion } } }