コード例 #1
0
        private Simbolo PreencheAtributos(Simbolo s, int cod_erro)
        {
            if (cod_erro >= 0) //Caso ocorra um erro, as seguintes informações são solicitadas
            {
                string _descricaoERRO = "";
                TiposErros.TryGetValue(cod_erro, out _descricaoERRO);
                s.DescricaoERRO = _descricaoERRO;
                s.Coluna        = _coluna;
                s.Linha         = _linha;

                return(s);
            }

            switch (s.Token)
            {
            case "num":
                if (s.Lexema.Contains("."))
                {
                    s.Tipo = "double";
                }
                else
                {
                    s.Tipo = "int";
                }
                break;

            case "lit":
                s.Tipo = "literal";
                break;

            case "opm":
                s.Tipo = s.Lexema;
                break;

            case "rcb":
                s.Tipo = "=";
                break;

            case "opr":
                s.Tipo = s.Lexema;
                break;
            }

            s.Coluna = _coluna;
            s.Linha  = _linha;

            return(s);
        }
コード例 #2
0
        public Simbolo AssociaRegraSemantica(int numProducao, List <Simbolo> tabDeSimbolos, out bool _houveErro)
        {
            Simbolo      s = new Simbolo();
            Simbolo      simboloNaoterminal = new Simbolo();
            StreamWriter x = File.AppendText(_caminhoNome);
            Simbolo      tipo;
            Simbolo      arg;
            Simbolo      oprd;
            Simbolo      ld;

            _houveErro = false;
            var tabelaDeSimbolos = tabDeSimbolos;

            switch (numProducao)
            {
            case 5:
                int i = 0;
                while (i++ < 3)
                {
                    x.WriteLine("");
                }
                break;

            case 6:
                _pilhaSemantica.Pop();
                s.Tipo = _pilhaSemantica.Pop().Tipo;
                Simbolo simboloTopo = _pilhaSemantica.Peek();
                simboloTopo.Tipo = s.Tipo;
                x.WriteLine($"{simboloTopo.Tipo} {simboloTopo.Lexema};");
                break;

            case 7:
                s    = _pilhaSemantica.Pop();
                tipo = new Simbolo("TIPO", "TIPO", s.Tipo);
                _pilhaSemantica.Push(tipo);
                break;

            case 8:
                s    = _pilhaSemantica.Pop();
                tipo = new Simbolo("TIPO", "TIPO", s.Tipo);
                _pilhaSemantica.Push(tipo);
                break;

            case 9:
                s    = _pilhaSemantica.Pop();
                tipo = new Simbolo("TIPO", "TIPO", s.Tipo);
                _pilhaSemantica.Push(tipo);
                break;

            case 11:
                _pilhaSemantica.Pop();
                s = _pilhaSemantica.Peek();
                if (s.Tipo != null)
                {
                    switch (s.Tipo)
                    {
                    case "literal":
                        x.WriteLine($"scanf(\"%s\",{s.Lexema});");
                        break;

                    case "int":
                        x.WriteLine($"scanf(\"%d\",&{s.Lexema});");
                        break;

                    case "double":
                        x.WriteLine($"scanf(\"%lf\",&{s.Lexema});");
                        break;
                    }
                }
                else
                {
                    _houveErro      = true;
                    s.DescricaoERRO = "Variável não declarada.";
                }
                break;

            case 12:
                _pilhaSemantica.Pop();
                arg = _pilhaSemantica.Peek();
                switch (arg.Token)
                {
                case "literal":
                    x.WriteLine($"printf({arg.Lexema});");
                    break;

                case "id":
                    switch (arg.Tipo)
                    {
                    case "int":
                        x.WriteLine($"printf(\"%d\",{arg.Lexema});");
                        break;

                    case "literal":
                        x.WriteLine($"printf(\"%s\",{arg.Lexema});");
                        break;

                    case "double":
                        x.WriteLine($"printf(\"%lf\",{arg.Lexema});");
                        break;
                    }
                    break;
                }
                break;

            case 13:
                s   = _pilhaSemantica.Pop();
                arg = s.CopiaAtributos();
                _pilhaSemantica.Push(arg);
                break;

            case 14:
                s   = _pilhaSemantica.Pop();
                arg = s.CopiaAtributos();
                _pilhaSemantica.Push(arg);
                break;

            case 15:
                s = _pilhaSemantica.Peek();
                if (s.Tipo != null)
                {
                    arg = s.CopiaAtributos();
                    _pilhaSemantica.Push(arg);
                }
                else
                {
                    _houveErro      = true;
                    s.DescricaoERRO = "Variável não declarada.";
                }
                break;

            case 17:
                _pilhaSemantica.Pop();
                Simbolo num = _pilhaSemantica.Pop();
                Simbolo rcb = _pilhaSemantica.Pop();
                Simbolo id  = _pilhaSemantica.Pop();
                if (id.Tipo != null)
                {
                    if (num.Tipo == id.Tipo)
                    {
                        x.WriteLine($"{id.Lexema} {rcb.Tipo} {num.Lexema};");
                    }
                    else
                    {
                        _houveErro      = true;
                        s               = id.CopiaAtributos();
                        s.DescricaoERRO = "Tipos diferentes para atribuição.";
                    }
                }
                else
                {
                    _houveErro      = true;
                    s               = id.CopiaAtributos();
                    s.DescricaoERRO = "Variável não declarada.";
                }
                break;

            case 18:
                Simbolo oprd1 = _pilhaSemantica.Pop();
                Simbolo opm   = _pilhaSemantica.Pop();
                Simbolo oprd2 = _pilhaSemantica.Pop();
                if (oprd1.Tipo == oprd2.Tipo)
                {
                    var temp = new VariavelTemporaria($"T{countTemp}", oprd1.Tipo.ToString());
                    _listaTemporarios.Add(temp);
                    Simbolo LD = new Simbolo($"T{countTemp++}", "LD", oprd1.Tipo);
                    _pilhaSemantica.Push(LD);
                    x.WriteLine($"{LD.Lexema} = {oprd2.Lexema} {opm.Tipo} {oprd1.Lexema};");
                }
                else
                {
                    _houveErro      = true;
                    s               = oprd1.CopiaAtributos();
                    s.DescricaoERRO = "Operandos com tipos incompatíveis.";
                }
                break;

            case 19:
                s  = _pilhaSemantica.Pop();
                ld = s.CopiaAtributos();
                _pilhaSemantica.Push(ld);
                break;

            case 20:
                s = _pilhaSemantica.Peek();
                if (s.Tipo != null)
                {
                    s    = _pilhaSemantica.Pop();
                    oprd = s.CopiaAtributos();
                    _pilhaSemantica.Push(oprd);
                }
                else
                {
                    _houveErro      = true;
                    s.DescricaoERRO = "Variável não declarada.";
                }
                break;

            case 21:
                s    = _pilhaSemantica.Pop();
                oprd = s.CopiaAtributos();
                _pilhaSemantica.Push(oprd);
                break;

            case 23:
                x.WriteLine("}");
                break;

            case 24:
                _pilhaSemantica.Pop();
                _pilhaSemantica.Pop();
                s = _pilhaSemantica.Pop();
                x.WriteLine($"if({s.Lexema}){{");
                break;

            case 25:
                Simbolo oprnd1 = _pilhaSemantica.Pop();
                Simbolo opr    = _pilhaSemantica.Pop();
                Simbolo oprnd2 = _pilhaSemantica.Pop();
                if (oprnd1.Tipo == oprnd2.Tipo)
                {
                    var temp = new VariavelTemporaria($"T{countTemp}", oprnd1.Tipo.ToString());
                    _listaTemporarios.Add(temp);
                    Simbolo exp_r = new Simbolo($"T{countTemp++}", "tx", "tx");
                    x.WriteLine($"{exp_r.Lexema} = {oprnd2.Lexema} {opr.Tipo} {oprnd1.Lexema};");
                    _pilhaSemantica.Push(exp_r);
                }
                else
                {
                    _houveErro      = true;
                    s               = oprnd1.CopiaAtributos();
                    s.DescricaoERRO = "Operandos com tipos incompatíveis.";
                }
                break;
            }

            x.Close();
            return(s);
        }
コード例 #3
0
        public void AnaliseSintatica()
        {
            AnalisadorLexico    analisadorLexico    = new AnalisadorLexico(_codigoFonte); //aqui é onde ele inicializa o analisador léxico
            AnalisadorSemantico analisadorSemantico = new AnalisadorSemantico();

            _pilha.Push(0);                                   // Empilha o estado inicial na pilha
            int             estado           = 0;
            string          acao             = "";
            string          guardaToken      = "";
            Simbolo         simbolo          = analisadorLexico.RetornaToken();
            Stack <Simbolo> pilhaDeSimbolos  = new Stack <Simbolo>();
            List <Simbolo>  TabelaDeSimbolos = analisadorLexico.GetTabelaDeSimbolos();

            while (true)                                                                   // Início do procedimento de Shift - Reduce
            {                                                                              //enquanto ele não aceitar ou dar erro ele não para a execução
                if (simbolo.Token != "ERRO")                                               //CASO NÃO SEJA RETORNADO UM ERRO DO ANALISADOR LÉXICO
                {
                    acao = _tabelaShiftReduce.Rows[estado][$"{simbolo.Token}"].ToString(); //captura a ação da tabela shift-reduce de acordo com o estado e com o simbolo

                    if (acao.Contains("S"))                                                //EMPILHA
                    {
                        estado = Convert.ToInt32(acao.Substring(1));
                        _pilha.Push(estado);
                        analisadorSemantico._pilhaSemantica.Push(simbolo);
                        if (pilhaDeSimbolos.Count == 0)
                        {
                            simbolo = analisadorLexico.RetornaToken(); //atualiza o simbolo com o token retornado do léxico
                        }
                        else
                        {
                            simbolo.Token = guardaToken;           //atualiza o token após o tratamento do erro
                            simbolo       = pilhaDeSimbolos.Pop(); //atualiza com o simbolo da pilha
                        }
                    }
                    else
                    {
                        if (acao.Contains("R"))                                   // REDUZ
                        {
                            int numProducao = Convert.ToInt32(acao.Substring(1)); //captura o numero da produção se for S32 PEGA SO O 32;
                            var producao    = new string[2];
                            _producoes.TryGetValue(numProducao, out producao);    //Atualiza a produção De acordo com o número da ação;
                            var Simbolos    = producao[1].Split(' ');
                            int numSimbolos = Simbolos.Count();
                            //DESEMPILHA QUANTIDADE DE SÍMBOLOS LADO DIREITO
                            for (int i = 0; i < numSimbolos; i++)
                            {
                                _pilha.Pop();
                            }

                            //EMPILHAR O VALOR DE [t,A] na pilha
                            estado = Convert.ToInt32(_tabelaShiftReduce.Rows[Convert.ToInt32(_pilha.Peek())][producao[0].ToString()]); //pula para o estado seguinte
                            _pilha.Push(estado);
                            Console.WriteLine($"{producao[0]} -> {producao[1]}");

                            if (_houveErro == false)
                            {
                                TabelaDeSimbolos = analisadorLexico.GetTabelaDeSimbolos();
                                var simboloComErro = analisadorSemantico.AssociaRegraSemantica(numProducao, TabelaDeSimbolos, out _houveErro);
                                if (_houveErro)
                                {
                                    PrintErro(simboloComErro.DescricaoERRO, simboloComErro);
                                }
                            }
                            else
                            {
                                analisadorSemantico.DeletaArquivoObj();
                            }
                        }
                        else
                        {
                            if (acao.Contains("ACC")) // ACEITA
                            {
                                Console.WriteLine("P' -> P");
                                if (_houveErro == false)
                                {
                                    analisadorSemantico.FinalizaArquivoObj();
                                }
                                Console.ReadLine();
                                break;
                            }
                            else //EM CASO DE ERRO SINTÁTICO
                            {
                                if (Convert.ToInt32(acao.Substring(1)) < 16) //CASO O ERRO SEJA TRATÁVEL
                                {
                                    Simbolo s = CopiaSimbolo(simbolo);
                                    pilhaDeSimbolos.Push(s);                  //cria uma nova pilha para guardar os tokens já lidos
                                    var tipoDeErro = Erro(acao, s);
                                    guardaToken   = simbolo.Token;            //guarda o token do simbolo atual para atualizar depois do tratamento de erro
                                    simbolo.Token = tipoDeErro[1].ToString(); //Rotina de erro
                                }
                                else //SE O ERRO NÃO FOR TRATÁVEL A COMPILAÇÃO É PAUSADA
                                {
                                    Erro(acao, simbolo);
                                    Console.ReadLine();
                                    break;
                                }
                            }
                        }
                    }
                }
                else//EM CASO DE ERRO LÉXICO
                {
                    PrintErro(simbolo.DescricaoERRO, simbolo); //Escreve o erro na tela
                    simbolo = analisadorLexico.RetornaToken(); //Busca o próximo token
                }
            }
        }
コード例 #4
0
        public Simbolo AnaliseLexica(string codigoFonte) // Percorre ocodigo fonte do Mgol
        {
            _proxEstado      = "q0";                     // a cada inicialização ele deve começar do estado incial
            _estadoAnterior  = "q0";
            _lexema          = "";                       // lexema vazio
            _linhaDoEstado   = 0;
            _colunaDaEntrada = 0;
            _tipo_de_erro    = -1;

            while (_ponteiro != codigoFonte.Length) // percorre o ponteiro enquanto ele não chegar no final do codigo fonte
            {
                //_ponteiro -> do codigo fonte
                _caracterAtual = codigoFonte[_ponteiro];

                ModificaLinhaColuna();                                       // Contador que atualiza o valor da linha e da coluna

                if (!SimbolosValidos.ContainsKey(_caracterAtual.ToString())) //verifica se o caractere atual é valido
                {                                                            // se não for caractere válido retorna o erro
                    _tipo_de_erro = 0;
                    _proxEstado   = "ERRO";
                }

                _estadoAnterior = _proxEstado;  //armazena o estado anterior para o proximo estado ser modificado

                TodosEstados.TryGetValue(_proxEstado, out _linhaDoEstado);

                SimbolosValidos.TryGetValue(_caracterAtual.ToString(), out _colunaDaEntrada); //Modifica o valor da coluna de acordo com o caractere

                if (_estadoAnterior == "num" && (_caracterAtual == 'E' || _caracterAtual == 'e'))
                {
                    _colunaDaEntrada = 9;
                }

                _proxEstado = Convert.ToString(TabelaDeTransicao[_linhaDoEstado][_colunaDaEntrada]);

                if (EstadosFinais.ContainsKey(_estadoAnterior) && _proxEstado == "")
                {
                    if (_estadoAnterior == "qG")
                    {
                        _estadoAnterior = "opr";
                    }

                    //VERIFICA SE TEM ESSE LEXEMA NA LISTA DE SIMBOLOS
                    Simbolo s = TabelaDeSimbolos.Find(o => o.Lexema == _lexema);

                    if (s == null) // s-> simbolo do codigo fonte
                    {
                        s = new Simbolo()
                        {
                            Lexema = _lexema, Token = _estadoAnterior, Tipo = null
                        };

                        if (_estadoAnterior.Equals("id"))
                        {
                            TabelaDeSimbolos.Add(s);             // lista de identificadores
                        }
                        s = PreencheAtributos(s, _tipo_de_erro); //Verifica se ocorreu algum erro de caracter inválido durante a leitura

                        return(s);
                    }
                    else
                    {
                        s = PreencheAtributos(s, _tipo_de_erro);//Verifica se ocorreu algum erro de caracter inválido durante a leitura

                        return(s);
                    }
                }

                if (!char.IsWhiteSpace(_caracterAtual) || _proxEstado == "qA") // Verifica se o caractere atual é espaço em  branco ou se o proximo estado é qA
                {
                    if (_caracterAtual == '\r')                                //Converte o \r para ' '
                    {
                        _caracterAtual = ' ';
                    }

                    _lexema += _caracterAtual;
                }

                _ponteiro++;

                continue; // Continua o laço de análise
            }

            Simbolo simb = TabelaDeSimbolos.Find(o => o.Lexema == _lexema); // verifica se o lexema formado está na tabela de simbolo

            if (simb == null)                                               // verifica se chegou no final da leitura do arquivo
            {
                simb = new Simbolo {
                    Token = "$"
                };
                _linha++;
                PreencheAtributos(simb, _tipo_de_erro);
            }

            return(simb);
        }
コード例 #5
0
        private static Dictionary <string, Simbolo> Palavras_Chave()
        {
            Dictionary <string, Simbolo> TabelaDeSimbolos = new Dictionary <string, Simbolo>();

            //palavras chave da linguagem MGOL
            var inicio = new Simbolo()
            {
                Lexema = "inicio",
                Token  = "inicio",
                Tipo   = null
            };

            var varinicio = new Simbolo()
            {
                Lexema = "varinicio",
                Token  = "varinicio",
                Tipo   = null
            };

            var varfim = new Simbolo()
            {
                Lexema = "varfim",
                Token  = "varfim",
                Tipo   = null
            };

            var escreva = new Simbolo()
            {
                Lexema = "escreva",
                Token  = "escreva",
                Tipo   = null
            };

            var leia = new Simbolo()
            {
                Lexema = "leia",
                Token  = "leia",
                Tipo   = null
            };

            var se = new Simbolo()
            {
                Lexema = "se",
                Token  = "se",
                Tipo   = null
            };

            var entao = new Simbolo()
            {
                Lexema = "entao",
                Token  = "entao",
                Tipo   = null
            };

            var fimse = new Simbolo()
            {
                Lexema = "fimse",
                Token  = "fimse",
                Tipo   = null
            };

            var fim = new Simbolo()
            {
                Lexema = "fim",
                Token  = "fim",
                Tipo   = null
            };

            var inteiro = new Simbolo()
            {
                Lexema = "inteiro",
                Token  = "inteiro",
                Tipo   = "int"
            };

            var lit = new Simbolo()
            {
                Lexema = "lit",
                Token  = "lit",
                Tipo   = "literal"
            };

            var real = new Simbolo()
            {
                Lexema = "real",
                Token  = "real",
                Tipo   = "double"
            };

            TabelaDeSimbolos.Add(inicio.Lexema, inicio);
            TabelaDeSimbolos.Add(varinicio.Lexema, varinicio);
            TabelaDeSimbolos.Add(varfim.Lexema, varfim);
            TabelaDeSimbolos.Add(escreva.Lexema, escreva);
            TabelaDeSimbolos.Add(leia.Lexema, leia);
            TabelaDeSimbolos.Add(se.Lexema, se);
            TabelaDeSimbolos.Add(entao.Lexema, entao);
            TabelaDeSimbolos.Add(fimse.Lexema, fimse);
            TabelaDeSimbolos.Add(fim.Lexema, fim);
            TabelaDeSimbolos.Add(inteiro.Lexema, inteiro);
            TabelaDeSimbolos.Add(lit.Lexema, lit);
            TabelaDeSimbolos.Add(real.Lexema, real);

            return(TabelaDeSimbolos);
        }