[Resolvido] Analisador Léxico e sintático

Estou precisando desenvolver um analisador léxico e sintático em JAVA porém ainda não possuo intimidade suficiente com o JAVA para a realização do mesmo.

Alguém poderia me ajudar em como desenvolver esses analisadores?

Obrigado.

http://www.antlr.org/
https://javacc.dev.java.net/

Agradeço as informações fornecidas, não teria algo em português, exemplos para me auxiliar melhor. Pois alguns termos em inglês eu me atrapalho.

Mais uma vez obrigado.

eu ja usei o javacc, assunto do segundo link que o tingol passou… infelizmente por isso posso afirmar que conteudo bom e em portugeus sobre compiladores é tremendamente raro, sobre compiladores de compiladores é ainda mais raro.

Esse site esta em ingles mais da pra se vira, mesmo que acabe sendo com google translator… la tem exemplos prontos de códigos que geram o analisador lexico e sintatico de linguagens como java, c e sql (ao menos a um certo tempo atras tinha)

da uma olhada la direito…

Analisei o JCC porém preciso de algo mais simples, já que se trata de um trabalho de faculdade onde o professor não que algo muito complexo.

Essa é a gramatica que especifica a linguagem:

-> SEQ | PAR
-> begin end
-> , |
-> name (timeout) |

Exemplo de entrada sintaticamente correta

SEQ begin proc (20.5) , PAR begin proc1 (nome), proc1890 (3) end end

O SEQ determina uma lista de processos que devem ser executados sequencialmente.
O PAR uma lista de processos que devem ser executados paralelamente.
O símbolo léxico name pode ser qualquer palavra formada por letras maiúsculas ou minúsculas seguidas ou não de dígitos.
o símbolo léxico timeout representa em segundos e detremina o tempo méximo que o processo pode executar. Caso seja colocado none indica que não possui nenhuma restrição.

É com isso que foi passado que tenho que construir em JAVA um analisador léxico e sintático. Quem puder me ajudar eu agradeceria.

Para um analisador léxico, você pode se basear no código do java.io.StreamTokenizer (olhe no JDK, arquivo src.zip, e ache nesse arquivo zip o arquivo java/io/StreamTokenizer.java )

Quanto ao analisador sintático, como a gramática é bem bobinha, você pode usar “recursive descent” ( http://en.wikipedia.org/wiki/Recursive_descent_parser ).
O nome é ameaçador, mas na prática é o que você faria se você não conhecesse P*** nenhuma de teoria de compiladores - é bem intuitivo, na verdade. Esse método é particularmente adequado se você quiser fazer as coisas na mão, sem auxílio nenhum de compilador de compiladores.
Mesmo linguagens com gramáticas mais complexas, como o próprio Java, têm compiladores que usam Recursive Descent. Se não me engano, o javac é um compilador desse tipo.

Alguém poderia me ajudar a terminar o programa, pois não estou conseguindo o que eu quero!

No botão “Analise Léxica” eu não estou conseguindo fazer com que o mesmo leia a entrada do código e como resposta além dos erros (caso possua algum) listar todos os tokens. (Imagem 1)

No botão “Analise Sintática” ler a entrada do código e como resposta ter a árvore de derivação. (Imagem 2)

Código principal:

[code]package compiladores;

import compiladores.Lexico;
import compiladores.Token;
import compiladores.LexicalError;
import compiladores.Sintatico;
import compiladores.SyntaticError;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class AnalisadorLS extends JFrame {

private JButton analisadorLexico,analisadorSintatico,fechar;
private JTextArea codPrograma,tokensGerados,erros;
private JPanel painel, pBotoes;
private JScrollPane scroll1, scroll2, scroll3;
private JLabel lb1,lb2,lb3;

public AnalisadorLS() {
	telaPrograma();
}

Lexico lexico = new Lexico();
Sintatico sintatico = new Sintatico();

public void telaPrograma() {
	setSize(540, 580);
	setLayout(null);
	setTitle("Analisador Léxico");
	setResizable(false);
	
	analisadorLexico = new JButton("Analise Léxica");
	analisadorSintatico = new JButton("Analise Sintática");
	fechar = new JButton("Fechar");
	
	lb1 = new JLabel("Entrada de dados");
	lb2 = new JLabel("Resultado da analise");
	lb3 = new JLabel("Erros");
	
	codPrograma = new JTextArea();
	tokensGerados = new JTextArea();
	erros = new JTextArea();
	
	painel = new JPanel(new GridLayout(2,2));
	pBotoes = new JPanel();
			
	analisadorLexico.setSize(10,20);
	analisadorSintatico.setSize(10,20);
	fechar.setSize(10,20);
	
	codPrograma.setBorder(BorderFactory.createLineBorder(Color.BLACK));
	tokensGerados.setBorder(BorderFactory.createLineBorder(Color.BLACK));
	erros.setBorder(BorderFactory.createLineBorder(Color.BLACK));
	
	codPrograma.setWrapStyleWord(true);
	tokensGerados.setWrapStyleWord(true);
	erros.setWrapStyleWord(true);
	
	scroll1 = new JScrollPane(codPrograma);
	scroll2 = new JScrollPane(tokensGerados);
	scroll3 = new JScrollPane(erros);
	
	analisadorLexico.setToolTipText("Executa a analise léxica");
	analisadorSintatico.setToolTipText("Executa a analise sintática");
	fechar.setToolTipText("Fecha a janela");
	
	pBotoes.add(analisadorLexico);
	pBotoes.add(analisadorSintatico);
	pBotoes.add(fechar);
	
	scroll1.setBounds(20, 40, 300, 380);
	scroll2.setBounds(350, 40, 120, 380);
	scroll3.setBounds(20, 450, 450, 50);
	
	pBotoes.setBounds(20, 510, 450, 40);
	
	lb1.setBounds(20, 20, 100, 20);
	lb2.setBounds(350, 20, 120, 20);
	lb3.setBounds(20, 430, 120, 20);
	
	add(scroll1);
	add(scroll2);
	add(scroll3);
	add(pBotoes);
	add(lb1);
	add(lb2);
	add(lb3);
	
	setDefaultCloseOperation(EXIT_ON_CLOSE);
	setVisible(true);		
	setLocationRelativeTo(this);
	
	analisadorLexico.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){
			if(codPrograma.getText().length() == 0){
				JOptionPane.showMessageDialog(null, "O campo 'Entrada de dados' está vazio");
			}else{
				lexico.setInput(codPrograma.getText());
				try
				{
				    Token t = null;
				    while ( (t = lexico.nextToken()) != null ) {
				        tokensGerados.setText(lexico.listaTokens());
				    }
				}
				catch ( LexicalError ev )
				{
				    //erros.getText(ev.getMessage());
				}
				
				
			}
		}
	});
	
	fechar.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e){
			dispose();
		}
	});
}

public static void main(String[] args) {
	AnalisadorLS executar = new AnalisadorLS();

}

}
[/code]

Código Léxico:

[code]package compiladores;

public class Lexico implements Constants
{
private int position;
private String input;

public Lexico()
{
    this("");
}

public Lexico(String input)
{
    setInput(input);
}

public void setInput(String input)
{
    this.input = input;
    setPosition(0);
}

public void setPosition(int pos)
{
    position = pos;
}

public Token nextToken() throws LexicalError
{
    if ( ! hasInput() )
        return null;

    int start = position;

    int state = 0;
    int lastState = 0;
    int endState = -1;
    int end = -1;

    while (hasInput())
    {
        lastState = state;
        state = nextState(nextChar(), state);

        if (state < 0)
            break;

        else
        {
            if (tokenForState(state) >= 0)
            {
                endState = state;
                end = position;
            }
        }
    }
    if (endState < 0 || (endState != state && tokenForState(lastState) == -2))
        throw new LexicalError(SCANNER_ERROR[lastState], start);

    position = end;

    int token = tokenForState(endState);

    if (token == 0)
        return nextToken();
    else
    {
        String lexeme = input.substring(start, end);
        return new Token(token, lexeme, start);
    }
}

private int nextState(char c, int state)
{
    int next = SCANNER_TABLE[state][c];
    return next;
}

private int tokenForState(int state)
{
    if (state < 0 || state >= TOKEN_STATE.length)
        return -1;

    return TOKEN_STATE[state];
}

private boolean hasInput()
{
    return position < input.length();
}

private char nextChar()
{
    if (hasInput())
        return input.charAt(position++);
    else
        return (char) -1;
}

}
[/code]

Código do Gerador de erro léxico:

[code]package compiladores;

public class LexicalError extends AnalysisError
{
public LexicalError(String msg, int position)
{
super(msg, position);
}

public LexicalError(String msg)
{
    super(msg);
}

}[/code]

Código Sintático:

[code]package compiladores;

import java.util.Stack;

public class Sintatico implements Constants
{
private Stack stack = new Stack();
private Token currentToken;
private Token previousToken;
private Lexico scanner;

public void parse(Lexico scanner) throws LexicalError, SyntaticError
{
    this.scanner = scanner;

    stack.clear();
    stack.push(new Integer(0));

    currentToken = scanner.nextToken();

    while ( ! step() )
        ;
}

private boolean step() throws LexicalError, SyntaticError
{
    if (currentToken == null)
    {
        int pos = 0;
        if (previousToken != null)
            pos = previousToken.getPosition()+previousToken.getLexeme().length();

        currentToken = new Token(DOLLAR, "$", pos);
    }

    int token = currentToken.getId();
    int state = ((Integer)stack.peek()).intValue();

    int[] cmd = PARSER_TABLE[state][token-1];

    switch (cmd[0])
    {
        case SHIFT:
            stack.push(new Integer(cmd[1]));
            previousToken = currentToken;
            currentToken = scanner.nextToken();
            return false;

        case REDUCE:
            int[] prod = PRODUCTIONS[cmd[1]];

            for (int i=0; i<prod[1]; i++)
                stack.pop();

            int oldState = ((Integer)stack.peek()).intValue();
            stack.push(new Integer(PARSER_TABLE[oldState][prod[0]-1][1]));
            return false;

        case ACTION:
            int action = FIRST_SEMANTIC_ACTION + cmd[1] - 1;
            stack.push(new Integer(PARSER_TABLE[state][action][1]));
            return false;

        case ACCEPT:
            return true;

        case ERROR:
            throw new SyntaticError(PARSER_ERROR[state], currentToken.getPosition());
    }
    return false;
}

}
[/code]

Código do erro sintático:

[code]package compiladores;

public class SyntaticError extends AnalysisError
{
public SyntaticError(String msg, int position)
{
super(msg, position);
}

public SyntaticError(String msg)
{
    super(msg);
}

}
[/code]

Quem puder me ajudar eu agradeço, já estou há uns três dias tentando e não saio do lugar!



Caso alguém precise de mais alguma informação para me ajudar a terminar esse programa é só perguntar.

Obrigado!

eu gostaria que voce postasse o seu codigo final,
por curiosidade minha mesmo!

grato.