学编译原理时的课程设计-java写的词法分析器
/**
* @(#)AnalyseFrame.java 1.0 06/4/01
* Copyright (c) 2006 xinyu, Inc. All Rights Reserved.
*/
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.JSplitPane;
/**
* Sample application analysing C code to accidence file
* 词法分析程序,分析C源代码,找出其中的单词,并确定单词的类型
* 关键字 KEY
* 标识符 ID
* 整数 INTEGER
* 浮点数 FLOAT
* 分隔符 SEPARATOR
* 操作符 OPERATOR
* 预定义符 PRETREATMENT
* 字符串 STRING 如 "string"
* 字符 CHAR 如 'c'
* 错误字符 ERROR
* @author 李平新
* @version 1.0 06/4/01
*/
public class AnalyseFrame extends JFrame implements DocumentListener{
private JPanel jContentPane = null;
private JToolBar toolBar = null;
private JMenuBar menuBar = null;
private JMenu fileMenu = null;
private JMenu analyseMenu = null;
private JMenu aboutMenu = null;
private Action openAction = null;
private Action saveAction = null;
private Action newAction = null;
private Action aboutAction = null;
private Action analyseAction = null;
private Action exitAction = null;
private JScrollPane inScrollPane = null;
private JTextArea inTextArea = null;
private JScrollPane outScrollPane = null;
private JTextArea outTextArea = null;
private File sourFile = null;
private File objFile = null;
private JSplitPane splitPane = null;
private Document indocument;
private boolean edited = false;
/**
* This method initializes toolBar
*
* @return javax.swing.JToolBar
*/
private JToolBar getToolBar() {
if (toolBar == null) {
toolBar = new JToolBar();
toolBar.add(getOpenAction());
toolBar.add(getSaveAction());
toolBar.add(getNewAction());
toolBar.add(getAnalyseAction());
toolBar.add(getAboutAction());
toolBar.add(getExitAction());
}
return toolBar;
}
/**
* This method initializes menuBar
*
* @return javax.swing.JMenuBar
*/
private JMenuBar getmenuBar() {
if (menuBar == null) {
menuBar = new JMenuBar();
fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
fileMenu.add(getNewAction());
fileMenu.add(getOpenAction());
fileMenu.add(getSaveAction());
fileMenu.addSeparator();
fileMenu.add(getExitAction());
menuBar.add(fileMenu);
analyseMenu = new JMenu("Analyse");
analyseMenu.setMnemonic('n');
analyseMenu.add(getAnalyseAction());
menuBar.add(analyseMenu);
aboutMenu = new JMenu("About");
aboutMenu.setMnemonic('A');
aboutMenu.add(getAboutAction());
menuBar.add(aboutMenu);
}
return menuBar;
}
/**
* This method initializes openAction
*
* @return javax.swing.Action
*/
private Action getOpenAction() {
if (openAction == null) {
openAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
openFile();
}
};
openAction.putValue(Action.NAME, "Open");
openAction.putValue(Action.SMALL_ICON,
new ImageIcon(AnalyseFrame.class.getResource("/img/open.gif")));
openAction.putValue(Action.SHORT_DESCRIPTION, "Open a file");
openAction.putValue(Action.MNEMONIC_KEY, new Integer('O'));
}
return openAction;
}
/**
* This method initializes saveAction
*
* @return javax.swing.Action
*/
private Action getSaveAction() {
if (saveAction == null) {
saveAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
saveFile();
}
};
saveAction.putValue(Action.NAME, "Save");
saveAction.putValue(Action.SMALL_ICON,
new ImageIcon(AnalyseFrame.class.getResource("/img/save.gif")));
saveAction.putValue(Action.SHORT_DESCRIPTION, "Save current file");
saveAction.putValue(Action.MNEMONIC_KEY, new Integer('S'));
}
return saveAction;
}
/**
* This method initializes newAction
*
* @return javax.swing.Action
*/
private Action getNewAction() {
if (newAction == null) {
newAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
newFile();
}
};
newAction.putValue(Action.NAME, "New");
newAction.putValue(Action.SMALL_ICON, new ImageIcon(AnalyseFrame.class.getResource("/img/new.gif")));
newAction.putValue(Action.SHORT_DESCRIPTION, "Create a new file");
newAction.putValue(Action.MNEMONIC_KEY, new Integer('N'));
}
return newAction;
}
/**
* This method initializes analyseAction
*
* @return javax.swing.Action
*/
private Action getAnalyseAction() {
if (analyseAction == null) {
analyseAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
analyseFile();
}
};
analyseAction.putValue(Action.NAME, "Analyse");
analyseAction.putValue(Action.SMALL_ICON, new ImageIcon(
AnalyseFrame.class.getResource("/img/analyse.gif")));
analyseAction.putValue(Action.SHORT_DESCRIPTION,
"Analyse current file");
analyseAction.putValue(Action.MNEMONIC_KEY, new Integer('A'));
}
return analyseAction;
}
/**
* This method initializes aboutAction
*
* @return javax.swing.Action
*/
private Action getAboutAction() {
if (aboutAction == null) {
aboutAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,
" 词法分析/n李平新/n计算机03-4", "About",
JOptionPane.INFORMATION_MESSAGE,new ImageIcon(AnalyseFrame.class.getResource("/img/me.jpg")));
}
};
aboutAction.putValue(Action.NAME, "About");
aboutAction.putValue(Action.SMALL_ICON, new ImageIcon(
AnalyseFrame.class.getResource("/img/about.gif")));
aboutAction
.putValue(Action.SHORT_DESCRIPTION, "About this program");
aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A'));
}
return aboutAction;
}
/**
* This method initializes exitAction
*
* @return javax.swing.Action
*/
private Action getExitAction() {
if (exitAction == null) {
exitAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
};
exitAction.putValue(Action.NAME, "Exit");
exitAction.putValue(Action.SMALL_ICON,
new ImageIcon(AnalyseFrame.class.getResource("/img/exit.gif")));
exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit this program");
exitAction.putValue(Action.MNEMONIC_KEY, new Integer('E'));
}
return exitAction;
}
/**
* This method initializes inscrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getInScrollPane() {
if (inScrollPane == null) {
inScrollPane = new JScrollPane();
inScrollPane.setViewportView(getInTextArea());
}
return inScrollPane;
}
/**
* This method initializes inTextArea
*
* @return javax.swing.JTextArea
*/
private JTextArea getInTextArea() {
if (inTextArea == null) {
inTextArea = new JTextArea();
indocument = inTextArea.getDocument();
indocument.addDocumentListener(this);
inTextArea.setEditable(false);
inTextArea.setForeground(Color.BLUE);
inTextArea.setFont(new Font(null,Font.BOLD,14));
}
return inTextArea;
}
/**
* This method initializes outScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getOutScrollPane() {
if (outScrollPane == null) {
outScrollPane = new JScrollPane();
outScrollPane.setViewportView(getOutTextArea());
}
return outScrollPane;
}
/**
* This method initializes outTextField
*
* @return javax.swing.JTextField
*/
private JTextArea getOutTextArea() {
if (outTextArea == null) {
outTextArea = new JTextArea();
outTextArea.setEditable(false);
outTextArea.setForeground(Color.RED);
outTextArea.setFont(new Font(null,Font.BOLD,12));
}
return outTextArea;
}
/**
* This method initializes splitPane
*
* @return javax.swing.JSplitPane
*/
private JSplitPane getSplitPane() {
if (splitPane == null) {
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
getInScrollPane(), getOutScrollPane());
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(350);
}
return splitPane;
}
/**
* mathod main to run this program
* @param args
*/
public static void main(String[] args) {
new AnalyseFrame();
}
/**
* This is the default constructor
*/
public AnalyseFrame() {
super();
initialize();
}
/**
* This method initializes this analyseFrame
*
* @return void
*/
private void initialize() {
// this.setSize(600, 400);
this.setContentPane(getJContentPane());
this.setTitle("词法分析器");
this.setJMenuBar(getmenuBar());
this.setBounds(200, 150, 600, 400);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jContentPane = new JPanel();
jContentPane.setLayout(new BorderLayout());
jContentPane.add(getToolBar(), java.awt.BorderLayout.NORTH);
jContentPane.add(getSplitPane(), java.awt.BorderLayout.CENTER);
}
return jContentPane;
}
/**
* This method initializes open file
*
* @return void
*/
private void openFile() {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
sourFile = fc.getSelectedFile();
try {
inTextArea.read(new FileReader(sourFile), null);
this.setTitle("词法分析器 - " + sourFile.getName());
inTextArea.setEditable(true);
edited = false;
indocument = inTextArea.getDocument();
indocument.addDocumentListener(this);
outTextArea.setText("");
} catch (IOException ioe) {
JOptionPane.showMessageDialog(this, "Can not open this file!",
"Error", JOptionPane.ERROR_MESSAGE);
}
}
}
/**
* This method initializes saveFile
*
* @return void
*/
private void saveFile() {
if(!inTextArea.isEditable()){
JOptionPane.showMessageDialog(this, "Please create a new file",
"Error", JOptionPane.ERROR_MESSAGE);
return;
}
if (sourFile == null) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
sourFile = fc.getSelectedFile();
} else
return;
}
try {
inTextArea.write(new FileWriter(sourFile));
this.setTitle("词法分析器 - " + sourFile.getName());
edited = false;
} catch (IOException ioe) {
JOptionPane.showMessageDialog(this, "can not open this file!",
"Error", JOptionPane.ERROR_MESSAGE);
}
}
/**
* This method initializes newFile
*
* @return void
*/
private void newFile() {
sourFile = null;
inTextArea.setText("");
this.setTitle("词法分析器 - Noname");
inTextArea.setEditable(true);
outTextArea.setText("");
indocument = inTextArea.getDocument();
indocument.addDocumentListener(this);
edited = false;
}
/**
* This method initializes analyseFile
*
* @return void
*/
private void analyseFile() {
saveFile();
outTextArea.setText("");
char c;
int end;
char A = 'A';
char Z = 'Z';
char a = 'a';
char z = 'z';
char xia = '_';
char zero = '0';
char nine = '9';
char newline = '/n';
char dot = '.';
if (sourFile != null) {
StringBuffer sb = new StringBuffer();
int len = inTextArea.getText().length();
char[] buffer = new char[len+1];
buffer = inTextArea.getText().toCharArray();
int i=0;
try{
while(i<len){
c = buffer[i];
/**
* key and identifier will start with character
*/
if (((c >= A) && (c <= Z)) || ((c >= a) && (c <= z))
|| (c == xia)) {
sb.delete(0, sb.length());
while (((c >= A) && (c <= Z)) || ((c >= a) && (c <= z))
|| (c == xia) || (c >= zero && c <= nine)) {
sb.append(c);
c = buffer[++i];
}
outTextArea.append("( " + sb.toString() + "/t,"
+ checkWord(sb.toString()) + "/t)/n");
} else {
/**
* if current char is a number, it will be numbers
*/
if ((c >= zero) && (c <= nine)) {
sb.delete(0, sb.length());
while ((c >= zero) && (c <= nine)) {
sb.append(c);
c = buffer[++i];
}
/**
* if the next char is dot, it will be float,else it's integer
*/
if (c == dot) {
sb.append(c);
c = buffer[++i];
while ((c >= zero) && (c <= nine)) {
sb.append(c);
c = buffer[++i];
}
outTextArea.append("( " + sb.toString() + "/t,"
+ "FLOAT" + "/t)/n");
}else{
outTextArea.append("( " + sb.toString() + "/t,"
+ "INTEGER" + "/t)/n");
}
} else {
/**
* character '/' is a special character
*/
if (c == '/') {
sb.delete(0, sb.length());
sb.append(c);
c = buffer[++i];
/*
* here is note mark,
* reading the next line to skip it
*/
if (c == '/') {
c = buffer[++i];
while (c != newline) {
c = buffer[++i];
}
c = buffer[++i];
} else
/*
* here is note mark,
* reading the end mark to skip it
*/
if (c == '*') {
// next *
c = buffer[++i];
int count = 0;
while (count != 2) {
count = 0;
while (c != '*') {
c = buffer[++i];
}
count++;
c = buffer[++i];
if (c == '/') {
count++;
}
}
c = buffer[++i];
} else {
/**
* operator '/='
*/
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
}
} else {
sb.delete(0, sb.length());
/*
* identify other operator
* 识别其他的操作符号
*/
switch (c) {
case '+':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '+') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '-':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '-') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '*':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
break;
case '%':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
break;
case '>':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '>') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '<':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '<') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '!':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
break;
case '&':
sb.append(c);
c = buffer[++i];
if (c == '&') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '=') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '|':
sb.append(c);
c = buffer[++i];
if (c == '|') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
if (c == '=') {
sb.append(c);
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( "
+ sb.toString() + "/t,"
+ "OPERATOR" + "/t)/n");
}
}
break;
case '=':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
break;
case '^':
sb.append(c);
c = buffer[++i];
if (c == '=') {
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
c = buffer[++i];
} else {
outTextArea.append("( " + sb.toString()
+ "/t," + "OPERATOR" + "/t)/n");
}
break;
case ',':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case ';':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '(':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case ')':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '{':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '}':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '[':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case ']':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '/'':
sb.append(c);
c = buffer[++i];
while (c != '/'') {
sb.append(c);
c = buffer[++i];
}
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "STRING" + "/t)/n");
c = buffer[++i];
break;
case '/"':
sb.append(c);
c = buffer[++i];
while (c != '/"') {
sb.append(c);
c = buffer[++i];
}
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "STRING" + "/t)/n");
c = buffer[++i];
break;
case '.':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case '#':
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "SEPARATOR" + "/t)/n");
c = buffer[++i];
break;
case ' ':
case '/n':
case '/r':
case '/t':
c = buffer[++i];
break;
default:
sb.append(c);
outTextArea.append("( " + sb.toString()
+ "/t," + "ERROR" + "/t)/n");
c = buffer[++i];
break;
}// end switch
}// end else of no /
}// end else of no number
}// end else of no key or id
}// end while
}catch(ArrayIndexOutOfBoundsException e){
outTextArea.append("( " + sb.toString()
+ "/t," + checkWord(sb.toString()) + "/t)/n");
}
if(objFile== null){
sb = new StringBuffer(sourFile.getName());
int positon = sb.indexOf(".");
sb.delete(positon,sb.length());
sb.append(".cc");
objFile = new File(sourFile.getParentFile(),sb.toString());
try{
outTextArea.write(new FileWriter(objFile));
}catch(IOException e){
}
}
}//file is nulll
}
/**
* This method initializes checkWord
*
* @return int
*/
private String checkWord(String word) {
/*
* 32 keys of c
*/
String key[] = { "auto", "break", "case", "char", "const", "continue",
"default", "do", "double", "else", "enum", "extern", "float",
"for", "goto", "if", "int", "long", "register", "return",
"short", "signed", "sizeof", "static", "struct", "switch",
"typedef", "union", "unsigned", "void", "volatile", "while" };
/*
* 12 pretreatments of c
*/
String pretreatment[] = {"define","endif","elif","error","line",
"include","ifdef","ifndef","pragma","undef","if","else"};
for (int i = 0; i < 32; i++) {
if (word.equals(key[i]))
return "KEY";
}
for (int i = 0; i < 12; i++) {
if (word.equals(pretreatment[i]))
return "PRETREATMENT";
}
return "ID";
}
/*
* DocumentListener to handle the changes of inTextArea
* 当inTextArea的内容改变是,将在标题处显示'*',提示用户,文本内容改变.
* @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
*/
public void changedUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
if (!edited) {
edited = true;
setTitle(getTitle() + " *");
}
}
public void removeUpdate(DocumentEvent e){
if (!edited) {
edited = true;
setTitle(getTitle() + " *");
}
}
}