Java词法分析器
[使用java开发,并且用来分析java源文件]
2003年1月12日
1. 开发工具:rational rose2002 jedition,borland jbuilder6 professional
2. 开发步骤:
1) 基于状态转换图的编译器原理如下:
2)在rose中建立分析器模型框架,根据分析器的状态转换图算法以及算法构造。词法分析器的框架结构如下图所示:
(分析器软件包)
(词法分析器的控制器结构,包括预编译器,扫描程序,保留字表和单词的类型种别码表以及词法分析器的引导程序和控制程序)
(词法分析器的扫描缓冲区和输入缓冲区结构以及获得缓冲区的缓冲工厂)
3)使用rose正向工程产生java框架代码,在jbuilder中进行编辑实现功能代码,生成最终的代码,进行test和debug,最后形成最终的目标程序。具体的实现请参考源代码。编辑和测试如下图所示:
(开发环境)
(运行结果,详细结果附在后面)
3. 源代码:
//lisence head
/*Java Accidence Analyser
**Author yellowicq
**All copyright reserved
**Version 1.0
*/
//lisence
1) 词法分析器引导文件:main.java
package JAccidenceAnalyse;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class main {
/**
* @param args
* @return void
* @roseuid 3D9BAE4702AD
*/
public static void main(String[] args) {
//读取配置文件,得到系统属性
String cfgString[] = new String[4];
try {
cfgString = main.loadAACfg("d:\\aaCfg.xml");
}
catch (Exception e) {
e.printStackTrace(System.err);
}
//设置待读文件名
////////////////////////////////////////////////////
//保留字表文件
String reserveFileName = cfgString[0];
//类型种别码表文件
String classFileName = cfgString[1];
//需要分析的源文件
String sourceFileName = cfgString[2];
//输出文件
String outputFileName = cfgString[3];
////////////////////////////////////////////////////
//创建词法分析器
AccidenceAnalyser aa = new AccidenceAnalyser();
aa.setFilesPath(reserveFileName, classFileName, sourceFileName,
outputFileName); //建立所需要的文件对象
//初始化词法分析器
aa.initAA();
//初始化关键字表
aa.keyWordTable.initKeyWordTable();
//初始化类型种别码表
aa.classIdentity.initClassIdentityTable();
//开始进行词法分析
aa.startAA();
//分析完毕
}
//读取配置文件
private static String[] loadAACfg(String name) throws Exception {
String cfgString[] = new String[4];
/*解析xml配置文件*/
try {
/*创建文档工厂*/
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
/*创建文档解析器*/
DocumentBuilder builder = factory.newDocumentBuilder();
/*解析配置文件*/
Document doc = builder.parse(name);
/*规范化文档*/
doc.normalize();
/*查找接点表*/
NodeList nlists = doc.getElementsByTagName("FilePath");
for (int i = 0; i < nlists.getLength(); i++) {
Element item = (Element) nlists.item(i);
//取得需要的配置属性
/******************/
cfgString[0] = item.getElementsByTagName("ReserveFileName").item(0).
getFirstChild().getNodeValue().trim();
/******************/
cfgString[1] = item.getElementsByTagName("ClassFileName").item(0).
getFirstChild().getNodeValue().trim();
/******************/
cfgString[2] = item.getElementsByTagName("SourceFileName").item(0).
getFirstChild().getNodeValue().trim();
/******************/
cfgString[3] = item.getElementsByTagName("OutputFileName").item(0).
getFirstChild().getNodeValue().trim();
/******************/
}
}
catch (Exception e) {
e.printStackTrace();
throw new Exception("[ERROR]加载配置文件 " + name + " 错误!");
}
//返回属性数组
return cfgString;
}
}
2) 词法分析器主程序:AccidenceAnalyser.java
//Source file: d:\\JAccidenceAnalyse\\AccidenceAnalyser.java
package JAccidenceAnalyse;
import java.io.*;
import java.util.*;
import JAccidenceAnalyse.Buffer.*;
public class AccidenceAnalyser {
private java.io.File SourceFile;
private java.io.File ReserveFile;
private java.io.File ClassFile;
private java.io.File OutputFile;
public Pretreatment pretreatment;
public KeyWordTable keyWordTable;
public ClassIdentity classIdentity;
public Scaner scaner;
public ConcreteScanBufferFactory csbFactory;
/**
* @roseuid 3D9BB93303D0
*/
public AccidenceAnalyser() {
System.out.println("[INFOR]已经建立词法分析器!");
}
/**
* @roseuid 3D9BAEF9029F
*/
public void initAA() {
//创建缓冲工厂
this.csbFactory = new ConcreteScanBufferFactory();
//创建字符串扫描对象
scaner = new Scaner(this);
//创建pre处理对象
pretreatment = new Pretreatment(SourceFile, this);
//创建关键字表对象
keyWordTable = new KeyWordTable(ReserveFile);
//创建对象种别码表对象
classIdentity = new ClassIdentity(ClassFile);
System.out.println("[INFOR]已经初始化词法分析器!");
}
/**
* @roseuid 3D9BAF12022D
*/
public void setFilesPath(String reserveFileName, String ClassFileName,
String sourceFileName, String outputFileName) {
//创建文件对象
SourceFile = new java.io.File(sourceFileName);
//创建文件对象
ReserveFile = new java.io.File(reserveFileName);
//创建文件对象
ClassFile = new java.io.File(ClassFileName);
//创建文件对象
OutputFile = new java.io.File(outputFileName);
//如果文件已经存在,先删除,然后建立新文件
if (OutputFile.exists()) {
OutputFile.delete();
}
try {
OutputFile.createNewFile();
}
catch (Exception e) {
e.printStackTrace(System.err);
}
try {
//创建文件随机读取对象
java.io.RandomAccessFile ROutputFile = new java.io.RandomAccessFile(this.
OutputFile, "rw");
//提示信息
ROutputFile.write("//////////////////////////////////////////////////\n".
getBytes());
ROutputFile.write( ("//JAccidenceAnalyser version " + getVersion() +
" design by yellowicq//\n").getBytes());
ROutputFile.write("//java词法分析器//////////////\n".getBytes());
ROutputFile.write("//使用java语言开发////////////////////////////////////\n".
getBytes());
ROutputFile.write("//////////////////////////////////////////////////\n".
getBytes());
ROutputFile.write("词法分析结果如下:\n".getBytes());
//关闭文件流
ROutputFile.close();
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
/**
* @roseuid 3D9BAFAB0089
*/
public void startAA() {
//从预处理开始词法分析
this.pretreatment.startPretreatment();
}
/**
* @roseuid 3D9BB0B40383
*/
public void outputAccidence(String outputString) {
//把分析出来的单词写入文件
outputString = "\n[第" + this.pretreatment.fileRow + "行]\n" + outputString;
try {
//创建文件随机读取对象
java.io.RandomAccessFile ROutputFile = new java.io.RandomAccessFile(this.
OutputFile, "rw");
//移动指针到文件末尾
ROutputFile.seek(ROutputFile.length());
//Start appending!
ROutputFile.write(outputString.getBytes());
//关闭文件流
ROutputFile.close();
}
catch (Exception e) {
e.printStackTrace(System.err);
}
//将分析的单词结果输出到终端
System.out.print(outputString);
}
/**
* @roseuid 3D9BB0CE02C2
*/
public void controlThread() {
//控制扫描器启动扫描
scaner.controlThread();
}
//获得版本号
public String getVersion() {
return "1.0";
}
}
3) 预处理子程序:Pretreatment.java
//Source file: d:\\JAccidenceAnalyse\\Pretreatment.java
package JAccidenceAnalyse;
import JAccidenceAnalyse.Buffer.*;
import java.io.*;
public class Pretreatment {
private String tmpString;
private String outputString;
private int BUFFER_SIZE = 100;
private AccidenceAnalyser aa;
public InputBuffer inputBuffer; //输入缓冲区--共享
private java.io.File SourceFile; //文件对象
private java.io.RandomAccessFile randomAFile; //随机文件对象
public static int fileRow = 0;
/**
* @roseuid 3DAB7C530399
*/
public Pretreatment(File SourceFile, AccidenceAnalyser aa) {
try {
this.SourceFile = SourceFile;
this.randomAFile = new java.io.RandomAccessFile(this.SourceFile, "r");
}
catch (FileNotFoundException e) {
e.printStackTrace(System.err);
}
this.aa = aa;
inputBuffer = aa.csbFactory.createInputBuffer(BUFFER_SIZE);
System.out.println("[INFOR]预处理器已经创建!");
}
/**
* @roseuid 3D9BAFE20331
*/
public void putSourceToINBuffer(String tmpString) {
this.inputBuffer.Data = tmpString.toCharArray();
}
/**
* @roseuid 3D9BB0400169
*/
public void putFinToSCBuffer(String filtratedString) {
aa.scaner.scanBuffer.Data = filtratedString.toCharArray();
}
/**
* @roseuid 3D9BB05E00A4
*/
public void controlThread() {
int intLength;
int resCounter = 0;
String tmpString;
String filtratedString;
System.out.println("[INFOR]开始单词分析////////////////////////////////////////");
try {
if (SourceFile.exists()) { //文件存在
//读文件内容到缓冲区
while ( (tmpString = this.randomAFile.readLine()) != null) {
++fileRow;
//分割符
System.out.println("...................begin row " + this.fileRow +
".......................");
//开始这一行分析
System.out.println("[INFOR]正在处理行: " + String.valueOf(fileRow));
//放入输入缓冲区
this.putSourceToINBuffer(tmpString);
//处理字符串
filtratedString = this.filtrateSource(this.inputBuffer.Data);
System.out.println("[INFOR]已过滤句子: " + filtratedString);
//放入扫描缓冲区
this.putFinToSCBuffer(filtratedString);
aa.controlThread();
}
System.out.println(
"[INFOR]分析完毕////////////////////////////////////////////");
}
else { //文件不存在
System.err.println("[ERROR]源文件不存在!");
}
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
/**
* @roseuid 3D9BB07D0239
*/
public String filtrateSource(char[] Data) {
String filtratedString = String.valueOf(Data).trim();
return filtratedString;
}
/**
* @roseuid 3D9BB9350315
*/
public void startPretreatment() {
this.controlThread();
}
}
4) 扫描子程序:Scaner.java
//Source file: d:\\JAccidenceAnalyse\\Scaner.java
package JAccidenceAnalyse;
import JAccidenceAnalyse.Buffer.*;
public class Scaner {
public ScanBuffer scanBuffer; //扫描缓冲区--共享
private String finalAccidence;
private AccidenceAnalyser aa;
private int BUFFER_SIZE = 100;
private String toDelString;
private int senLength = 0;
private char[] sentenceChar = new char[1000];
private String TOKEN;
private char CHAR;
private int index = 0;
private String IDENTITY = "identity";
private String DIGIT = "digit";
private String WORD_ERROR_INF = "在此行发现不能识别的单词,此行分析终止!";
private boolean ASTATE = true;
/**
* @roseuid 3D9BB9370213
*/
public Scaner(AccidenceAnalyser aa) {
this.aa = aa;
initBuffer();
this.finalAccidence = "";
System.out.println("[INFOR]扫描处理器已经创建!");
}
/**
* @roseuid 3D9BB2860329
*/
public String readFromBuffer(char[] Data) {
String toDelString = String.valueOf(Data);
return toDelString;
}
/**
* @param tmpString
* @return String
* @roseuid 3D9BB2D5008D
*/
public String scan(String toDelString) {
sentenceChar = toDelString.toCharArray();
this.senLength = sentenceChar.length;
int i = 0;
//分析单词
while (this.index <= this.senLength) {
//state0:
this.TOKEN = "";
this.CHAR = GETBC(sentenceChar);
if (this.CHAR == ';') {
break; //';'表示这一行结束
}
//进入状态判断
switch (this.CHAR) {
//judge letter
case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':
case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':
case 'z':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':
case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z':
//do
this.TOKEN = this.CONTACT(TOKEN, CHAR);
//state1
CHAR = this.GETCHAR(sentenceChar);
while (this.ISLETTER(CHAR) || this.ISDIGIT(CHAR)) {
this.TOKEN = this.CONTACT(this.TOKEN, CHAR);
CHAR = this.GETCHAR(sentenceChar);
}
this.RETRACT();
//state2
if (aa.keyWordTable.isKeyWord(TOKEN)) {
this.finalAccidence = this.finalAccidence + "[保留字] " +
this.returnAWord(TOKEN) + "\n";
}
else {
this.finalAccidence = this.finalAccidence + "[标识符] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(IDENTITY)) + "\n";
}
//clear up token
this.TOKEN = "";
break;
//judge ditital
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
//do
this.TOKEN = this.CONTACT(TOKEN, CHAR);
//state3
CHAR = this.GETCHAR(sentenceChar);
while (this.ISDIGIT(CHAR)) {
this.TOKEN = this.CONTACT(TOKEN, CHAR);
CHAR = this.GETCHAR(sentenceChar);
}
this.RETRACT();
//state4
this.finalAccidence = this.finalAccidence + "[数字] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(DIGIT)) + "\n";
//clear up token
this.TOKEN = "";
break;
case '=':
//state5
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[等号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '+':
//state6
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[加号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '*':
//state7
this.TOKEN = this.CONTACT(TOKEN, CHAR);
CHAR = this.GETCHAR(sentenceChar);
//state8
if (CHAR == '*') {
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[乘方] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
}
//state9
else {
this.finalAccidence = this.finalAccidence + "[乘号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
}
//clear up token
this.TOKEN = "";
break;
case ',':
//state10
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[逗号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '(':
//state11
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[左括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case ')':
//state12
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[右括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '{':
//state13
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[左大括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '}':
//state14
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[右大括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '[':
//state15
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[左中括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case ']':
//state16
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[右中括号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
case '.':
//state17
this.TOKEN = this.CONTACT(TOKEN, CHAR);
this.finalAccidence = this.finalAccidence + "[点号] " +
this.returnAWord(TOKEN) + "[种别码] " +
String.valueOf(aa.classIdentity.findKey(String.valueOf(CHAR))) +
"\n";
//clear up token
this.TOKEN = "";
break;
default:
//state18
this.TOKEN = this.CONTACT(this.TOKEN, this.CHAR);
//追加出错信息
this.finalAccidence = this.finalAccidence + "[ERROR]" +
this.WORD_ERROR_INF + "'" + this.TOKEN + "'" + "\n";
this.ASTATE = false;
//clear up token
this.TOKEN = "";
break;
}
if (this.ASTATE == false) {
break;
}
}
return this.finalAccidence;
}
/**
* @roseuid 3D9BB2E70260
*/
public void controlThread() {
this.toDelString = this.readFromBuffer(this.scanBuffer.Data);
this.aa.outputAccidence(this.scan(this.toDelString));
//分割符
System.out.println("...................end row " + aa.pretreatment.fileRow +
".........................");
//结束这一行分析
//clear up the var
this.index = 0;
this.finalAccidence = "";
this.ASTATE = true;
this.toDelString = "";
this.senLength = 0;
this.TOKEN = "";
}
/**
* @param tmpString
* @return String
* @roseuid 3D9BB3FB037F
*/
public String returnAWord(String TOKEN) {
return TOKEN;
}
/**
* @roseuid 3D9BB55502B4
*/
public void initBuffer() {
this.scanBuffer = aa.csbFactory.createScanBuffer(BUFFER_SIZE);
}
//以下为字符的处理方法
/////////////////////////////////////////////////////
//////////////字符方法开始///////////////////////////
/////////////////////////////////////////////////////
/**
* @roseuid 3D9BB0B40383
*/
public char GETBC(char[] sentenceChar) {
try {
while ( (sentenceChar[this.index]) == ' ') {
this.index++;
}
this.index++;
}
catch (java.lang.ArrayIndexOutOfBoundsException e) {
return ';'; //表示此行已经结束
}
return sentenceChar[index - 1];
}
/**
* @roseuid 3D9BB0B40383
*/
public char GETCHAR(char[] sentenceChar) {
next();
return sentenceChar[this.index - 1];
}
/**
* @roseuid 3D9BB0B40383
*/
public void next() {
this.index++;
}
/**
* @roseuid 3D9BB0B40383
*/
public boolean ISLETTER(char letter) {
return java.lang.Character.isLetter(letter);
}
/**
* @roseuid 3D9BB0B40383
*/
public boolean ISDIGIT(char letter) {
return java.lang.Character.isDigit(letter);
}
/**
* @roseuid 3D9BB0B40383
*/
public String CONTACT(String TOKEN, char CHAR) {
String tmpS = TOKEN + String.valueOf(CHAR);
TOKEN = tmpS;
return TOKEN;
}
/**
* @roseuid 3D9BB0B40383
*/
public boolean ISRESERVE(String TOKEN) {
return aa.keyWordTable.isKeyWord(TOKEN);
}
/**
* @roseuid 3D9BB0B40383
*/
public void RETRACT() {
this.index--;
}
/////////////////////////////////////////////////////
//////////////字符方法结束///////////////////////////
/////////////////////////////////////////////////////
}
5) 表留字表程序:KeyWordTable.java
//Source file: d:\\JAccidenceAnalyse\\KeyWordTable.java
package JAccidenceAnalyse;
import java.util.*;
import java.io.*;
public class KeyWordTable {
private Hashtable KWHash;
private File ReserveFile;
private FileReader resFileReader; //读文件对象
private int TMP_BUFFER_SIZE = 30;
/**
* @roseuid 3D9BB9390108
*/
public KeyWordTable(java.io.File ReserveFile) {
System.out.println("[INFOR]关键字表已创建!");
this.ReserveFile = ReserveFile;
}
/**
* @param inw
* @return boolean
* @roseuid 3D9BAE4702AD
*/
public boolean isKeyWord(String inw) {
String resWord;
//查找hash表
for (Enumeration e = this.KWHash.elements(); e.hasMoreElements(); ) {
resWord = (String) e.nextElement();
if (resWord.equalsIgnoreCase(inw)) {
return true;
}
}
return false;
}
/**
* @roseuid 3D9BAE7303D3
*/
public void initKeyWordTable() {
KWHash = new Hashtable(); //创建hash表
int intLength;
char[] chrBuffer = new char[TMP_BUFFER_SIZE];
String resWord;
int resCounter = 0;
try {
if (ReserveFile.exists()) { //文件存在
//创建读文件对象
resFileReader = new java.io.FileReader(ReserveFile);
//读文件内容到hash表
while ( (intLength = resFileReader.read(chrBuffer)) != -1) {
resCounter++;
//填写hash表
resWord = String.valueOf(chrBuffer).trim();
System.out.println("[INFOR]读取关键字: [INDEX: " + resCounter +
"][VALUE: " + resWord + "]");
this.KWHash.put(Integer.toString(resCounter), resWord);
}
//关闭读文件对象
resFileReader.close();
}
else { //文件不存在
System.err.println("[ERROR]保留字文件不存在!");
}
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
6) 类型种别码程序:ClassIdentity.java
//Source file: d:\\JAccidenceAnalyse\\KeyWordTable.java
package JAccidenceAnalyse;
import java.util.*;
import java.io.*;
public class ClassIdentity {
private Hashtable ClassHash;
private File ClassFile;
private FileReader classFileReader; //读文件对象
private int TMP_BUFFER_SIZE = 30;
/**
* @roseuid 3D9BB9390108
*/
public ClassIdentity(java.io.File ClassFile) {
System.out.println("[INFOR]类型种别码表已创建!");
this.ClassFile = ClassFile;
}
/**
* @roseuid 3D9BB0B40383
*/
//查找类型种别码
public int findKey(String classWord) {
int KEY;
for (Enumeration e = this.ClassHash.keys(); e.hasMoreElements(); ) {
KEY = Integer.parseInt( (String) e.nextElement());
if ( ( (String)this.ClassHash.get(Integer.toString(KEY))).
equalsIgnoreCase(classWord)) {
return KEY;
}
}
return -1;
}
/**
* @roseuid 3D9BAE7303D3
*/
public void initClassIdentityTable() {
ClassHash = new Hashtable(); //创建hash表
int intLength;
char[] chrBuffer = new char[TMP_BUFFER_SIZE];
String classWord;
int classCounter = 0;
try {
if (ClassFile.exists()) { //文件存在
//创建读文件对象
classFileReader = new java.io.FileReader(ClassFile);
//读文件内容到hash表
while ( (intLength = classFileReader.read(chrBuffer)) != -1) {
classCounter++;
//填写hash表
classWord = String.valueOf(chrBuffer).trim();
System.out.println("[INFOR]读取类型种别码: [KEY: " + classCounter +
"][VALUE: " + classWord + "]");
this.ClassHash.put(Integer.toString(classCounter), classWord);
}
//关闭读文件对象
classFileReader.close();
}
else { //文件不存在
System.err.println("[ERROR]类型种别码文件不存在!");
}
}
catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
7) 抽象扫描缓冲区工厂:BufferFactory.java(使用抽象工厂方法模式产生缓冲区对象)
//Source file: d:\\JAccidenceAnalyse\\Buffer\\BufferFactory.java
package JAccidenceAnalyse.Buffer;
public interface BufferFactory {
/**
* @return JAccidenceAnalyse.Buffer.ScanBuffer
* @roseuid 3D9BB6F0003E
*/
public ScanBuffer createScanBuffer(int size);
/**
* @return JAccidenceAnalyse.Buffer.InputBuffer
* @roseuid 3D9BB7090062
*/
public InputBuffer createInputBuffer(int size);
}
8) 缓冲区工厂:ConcreteScanBufferFactory.java(实现了抽象工厂)
//Source file: d:\\JAccidenceAnalyse\\Buffer\\ConcreteScanBufferFactory.java
package JAccidenceAnalyse.Buffer;
public class ConcreteScanBufferFactory
implements BufferFactory {
/**
* @roseuid 3D9BBA19006A
*/
public ConcreteScanBufferFactory() {
System.out.println("[INFOR]缓冲区工厂已经建立!");
}
/**
* @return JAccidenceAnalyse.Buffer.ScanBuffer
* @roseuid 3D9BAC01004E
*/
public ScanBuffer createScanBuffer(int size) {
System.out.println("[INFOR]创建扫描缓冲区!");
return new ScanBuffer(size);
}
/**
* @return JAccidenceAnalyse.Buffer.InputBuffer
* @roseuid 3D9BB6050267
*/
public InputBuffer createInputBuffer(int size) {
System.out.println("[INFOR]创建输入缓冲区!");
return new InputBuffer(size);
}
}
9) 缓冲区对象抽象接口:Buffer.java
//Source file: d:\\JAccidenceAnalyse\\Buffer\\Buffer.java
package JAccidenceAnalyse.Buffer;
//abstract buffer interface
public interface Buffer {
}
10) 输入缓冲区对象:InputBuffer.java
//Source file: d:\\JAccidenceAnalyse\\Buffer\\InputBuffer.java
package JAccidenceAnalyse.Buffer;
import java.io.*;
public class InputBuffer
implements Buffer {
public char[] Data;
/**
* @roseuid 3D9BBA1C0186
*/
public InputBuffer(int size) {
this.Data = new char[size];
}
}
11) 扫描缓冲区对象:ScanBuffer.java
//Source file: d:\\JAccidenceAnalyse\\Buffer\\ScanBuffer.java
package JAccidenceAnalyse.Buffer;
public class ScanBuffer
implements Buffer {
public char[] Data;
/**
* @roseuid 3D9BBA1A0314
*/
public ScanBuffer(int size) {
this.Data = new char[size];
}
}
12) 词法分析器配置文件:aaCfg.xml
<?xml version="1.0" standalone="yes"?>
<Analyzer>
<FilePath>
<ReserveFileName>d:\\reserve.table</ReserveFileName>
<ClassFileName>d:\\class.table</ClassFileName>
<SourceFileName>d:\\aClass.java</SourceFileName>
<OutputFileName>d:\\output.aa</OutputFileName>
</FilePath>
</Analyzer>
13) 类型种别码文件:class.table
identity
digit
=
+
*
**
,
(
)
{
}
[
]
.
14) 关键字表文件:reserve.table
while
do
public
class
static
new
void
int
do
for
int
System
15) 一个测试文件:aClass.java
public class aClass{
public void aMethod( int value ) {
System.out.println( value );
}
public static void main( String[] args ){
aClass foo = new aClass();
int i=0;
foo.aMethod(i);
i = i+1;
foo.aMethod(i);
}
}
16)分析以后的输出结果:output.aa
//////////////////////////////////////////////////
//JAccidenceAnalyser version 1.0 design by yellowicq//
//java词法分析器//////////////
//使用java语言开发////////////////////////////////////
//////////////////////////////////////////////////
词法分析结果如下:
[第1行]
[保留字] public
[保留字] class
[标识符] aClass[种别码] 1
[左大括号] {[种别码] 10
[第2行]
[保留字] public
[保留字] void
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[保留字] int
[标识符] value[种别码] 1
[右括号] )[种别码] 9
[左大括号] {[种别码] 10
[第3行]
[保留字] System
[点号] .[种别码] 14
[标识符] out[种别码] 1
[点号] .[种别码] 14
[标识符] println[种别码] 1
[左括号] ([种别码] 8
[标识符] value[种别码] 1
[右括号] )[种别码] 9
[第4行]
[右大括号] }[种别码] 11
[第5行]
[保留字] public
[保留字] static
[保留字] void
[标识符] main[种别码] 1
[左括号] ([种别码] 8
[标识符] String[种别码] 1
[左中括号] [[种别码] 12
[右中括号] ][种别码] 13
[标识符] args[种别码] 1
[右括号] )[种别码] 9
[左大括号] {[种别码] 10
[第6行]
[标识符] aClass[种别码] 1
[标识符] foo[种别码] 1
[等号] =[种别码] 3
[保留字] new
[标识符] aClass[种别码] 1
[左括号] ([种别码] 8
[右括号] )[种别码] 9
[第7行]
[保留字] int
[标识符] i[种别码] 1
[等号] =[种别码] 3
[数字] 0[种别码] 2
[第8行]
[标识符] foo[种别码] 1
[点号] .[种别码] 14
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[标识符] i[种别码] 1
[右括号] )[种别码] 9
[第9行]
[标识符] i[种别码] 1
[等号] =[种别码] 3
[标识符] i[种别码] 1
[加号] +[种别码] 4
[数字] 1[种别码] 2
[第10行]
[标识符] foo[种别码] 1
[点号] .[种别码] 14
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[标识符] i[种别码] 1
[右括号] )[种别码] 9
[第11行]
[右大括号] }[种别码] 11
[第12行]
[右大括号] }[种别码] 11
16) 运行时的系统显示:jbuilder.runtime
D:\JBuilder6\jdk1.3.1\bin\javaw -classpath
"F:\mybak_new\jbproject\JAccidenceAnalyse\classes;D:\JBuilder7\lib\rowset.jar;D:\JBuilder6\lib\xerces.jar;D:\JBuilder6\jdk1.3.1\demo\jfc\Java2D\Java2Demo.jar;D:\JBuilder6\jdk1.3.1\jre\lib\i18n.jar;D:\JBuilder6\jdk1.3.1\jre\lib\jaws.jar;D:\JBuilder6\jdk1.3.1\jre\lib\rt.jar;D:\JBuilder6\jdk1.3.1\jre\lib\sunrsasign.jar;D:\JBuilder6\jdk1.3.1\lib\dt.jar;D:\JBuilder6\jdk1.3.1\lib\htmlconverter.jar;D:\JBuilder6\jdk1.3.1\lib\tools.jar" JAccidenceAnalyse.main
[INFOR]已经建立词法分析器!
[INFOR]缓冲区工厂已经建立!
[INFOR]创建扫描缓冲区!
[INFOR]扫描处理器已经创建!
[INFOR]创建输入缓冲区!
[INFOR]预处理器已经创建!
[INFOR]关键字表已创建!
[INFOR]类型种别码表已创建!
[INFOR]已经初始化词法分析器!
[INFOR]读取关键字: [INDEX: 1][VALUE: while]
[INFOR]读取关键字: [INDEX: 2][VALUE: do]
[INFOR]读取关键字: [INDEX: 3][VALUE: public]
[INFOR]读取关键字: [INDEX: 4][VALUE: class]
[INFOR]读取关键字: [INDEX: 5][VALUE: static]
[INFOR]读取关键字: [INDEX: 6][VALUE: new]
[INFOR]读取关键字: [INDEX: 7][VALUE: void]
[INFOR]读取关键字: [INDEX: 8][VALUE: int]
[INFOR]读取关键字: [INDEX: 9][VALUE: do]
[INFOR]读取关键字: [INDEX: 10][VALUE: for]
[INFOR]读取关键字: [INDEX: 11][VALUE: int]
[INFOR]读取关键字: [INDEX: 12][VALUE: System]
[INFOR]读取类型种别码: [KEY: 1][VALUE: identity]
[INFOR]读取类型种别码: [KEY: 2][VALUE: digit]
[INFOR]读取类型种别码: [KEY: 3][VALUE: =]
[INFOR]读取类型种别码: [KEY: 4][VALUE: +]
[INFOR]读取类型种别码: [KEY: 5][VALUE: *]
[INFOR]读取类型种别码: [KEY: 6][VALUE: **]
[INFOR]读取类型种别码: [KEY: 7][VALUE: ,]
[INFOR]读取类型种别码: [KEY: 8][VALUE: (]
[INFOR]读取类型种别码: [KEY: 9][VALUE: )]
[INFOR]读取类型种别码: [KEY: 10][VALUE: {]
[INFOR]读取类型种别码: [KEY: 11][VALUE: }]
[INFOR]读取类型种别码: [KEY: 12][VALUE: []
[INFOR]读取类型种别码: [KEY: 13][VALUE: ]]
[INFOR]读取类型种别码: [KEY: 14][VALUE: .]
[INFOR]开始单词分析////////////////////////////////////////
...................begin row 1.......................
[INFOR]正在处理行: 1
[INFOR]已过滤句子: public class aClass{
[第1行]
[保留字] public
[保留字] class
[标识符] aClass[种别码] 1
[左大括号] {[种别码] 10
...................end row 1.........................
...................begin row 2.......................
[INFOR]正在处理行: 2
[INFOR]已过滤句子: public void aMethod( int value ) {
[第2行]
[保留字] public
[保留字] void
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[保留字] int
[标识符] value[种别码] 1
[右括号] )[种别码] 9
[左大括号] {[种别码] 10
...................end row 2.........................
...................begin row 3.......................
[INFOR]正在处理行: 3
[INFOR]已过滤句子: System.out.println( value );
[第3行]
[保留字] System
[点号] .[种别码] 14
[标识符] out[种别码] 1
[点号] .[种别码] 14
[标识符] println[种别码] 1
[左括号] ([种别码] 8
[标识符] value[种别码] 1
[右括号] )[种别码] 9
...................end row 3.........................
...................begin row 4.......................
[INFOR]正在处理行: 4
[INFOR]已过滤句子: }
[第4行]
[右大括号] }[种别码] 11
...................end row 4.........................
...................begin row 5.......................
[INFOR]正在处理行: 5
[INFOR]已过滤句子: public static void main( String[] args ){
[第5行]
[保留字] public
[保留字] static
[保留字] void
[标识符] main[种别码] 1
[左括号] ([种别码] 8
[标识符] String[种别码] 1
[左中括号] [[种别码] 12
[右中括号] ][种别码] 13
[标识符] args[种别码] 1
[右括号] )[种别码] 9
[左大括号] {[种别码] 10
...................end row 5.........................
...................begin row 6.......................
[INFOR]正在处理行: 6
[INFOR]已过滤句子: aClass foo = new aClass();
[第6行]
[标识符] aClass[种别码] 1
[标识符] foo[种别码] 1
[等号] =[种别码] 3
[保留字] new
[标识符] aClass[种别码] 1
[左括号] ([种别码] 8
[右括号] )[种别码] 9
...................end row 6.........................
...................begin row 7.......................
[INFOR]正在处理行: 7
[INFOR]已过滤句子: int i=0;
[第7行]
[保留字] int
[标识符] i[种别码] 1
[等号] =[种别码] 3
[数字] 0[种别码] 2
...................end row 7.........................
...................begin row 8.......................
[INFOR]正在处理行: 8
[INFOR]已过滤句子: foo.aMethod(i);
[第8行]
[标识符] foo[种别码] 1
[点号] .[种别码] 14
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[标识符] i[种别码] 1
[右括号] )[种别码] 9
...................end row 8.........................
...................begin row 9.......................
[INFOR]正在处理行: 9
[INFOR]已过滤句子: i = i+1;
[第9行]
[标识符] i[种别码] 1
[等号] =[种别码] 3
[标识符] i[种别码] 1
[加号] +[种别码] 4
[数字] 1[种别码] 2
...................end row 9.........................
...................begin row 10.......................
[INFOR]正在处理行: 10
[INFOR]已过滤句子: foo.aMethod(i);
[第10行]
[标识符] foo[种别码] 1
[点号] .[种别码] 14
[标识符] aMethod[种别码] 1
[左括号] ([种别码] 8
[标识符] i[种别码] 1
[右括号] )[种别码] 9
...................end row 10.........................
...................begin row 11.......................
[INFOR]正在处理行: 11
[INFOR]已过滤句子: }
[第11行]
[右大括号] }[种别码] 11
...................end row 11.........................
...................begin row 12.......................
[INFOR]正在处理行: 12
[INFOR]已过滤句子: }
[第12行]
[右大括号] }[种别码] 11
...................end row 12.........................
[INFOR]分析完毕////////////////////////////////////////////