Пример #1
0
        public Simbolos buscarProximoLexema(LerArquivo arquivo)
        {
            int estadoAtual = 0;
            int estadoFinal = 16;

            while (estadoAtual != estadoFinal)
            {
                switch (estadoAtual)
                {
                case 0:
                    // Ler proximo caractere caso devolver for false.
                    if (!devolve)
                    {
                        _char = (char)arquivo.Read();
                    }

                    devolve = false;
                    lexema  = "";

                    if (eCaractere(_char))
                    {
                        if (_char == 10 || _char == 11)
                        {    // Próxima linha 0Ah ou Tab vertical (\v).
                            estadoAtual = 0;
                            linha++;
                        }

                        else if (_char == 8 || _char == 9 || _char == 13 || _char == 32)
                        {    // Apagar (\b) ou Tab horizontal (\t) ou Início da linha 0Dh (\r) ou Espaço.
                            estadoAtual = 0;
                        }
                        // Confere se char e um dos caracteres abaixo e aceita como token.
                        else if (_char == 10 || _char == '[' || _char == ']' || _char == '%' || _char == ')' || _char == '(' || _char == '=' ||
                                 _char == ';' || _char == ',' || _char == '+' || _char == '-' || _char == '*' || _char == '{' || _char == '}')
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }

                        else if (eLetra(_char))
                        {    // É letra então vai pro estado 1.
                            lexema     += _char;
                            estadoAtual = 1;
                        }

                        else if (_char == '_')
                        {    // É sublinhado então vai pro estado 2.
                            lexema     += _char;
                            estadoAtual = 2;
                        }

                        else if (_char == '.')
                        {    // É ponto então vai pro estado 3.
                            lexema     += _char;
                            estadoAtual = 3;
                        }

                        else if (_char == '<')
                        {    // É menor então vai pro estado 4.
                            lexema     += _char;
                            estadoAtual = 4;
                        }

                        else if (_char == '>')
                        {    // É maior então vai pro estado 5.
                            lexema     += _char;
                            estadoAtual = 5;
                        }

                        else if (_char == '0')
                        {    // É zero então vai pro estado 6.
                            lexema     += _char;
                            estadoAtual = 6;
                        }

                        else if (eDigito(_char) && _char != '0')
                        {    // É digito e diferente de zero então vai pro estado 10.
                            lexema     += _char;
                            estadoAtual = 9;
                        }

                        else if (_char == '/')
                        {    // É barra então vai pro estado 11.
                            lexema     += _char;
                            estadoAtual = 10;
                        }

                        else if (_char == '"')
                        {    // É aspas então vai pro estado 14.
                            lexema     += _char;
                            estadoAtual = 13;
                        }

                        else if (_char == 39)
                        {    // É apóstofro então vai pro estado 15.
                            lexema     += _char;
                            estadoAtual = 14;
                        }

                        else if (_char == -1 || _char == 65535)
                        {    // É final de arquivo então vai pro estado 16(final).
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                            EOF         = true;
                            arquivo.Close();
                        }

                        else
                        {    // Lexema não identificado.
                            lexema += _char;
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;    // Fim estado 0.

                case 1:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        if (eLetra(_char) | eDigito(_char) | _char == '_' | _char == '.')
                        {    // Verifica se obedece as condições para montagem do token identificador.
                            lexema     += _char;
                            estadoAtual = 1;
                        }
                        else
                        {    // Reconhece ID
                            estadoAtual = estadoFinal;
                            devolve     = true;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 2:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // "Loop" _
                        if (_char == '_')
                        {
                            lexema     += _char;
                            estadoAtual = 2;
                        }
                        else if (eLetra(_char) | eDigito(_char) | _char == '.')
                        {                    // Verifica se obedece as condições para montagem do token identificador
                            lexema     += _char;
                            estadoAtual = 1; //Volta para estado 1 garantindo não ter somente _
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Caso seja outro caractere não permitido, logo não consegue identificar o lexema.
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 3:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // "Loop" _
                        if (_char == '.')
                        {
                            lexema     += _char;
                            estadoAtual = 3;
                        }
                        else if (eLetra(_char) | eDigito(_char) | _char == '_')
                        {                    // Verifica se obedece as condições para montagem do token identificador
                            lexema     += _char;
                            estadoAtual = 1; //Volta para estado 1 garantindo não ter somente ponto
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Caso seja outro caractere não permitido, logo não consegue identificar o lexema.
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 4:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // token <> ou <=
                        if (_char == '>' | _char == '=')
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }
                        else
                        {    // token < e devolve o proximo.
                            devolve     = true;
                            estadoAtual = estadoFinal;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 5:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // token >=
                        if (_char == '=')
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }
                        else
                        {    // token > e devolve o proximo.
                            devolve     = true;
                            estadoAtual = estadoFinal;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 6:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // Formando token hexadecimal 0x
                        if (_char == 'x')
                        {
                            lexema     += _char;
                            estadoAtual = 7;
                        }
                        else if (eDigito(_char))
                        {    // Formação de numero.
                            lexema     += _char;
                            estadoAtual = 9;
                        }
                        else
                        {    // valor Zero.
                            devolve     = true;
                            estadoAtual = estadoFinal;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 7:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // Formação token hexadecimal 0xD
                        if (eHexadecimal(_char))
                        {
                            lexema     += _char;
                            estadoAtual = 8;
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Caso seja outro caractere não permitido, logo não consegue identificar o lexema.
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 8:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // token hexadecimal 0xDD
                        if (eHexadecimal(_char))
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Caso seja outro caractere não permitido, logo não consegue identificar o lexema.
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 9:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // "Loop" formação valor
                        if (eDigito(_char))
                        {
                            lexema     += _char;
                            estadoAtual = 9;
                        }
                        else
                        {    // const valor
                            devolve     = true;
                            estadoAtual = estadoFinal;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 10:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // inicio comentario
                        if (_char == '*')
                        {
                            lexema     += _char;
                            estadoAtual = 11;
                        }
                        else
                        {    // token /
                            devolve     = true;
                            estadoAtual = estadoFinal;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 11:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // Caminho finalizar comentario
                        if (_char == '*')
                        {
                            lexema     += _char;
                            estadoAtual = 12;
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // "Loop" ignorando carcteres
                            lexema     += _char;
                            estadoAtual = 11;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 12:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // Caminho finalizar comentario
                        if (_char == '*')
                        {
                            lexema     += _char;
                            estadoAtual = 12;
                        }
                        else if (_char == '/')
                        {    // Finaliza comentario
                            lexema     += _char;
                            estadoAtual = 0;
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Voltando pro estado 11 para continuação comentario
                            lexema     += _char;
                            estadoAtual = 11;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 13:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        // String
                        if (_char == '"')
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }
                        else if (_char == 10 || _char == '$')
                        {    // não pode conter quebra de linha e $
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {
                            lexema     += _char;
                            estadoAtual = 13;
                        }
                    }
                    else
                    {    // Caractere Invalido.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 14:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractereImprimivel(_char))
                    {
                        lexema     += _char;
                        estadoAtual = 15;
                    }
                    else if (_char == -1 || _char == 65535)
                    {    // Fim do arquivo não esperado.
                        Erro.ErroLexico.Arquivo(linha);
                    }
                    else
                    {    // Caractere Invalido(não pertence a linguagem) ou não imprivel.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;

                case 15:

                    _char = (char)arquivo.Read();

                    // Verifica se caractere valido.
                    if (eCaractere(_char))
                    {
                        //token char
                        if (_char == 39)
                        {
                            lexema     += _char;
                            estadoAtual = estadoFinal;
                        }
                        else if (_char == -1 || _char == 65535)
                        {    // Fim do arquivo não esperado.
                            Erro.ErroLexico.Arquivo(linha);
                        }
                        else
                        {    // Erro ao formar o  char 'c ?(alguma coisa)
                            Erro.ErroLexico.Lexema(linha, lexema);
                        }
                    }
                    else
                    {    // Caractere Invalido(não pertence a linguagem) ou não imprivel.
                        Erro.ErroLexico.Char(linha);
                    }

                    break;
                }
            }

            if (!EOF)// não for final do arquivo.
            {
                if (tbSimbolos.buscarSimbolo(lexema.ToLower()) != null)
                {// Caso lexema já exista na tabela de simbolos
                    simbolo = tbSimbolos.buscarSimbolo(lexema.ToLower());
                }
                else if (lexema[0] == '_' || lexema[0] == '.' || eLetra(lexema[0]))
                {     // adicionar identificador na tabela
                    if (lexema.Length >= 255)
                    { // validando tamanho identificador
                        Erro.ErroLexico.Lexema(linha, lexema);
                    }
                    else
                    {//inserindo na tabela
                        simbolo = tbSimbolos.inserirIdentificador(lexema.ToLower());
                    }
                }
                else if (lexema[0] == '"')
                {     // identificando string
                    if (lexema.Length >= 256)
                    { // validando tamanho string
                        Erro.ErroLexico.Lexema(linha, lexema);
                    }
                    else
                    {
                        lexema = '"' + lexema.Substring(1, lexema.Length - 2) + "$" + '"';
                    }

                    simbolo = new Simbolos(lexema, TabelaSimbolos.CONSTANTE, Simbolos.TIPO_STRING);
                }
                else
                {   //const hexadecimal
                    if (lexema.Length > 1 && lexema[1] == 'x')
                    {
                        simbolo = new Simbolos(lexema, TabelaSimbolos.CONSTANTE, Simbolos.TIPO_HEXADECIMAL);
                    }
                    else if (lexema[0] == 39)
                    {//alfanumérico('c')
                        simbolo = new Simbolos(lexema, TabelaSimbolos.CONSTANTE, Simbolos.TIPO_CARACTERE);
                    }
                    else
                    {// inteiro
                        simbolo = new Simbolos(lexema, TabelaSimbolos.CONSTANTE, Simbolos.TIPO_INTEIRO);
                    }
                }
            }
            else
            {// retonar eof para futuras validações.
                simbolo = new Simbolos("EOF", TabelaSimbolos.EOF);
            }

            return(simbolo);
        }