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.
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.
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.