Expressões regulares (verificar se é uma classe)

3 respostas
M

Estou tentando fazer um programa similar à um compilador, ele deveria verificar o seguinte arquivo de texto: Classe.txt que tem como conteúdo: classe teste { int i; }

O resultado seria imprimir o conteúdo do arquivo, caso ouver problema, é para informar uma mensagem... mas estou com problemas ao verificar isso com expressão regular, alguém pode me ajudar?

o código do que eu fiz até agora é o seguinte:

public static boolean identificador(String texto) {
        Pattern valida = Pattern.compile("^[a-zA-Z]+[a-zA-Z0-9]*");
        Matcher retorno = valida.matcher(texto);
        return retorno.matches();
    }
    String token = "";

    public void D() {
        Le_Token();
        if (token == "class") {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
        if (identificador(token)) {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
        if (token == "{") {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
        C();
        if (token == "}^") {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
    }

    public void C() {
        Le_Token();
        if (token == "int" || token == "string" || token == "char") {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
        if (identificador(token)) {
            System.out.println(token);
            Le_Token();
        } else {
            Mostra_Erro(token);
        }
    }

    public void Le_Token() {
        File arquivo = new File("C:/Users/Luiz/Documents/NetBeansProjects/Classe.txt");
        FileReader conteudo = null;

        try {
            conteudo = new FileReader(arquivo);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        int indice = 0;
        int ln = 1, cl = 1, ct = 0, i = 0;
        char c = ' ';
        while (indice != -1) {
            try {
                indice = conteudo.read();
            } catch (IOException ex) {
                Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
            c = (char) indice;


            if (c != (' ') && c != ('\n') && c != ('\r') && c != ('"') //if (c != (' ') && c != (';') && c != ('\n') && c != ('\r') && c != ('"')
                    && c != ('(') && c != (')') && c != ('[') && c != (']') && c != ('\t')) {  //&& c != ('(') && c != (')') && c != ('[') && c != (']') && c != ('\t')) {
                token = token + c;
            } else {
                System.out.println(token);
                cl = ct + 1;
                if (c == ('\n')) {
                    cl = 1;
                    ln = ln + 1;
                }
                token = "";
            }
            ct++;
        }
    }

    void Mostra_Erro(String onde) {
        System.out.println("Erro em " + onde);
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        D();

    }

3 Respostas

davidbuzatto

Você tem vários problemas no seu código.
O seu Le_Token está implementado errado. Ele não faz o que você acha que ele está fazendo.
Ele inicia o parse do arquivo toda vez que é invocado e não é isso que você quer.
Outro problema são as comparações das Strings ( token == “alguma coisa” ). Strings são camparadas usando o método equals.
Seu código não está passando nem pelo primeiro teste.

Estou dando uma mexida aqui para ver se consigo fazer algo…

[]'s

davidbuzatto

Como isso está parecendo trabalho de faculdade, fiz um código aqui para você um pouco mais complicado. A ideia é vc usá-lo como base.

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 *
 * @author David Buzatto
 */
public class Parser {
    
    private FileReader conteudo;
    private int numeroLinhaAtual = 1;
    private int numeroCaractereAtual = 0;
    private int valorAtual;
    private char caractereAtual;
    private String token;
    
    public static void main( String[] args ) {
        try {
            new Parser( new File( "C:/Classe.txt" ) ).parse();
        } catch ( ParseException exc ) {
            exc.printStackTrace();
        } catch ( IOException exc ) {
            exc.printStackTrace();
        }
    }
    
    public Parser( File arquivo ) throws IOException {
        conteudo = new FileReader( arquivo );
    }
    
    public void parse() throws ParseException, IOException {
        
        proximoToken();
        
        if ( token.equals( "class" ) ) {
            System.out.println( token );
            proximoToken();
        } else {
            throw new ParseException( token, numeroLinhaAtual, numeroCaractereAtual );
        }
        
        identificador();
        
        if ( token.equals( "{" ) ) {
            System.out.println( token );
            proximoToken();
        } else {
            throw new ParseException( token, numeroLinhaAtual, numeroCaractereAtual );
        }
        
        tipo();
        identificador();
          
        if ( token.equals( "}" ) ) {
            System.out.println( token );
            proximoToken();
        } else {
            throw new ParseException( token, numeroLinhaAtual, numeroCaractereAtual );
        }
        
        if ( token == null ) {
            System.out.println( "Arquivo sintaticamente correto." );
        }
        
    }
    
    private void tipo() throws ParseException, IOException {
        
        if ( token.equals( "int" ) || token.equals( "string" ) || token.equals( "char" ) ) {
            System.out.println( token );
            proximoToken();
        } else {
            throw new ParseException( token, numeroLinhaAtual, numeroCaractereAtual );
        }
        
    }
    
    private void identificador() throws ParseException, IOException {
        
        if ( token.matches( "^[a-zA-Z]+[a-zA-Z0-9]*" ) ) {
            System.out.println( token );
            proximoToken();
        } else {
            throw new ParseException( token, numeroLinhaAtual, numeroCaractereAtual );
        }
        
    }
    
    private void proximoToken() throws IOException {
        
        token = null;
            
        while ( ( valorAtual = conteudo.read() ) != -1 ) {

            caractereAtual = (char) valorAtual;

            // não deveria descartar o ";"...
            if ( caractereAtual != ' ' && caractereAtual != '\n' && caractereAtual != ';' ) {
                if ( token != null ) {
                    token += caractereAtual;
                } else {
                    token = String.valueOf( caractereAtual );
                }
                numeroCaractereAtual++;
            } else {
                if ( caractereAtual == ' ' ) {
                    numeroCaractereAtual++;
                    break;
                } else if ( caractereAtual == '\n' ) {
                    numeroLinhaAtual++;
                    numeroCaractereAtual = 1;
                    break;
                }
            }

        }
        
    }
    
}

/**
 *
 * @author David Buzatto
 */
public class ParseException extends Exception {
    
    private String token;
    private int linha;
    private int caractere;
    
    public ParseException( String token, int linha, int caractere ) {
        this.token = token;
        this.linha = linha;
        this.caractere = caractere;
    }

    @Override
    public String toString() {
        return String.format( 
                "Erro em \"%s\" (linha: %d, caractere: %d)", 
                token, linha, caractere );
    }
    
}

Note que o parser que escrevi não elimina nem espaços nem linhas a mais que estiverem no código da classe.
Outro detalhe é que a estrutura do parser não está muito legal... Vc deve tratar a chamada dos métodos de reconhecimento para representar uma árvore, algo feito precariamente no método parse. Enfim, dê uma olhada. As duas classes devem estar no mesmo pacote para funcionar.

Ah, sua expressão regular, motivo do seu tópico, está correta :D

[]'s

M

Muito obrigado, peguei a ideia aqui e vou ver o que posso fazer a mais com meu professor amanhã.

Criado 9 de dezembro de 2011
Ultima resposta 9 de dez. de 2011
Respostas 3
Participantes 2