一、實驗目的
通過設計編制調試一個具體的詞法分析程序,加深對詞法分析原理的理解。並掌握在對程序設計語言源程序進行掃描過程中將其分解為各類單詞的詞法分析方法。
編制一個讀單詞過程,從輸入的源程序中,識別出各個具有獨立意義的單詞,即基本保留字、標識符、常數、運算符、分隔符五大類。並依次輸出各個單詞的內部編碼及單詞符號自身值。(遇到錯誤時可顯示“Error”,然后跳過錯誤部分繼續顯示).
二、實驗准備工作
1、詞法分析器的功能和輸出格式
詞法分析器的功能是輸入源程序,輸出單詞符號。詞法分析器的單詞符號常常表示成以下的二元式(單詞種別碼,單詞符號的屬性值)。本實驗中,采用的是一類符號一種別碼的方式。
2、Java程序語言的單詞符號的種別.
識別java的關鍵字:
boolean,byte,char,double,false,float,int,long,new,null,short,true,void,instanceof,break,case,catch,continue,default,do,else,for,if,return,switch,try,while,finally,throw,this,super,abstract,final,namtive,private,protected,public ,static,synchronized,transient,volatile,class,extends,implements,interface,package,import,throws;單詞識別碼為1;
標識符:標識符必須是以字母,下划線,美元符號開始,單詞識別碼為2;
常量:常數為無符號整形數;單詞種別碼為3;
運算符:+、-、*、/、=、>、<、>=、<=、==、!= 、++、--、%、&&、||、!單詞識別碼為4;
分隔符:,、;、{、}、(、); 單詞種別碼為5
4.單元模塊

//業務代碼:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Vector;
public class JavaAnaylsis
{
private static String[] keyword =
{ "boolean", "byte", "char", "double", "false", "float", "int", "long",
"new", "null", "short", "true", "void", "instanceof", "break",
"case", "catch", "continue", "default", "do", "else", "for", "if",
"return", "switch", "try", "while", "finally", "throw", "this",
"super", "abstract", "final", "namtive", "private", "protected",
"public", "static", "synchronized", "transient", "volatile",
"class", "extends", "implements", "interface", "package", "import",
"throws" };
static String string;
static String wordString;
static Vector vc;
public JavaAnaylsis(String str) throws Exception
{
File inFile = new File(str);
if (inFile.exists())
{
System.out.println("文件打開成功!!!");
try
{
FileReader reader = new FileReader(inFile);
BufferedReader br = new BufferedReader(reader);
vc = new Vector();
while ((string = br.readLine()) != null)
{
// 預處理 將一行的字符串連續的空格換成一個空格或將連續的制表符換成一個空格
string = string.trim().replace(" +", " ")
.replaceAll("\\t+", " ");
// System.out.println(string);
judgement();
}
br.close();
} catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
{
System.out.println("文件打開失敗");
}
}
/*
* 判斷讀入的字符是否為字母
*/
public static boolean isLetter(char c)
{
if ((c >= 'a' && c <= 'z') || (c > +'A' && c <= 'Z'))
{
return true;
} else
return false;
}
/*
* 判斷讀入的字符是否為數字
*/
public static boolean isDigit(char c)
{
if (c >= '0' && c <= '9')
{
return true;
} else
return false;
}
/*
* 判斷是否為關鍵字
*/
public static boolean isKey(String ss)
{
int flag = 0;
for (int i = 0; i < keyword.length; i++)
{
if (ss.equals(keyword[i]))
{
flag = 1;
break;
}
}
if (flag == 1)
{
return true;
}
return false;
}
/*
* 判斷是否為運算符
*/
public static boolean isSpilt(char ch)
{
if (ch == '+' || ch == '-' || ch == '|' || ch == '=' || ch == '&')
{
return true;
} else
return false;
}
/*
* 判斷輸入的字符並輸出單詞符號
*/
public static void judgement() throws Exception
{
char ch = 0;
int m = 0;
String str = null;
for (int i = 0; i < string.length(); i++)
{
switch (m)
{
case 0:
ch = string.charAt(i);
// 判斷是否為運算符使用超前搜索
if (ch == '+' || ch == '-' || ch == '*' || ch == '/'
|| ch == '=' || ch == '>' || ch == '<' || ch == '!'
|| ch == '%' || ch == '|')
{
str = "";
str += ch;
if (ch == '+' || ch == '-' || ch == '>' || ch == '<'
|| ch == '!' || ch == '|' || ch == '&')
{
ch = string.charAt(i + 1); // 對下一個字符進行判斷是否為運算符
if (isSpilt(ch))
{
str += ch;
m = 4;
} else
{
ch = string.charAt(i - 1); // 不是運算符則進行回退操作
m = 4;
}
}
}
// 判斷是否為界符
else if (ch == ',' || ch == ';' || ch == '{' || ch == '}'
|| ch == '(' || ch == ')')
{
m = 5;
}
// 判斷是否數字
else if (isDigit((ch = string.charAt(i))))
{
str = "";
str += ch;
m = 3;
}
// 判斷是否字母
else if (isLetter(ch = string.charAt(i)))
{
str = "";
str += ch;
m = 2;
}
// 判斷是否下划線或美元符號
else if (ch == '_' || ch == '$')
{
str = "";
str += ch;
m = 2;
} else
{
}
break;
case 4:
i--;
System.out.println(("( 4 " + "“ " + str + " ” )"));
wordString = ("( 4 " + "“ " + str + " ” )");
vc.add(wordString);
m = 0;
break;
case 5:
i--;
System.out.println(("( 5 " + "“ " + ch + " ” )"));
wordString = ("( 5 " + "“ " + ch + " ” )");
vc.add(wordString);
m = 0;
break;
case 2:
if (isLetter(ch = string.charAt(i)))
{
str += ch;
} else
{
if (isKey(str))
{
System.out.println("( 1 " + "“ " + str + " ” )");
wordString = ("( 1 " + "“ " + str + " ” )");
vc.add(wordString);
} else
{
System.out.println(("( 2 " + "“ " + str + " ” )"));
wordString = ("( 2 " + "“ " + str + " ” )");
vc.add(wordString);
}
i--;
m = 0;
}
break;
case 3:
if (isDigit((ch = string.charAt(i))))
{
str += ch;
} else
{
System.out.println("( 3 " + "“ " + str + " ” )");
wordString = "( 3 " + "“ " + str + " ” )";
vc.add(wordString);
i--;
m = 0;
}
break;
}
}
}
public static Vector getVector()
{
return vc;
}
}
//界面代碼:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
public class JavaFrame extends JFrame
{
private JTextArea textArea, textArea2;
private JButton anaylisbButton;
static String filename;
static Vector vcVector;
public JavaFrame()
{
super();
setTitle("Java詞法分析器");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 設置"關閉"按鈕處理事件
Toolkit tool = Toolkit.getDefaultToolkit(); // 創建工具欄
Dimension screenSize = tool.getScreenSize(); // 獲得屏幕大小
setSize(800, 500); // 設置窗體大小
setLocation((screenSize.width - getWidth()) / 2,
(screenSize.height - getHeight()) / 2);
JPanel scollJPanel = (JPanel) getContentPane(); // 獲得內容面板
setResizable(false); // 設置最大化按鈕不能用
JMenuBar menuBar = createMenu(); // 設置菜單項
this.setJMenuBar(menuBar);
// textArea=new TextArea();
JScrollPane jScrollPane = new JScrollPane(textArea = new JTextArea(
"源代碼:" + "\n", 1000, 35));
JScrollPane jScrollPane2 = new JScrollPane(textArea2 = new JTextArea(
"詞法分析后:" + "\n", 1000, 35));
scollJPanel.add(jScrollPane2, BorderLayout.EAST);
scollJPanel.add(jScrollPane, BorderLayout.WEST);
JPanel buttonJPanel = new JPanel();
anaylisbButton = new JButton("開始詞法分析");
anaylisbButton.addActionListener(new start());
buttonJPanel.add(anaylisbButton);
scollJPanel.add(buttonJPanel, "South");
setVisible(true);
}
private JMenuBar createMenu()
{
// TODO Auto-generated method stub
JMenuBar menuBar = new JMenuBar();// 初始化菜單欄
JMenu menu = new JMenu(" 文件 ");
JMenu menu2 = new JMenu(" 窗口 ");
menu2.setEnabled(false);
JMenu menu3 = new JMenu(" 幫助 ");
menu3.setEnabled(false);
JMenu menu4 = new JMenu(" 格式 ");
menu4.setEnabled(false);
JMenuItem meun1 = new JMenuItem(" 打開 ");
JMenuItem meun2 = new JMenuItem(" 保存 ");
JMenuItem meun3 = new JMenuItem(" 另存為 ");
JMenuItem meun4 = new JMenuItem(" 退出 ");
meun4.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
// TODO Auto-generated method stub
JavaFrame.this.dispose();
}
});
meun1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
// TODO Auto-generated method stub
// 初始化文件選擇框
textArea.setText("源代碼:" + "\n");
JFileChooser fDialog = new JFileChooser("d:/");
// 設置文件選擇框的標題
fDialog.setDialogTitle("請選擇文件");
// 彈出選擇框
int returnVal = fDialog.showOpenDialog(null);
// 如果是選擇了文件
if (JFileChooser.APPROVE_OPTION == returnVal)
{
// 打印出文件的路徑,你可以修改位 把路徑值 寫到 textField 中
System.out.println(fDialog.getSelectedFile());
filename = fDialog.getSelectedFile().toString();
File inFile = new File(filename);
try
{
FileReader reader = new FileReader(inFile);
BufferedReader br = new BufferedReader(reader);
String strings;
while ((strings = br.readLine()) != null)
{
textArea.append(strings + "\n");
}
br.close();
} catch (Exception e)
{
// TODO: handle exception
}
}
}
});
meun2.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent arg0)
{
// TODO Auto-generated method stub
JFileChooser jf = new JFileChooser("d:/");
int value = jf.showSaveDialog(null);
if (value == JFileChooser.APPROVE_OPTION)
{ // 判斷窗口是否點的是打開或保存
File getPath = jf.getSelectedFile(); // 取得路徑
System.out.println(getPath);
try
{
FileWriter fWriter = new FileWriter(getPath);
BufferedWriter out = new BufferedWriter(fWriter);
Iterator iterator = vcVector.iterator();
while (iterator.hasNext())
{
// textArea2.append(iterator.next().toString()+"\n");
out.write(iterator.next().toString());
out.newLine();
}
out.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
{
// 沒有選擇,即點了窗口的取消
}
}
});
menu.add(meun1);
menu.add(meun2);
menu.add(meun3);
menu.addSeparator();
menu.add(meun4);
menuBar.add(menu);
menuBar.add(menu2);
menuBar.add(menu4);
menuBar.add(menu3);
return menuBar;
}
private class start implements ActionListener
{
@Override
public void actionPerformed(ActionEvent arg0)
{
// TODO Auto-generated method stub
textArea2.setText("詞法分析后:" + "\n");
try
{
new JavaAnaylsis(filename);
vcVector = new Vector();
vcVector = JavaAnaylsis.getVector();
Iterator iterator = vcVector.iterator();
while (iterator.hasNext())
{
textArea2.append(iterator.next().toString() + "\n");
}
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
new JavaFrame();
}
}
實驗總結:我在編程的過程中一共花了一天的時間,而在紙上設計就大概花了半個小時吧,花了半天的時間去上機輸入和調試,在這次的實驗過程中花了近半天的時間去思考問題,也遇到了編程的過程的問題,主要在邏輯錯誤問題較多,開始時我以為我的邏輯無錯誤,還以為是其他的問題,最后靜下來理清自己的邏輯,還是發現了出現了較嚴重的邏輯問題,通過在網上查閱相關的資料來解決問題.到最后還是基本完成了這個java詞法分析器的實驗.對於我自己的程序我認為還是可以應對基本的詞法分析,能編出這個程序我感覺到有那么一點成就感,這次的實驗讓我進一步地熟悉了java語言,提高了我的編程思維能力,增大了我的興趣愛好,鞏固了我的知識.還有好......
