编制一个读单词函数,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import static java.lang.System.out;
public class LexicalAnalyst {
private final String FILE_PATH = 你要分析的程序代码;
private final String IDENTIFIER_CHARACTER_SET = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_&";
private HashMap<String, String> preservedKeysMapping = new HashMap<>();
private HashMap<String, String> operatorsMapping = new HashMap<>();
private HashMap<String, String> separatorsMapping = new HashMap<>();
private final String CONST_STRING = "numbers";
private final String IDENTIFIER_STRING = "ident";
private final String ERROR_STRING = "Error";
private final int TYPE_CONST = 0;
private final int TYPE_IDENTIFIER = 1;
private final int TYPE_ERROR = 2;
private String[] info = new String[3];
private final int STACK_SIZE = 100;
public void work () throws IOException {
init();//初始化映射信息
FileReader reader = new FileReader(new File(FILE_PATH));
int content = reader.read();
char[] stack = new char[STACK_SIZE];
int top = -1;
while (content != -1) {
char ch = (char) content;
//out.println("ch: " + ch);
if (isBlank(ch)) {
if (top != -1) {
onSingleWord(new String(stack, 0, top + 1));
stack = new char[STACK_SIZE];
top = -1;
}
} else {
String s = ch + "";
if (operatorsMapping.containsKey(s) || separatorsMapping.containsKey(s)) {
// onSingleWord(s);
//遇到操作符或者分隔符则清空栈
if (top != -1) {
onSingleWord(new String(stack, 0, top+1));
stack = new char[STACK_SIZE];
top = -1;
}
onSingleWord(s);
} else {
stack[++top] = ch;
}
}
content = reader.read();
}
if (top != -1) {
onSingleWord(new String(stack, 0, top + 1));
}
}
/*识别单个单词*/
private void onSingleWord (String word) {
/*前附*/
if (preservedKeysMapping.containsKey(word)) {
out.println(preservedKeysMapping.get(word) + ", " + word);
} else {
if (operatorsMapping.containsKey(word)) {
out.println(operatorsMapping.get(word) + ", " + word);
} else {
if (separatorsMapping.containsKey(word)) {
out.println(separatorsMapping.get(word) + ", " + word);
} else {
out.println(info[getType(word)] + ", " + word);
}
}
}
}
private int getType (String word) {
char ch = word.charAt(0);
if (ch>= '0' && ch <= '9') {
//如果以数字开头则考虑常量或者错误
for (int i = 1; i < word.length(); ++i) {
if (word.charAt(i) < '0' || word.charAt(i) > '9')
return TYPE_ERROR;
}
return TYPE_CONST;
} else {
//考虑标识符或错误
for (int i = 0; i < word.length(); ++i) {
if (IDENTIFIER_CHARACTER_SET.indexOf(word.charAt(i)) < 0)
return TYPE_ERROR;
}
return TYPE_IDENTIFIER;
}
}
/*判断是否是空白*/
private boolean isBlank (char ch) {
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
return true;
else return false;
}
/*初始化map*/
private void init() {
/*前附*/
//初始化info数组
info[TYPE_CONST] = CONST_STRING;
info[TYPE_IDENTIFIER] = IDENTIFIER_STRING;
info[TYPE_ERROR] = ERROR_STRING;
//初始化保留字
preservedKeysMapping.put("public", "publicsys");
preservedKeysMapping.put("static", "staticsys");
preservedKeysMapping.put("class", "classsys");
preservedKeysMapping.put("void", "voidsys");
preservedKeysMapping.put("main", "mainsys");
preservedKeysMapping.put("private", "privatesys");
preservedKeysMapping.put("return", "returnsys");
preservedKeysMapping.put("if", "ifsys");
preservedKeysMapping.put("while", "whilesys");
preservedKeysMapping.put("for", "forsys");
preservedKeysMapping.put("else", "elsesys");
//初始化操作符
operatorsMapping.put("+", "plus");
operatorsMapping.put("-", "minus");
operatorsMapping.put("*", "times");
operatorsMapping.put("/", "slash");
operatorsMapping.put("=", "eql");
operatorsMapping.put(">", "gtr");
operatorsMapping.put("<", "lss");
operatorsMapping.put(">=", "geq");
operatorsMapping.put("<=", "leq");
operatorsMapping.put("!=", "neq");
//初始化分隔符
separatorsMapping.put(",", "comma");
separatorsMapping.put(";", "semicolon");
separatorsMapping.put("(", "lparen");
separatorsMapping.put(")", "rparen");
separatorsMapping.put("{", "lbparen");
separatorsMapping.put("}", "rbparen");
separatorsMapping.put("[", "lsparen");
separatorsMapping.put("]", "rsparen");
}
}
使用姿势
import java.io.IOException;
public class Test {
public static void main (String[] args) throws IOException {
new LexicalAnalyst().work();
}
}