/// <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
        }
Пример #2
0
 public override bool Equals(object obj)
 {
     if (obj is GrammarState)
     {
         GrammarState anotherState = (GrammarState)obj;
         return(anotherState.StateValue.Equals(StateValue) && (anotherState.IsFinal == IsFinal));
     }
     return(false);
 }
Пример #3
0
        /// <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);
             }
         }
     }
 }
Пример #5
0
        /// <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);
        }
Пример #6
0
 public GrammarState(GrammarState anotherState)
 {
     StateValue = anotherState.StateValue;
     IsFinal    = anotherState.IsFinal;
 }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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
        }
Пример #9
0
 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
                }
            }
        }