import java.io.*;import java.util.*;
/** * 词法分析器 * * 1.关键字: abstract boolean break byte case catch char class continue * default do double else extends final finally float for if implements import * instanceof int interface long native new package private protected public * return short static super switch synchronized this throw throws transient try * void volatile while * * 2.标识符 * * 3. 常数 * * 4.运算符包括:+、-、*、/、=、>、< * * 5.分隔符包括:, ; { } ( ) [ ] * * 程序过程: 0.定义部分:定义常量、变量、数据结构。 * * 1.初始化:从文件将源程序全部输入到字符缓冲区中。 * * 2.取单词前:去掉多余空白。 * * 3.取单词后:去掉多余空白(可选,看着办)。 * * 4.取单词:读出单词的每一个字符,组成单词,分析类型。(关键是如何判断取单词结束?取到的单词是什么类型的单词?) * * 5.显示结果。 */
public class Analyzer {
private String keyWords[] = { "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "continue", "default", "do", "double", "else", "extends", "final", "finally", "float", "for", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while" }; // 关键字数组 private char operators[] = { '+', '-', '*', '/', '=', '>', '<', '&' }; // 运算符数组 private char separators[] = { ',', ';', '{', '}', '(', ')','[',']','_',':','、','.' ,'"'}; // 分隔符数组 private String fileSrcName; // 源程序名 private StringBuffer buffer = new StringBuffer(); // 缓冲区 private char ch; // 字符变量,存放最新读进的源程序字符 private static int i = 0; private String strToken; // 字符数组,存放构成单词符号的字符串 private HashSet<String> retKeyWords = new HashSet<String>(); // 1.关键字结果 private HashSet<String> retIds = new HashSet<String>(); // 2.标识符结果 private HashSet<Integer> retConsts = new HashSet<Integer>(); // 3.常数结果 private HashSet<Character> retOperators = new HashSet<Character>(); // 4.运算符结果 private HashSet<Character> retSeparators = new HashSet<Character>(); // 5.分隔符结果
/** * 构造方法 */ public Analyzer() {
}
public Analyzer(String fileSrcName) { this.fileSrcName = fileSrcName; }
/** * 将下一个输入字符读到ch中,搜索指示器前移一个字符 */ public void getChar() { ch = buffer.charAt(i); i++; }
/** * 检查ch中的字符是否为空白,若是则调用getChar() 直至ch中进入一个非空白字符 */ public void getBc() {// while (ch == ' ' || ch == '/t' || ch == '/n') { // 检查ch中的字符是否为空白// getChar();// } while(Character.isSpaceChar(ch)) getChar(); }
/** * 将ch连接到strToken之后 */ public void concat() { strToken += ch; }
/** * 判断字符是否为字母 */ boolean isLetter() {// if ((ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'))// return true; if(Character.isLetter(ch)) return true; return false; }
/** * 判断字符是否为数字 */ boolean isDigit() {// if (ch >= '0' && ch <= '9')// return true; if(Character.isDigit(ch)) return true; return false; }
/** * 将搜索指示器回调一个字符位置,将ch值为空白字 */ public void retract() { i--; ch = ' '; }
/** * 判断单词是否为关键字 */ public boolean isKeyWord() {
for (int i = 0; i < keyWords.length; i++) { if (keyWords[i].equals(strToken)) return true; } return false; }
/** * 判断是否为运算符 */ public boolean isOperator() { for (int i = 0; i < operators.length; i++) { if (ch == operators[i]) return true; } return false; }
/** * 判断是否为分隔符 */ public boolean isSeparators() { for (int i = 0; i < separators.length; i++) { if (ch == separators[i]) return true; } return false; }
/** * 将strToken插入到关键字表 */ public void insertKeyWords(String strToken) { retKeyWords.add(strToken); }
/** * 将strToken插入到符号表 */ public void insertId(String strToken) { retIds.add(strToken); }
/** * 将strToken中的常数插入到常数表中 */ public void insertConst(String strToken) { int num = Integer.parseInt(strToken); retConsts.add(num); }
/** * 将ch插入到运算符表中 */ public void insertOperators(char ch) { retOperators.add(ch); }
/** * 将ch插入到分隔符表 */ public void insertSeparators() { retSeparators.add(ch); }
/** * 将源程序读入到缓冲区中 */ public void readFile() { try { FileReader fis = new FileReader(this.fileSrcName); BufferedReader br = new BufferedReader(fis); String temp = null; while ((temp = br.readLine()) != null) { buffer.append(temp); }
} catch (FileNotFoundException e) { System.out.println("源文件未找到!"); e.printStackTrace(); } catch (IOException e) { System.out.println("读写文件出现异常!"); e.printStackTrace(); } }
/** * 词法分析 */ public void analyse() { boolean code, value; strToken = ""; // 置strToken为空串 while (i < buffer.length()) { getChar(); getBc(); if (isLetter()) { // 如果ch为字母 while (isLetter() || isDigit()) { concat(); getChar(); } retract(); // 回调 code = isKeyWord(); // 判断strToken是否为关键字 if (code) { // 如果是,则插入到1.保留字表中 insertKeyWords(strToken); } else { // 否则插入到2.符号表中 insertId(strToken); } strToken=""; } else if (isDigit()) { // 如果ch为数字 while (isDigit()) { concat(); getChar(); } retract(); // 回调 insertConst(strToken); // 是常数,插入到3.常数表中 strToken=""; } else if (isOperator()) { // 如果是运算符,则插入到4.运算符表 insertOperators(ch); } else if (isSeparators()) { // 如果是分隔符,插入到5.分隔符表中 insertSeparators(); } }
}
public static void main(String[] args) {
/* * Scanner in = new Scanner(System.in); * System.out.println("请输入要分析的文件名:"); String fileName = in.next(); */ Analyzer alr = new Analyzer("F://java//Analisis//src//test.txt"); alr.readFile(); alr.analyse();
System.out.println("词法分析器的分析结果如下:"); System.out.println("1、关键字表"); for (String key : alr.retKeyWords) { System.out.print(key + " "); } System.out.println(); System.out.println("2、标识符表"); for (String id : alr.retIds) { System.out.print(id + " "); } System.out.println(); System.out.println("3、常数表"); for (Integer con : alr.retConsts) { System.out.print(con + " "); } System.out.println(); System.out.println("4、运算符表"); for (Character operator : alr.retOperators) { System.out.print(operator + " "); } System.out.println(); System.out.println("5、分隔符表"); for (Character separator : alr.retSeparators) { System.out.print(separator + " "); } }
}