📄 lexer.java
字号:
/*
* @(#)Lexer.java 1.0.0 05/13/2007
*
* Copyright 2007 Xuxt@buaa, No.34060520 All rights reserved.
*/
package com.king4solomon.homework.compiler.core;
import com.king4solomon.homework.compiler.gui.*;
import java.io.*;
import java.util.*;
/**
* @author Xuxt@buaa
*
*/
public final class Lexer {
/**
* 设置词法输入流方法
*
* @param fr
* 打开的文件读入类
*/
public static void setFileRdr(FileReader fr) {
in = new BufferedReader(fr);
}
/**
* 设置调式标志变量方法
*
* @param b
* 待设项
*/
public static void setDebug(boolean b) {
isDebug = b;
}
/**
* 从两个缓冲区中读出词法标志类型,若为空则从流中读一个
*
* @return 读出的词法标志类型
*/
public static int getSym() {
if (isEpt2) {
int temp = getSymNoBuf();
val = value;
return temp;
} else if (isEpt1) {
val = bufValue2;
isEpt2 = true;
return bufSym2;
} else {
val = bufValue1;
isEpt1 = true;
return bufSym1;
}
}
/**
* 向缓冲区中写回方法
*
* @param sym
* 待写回的词法标志类型
* @param value
* 待写回的值
*/
public static void ungetSym(int sym, String value) {
if (isEpt2) {
bufSym2 = sym;
bufValue2 = value;
isEpt2 = false;
} else if (isEpt1) {
bufSym1 = sym;
bufValue1 = value;
isEpt1 = false;
}
};
/**
* 从流中读出一个词法标识类型
*
* @return 返回读出的词法标志类型
*/
private static int getSymNoBuf() {
// skip blank
while (Character.isWhitespace(crtChar)) {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
}
// reserved word or identifier
if (Character.isLetter(crtChar) || crtChar == '_') {
wLength = 0;
do {
crtWord[wLength] = crtChar;
wLength += 1;
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (Character.isLetterOrDigit(crtChar) || crtChar == '_');
// reserved word
if (isReserved()) {
value = ReservedTable.rsvWord[idx];
if (value.equals("int") || value.equals("float")
|| value.equals("char"))
return ConstSet.TYPE_IDEN;
return ConstSet.RESERVED_WORD;
}
// identifier
else {
value = new String(crtWord, 0, wLength).toLowerCase();
return ConstSet.IDENTIFIER;
}
}
// unsigned
else if (Character.isDigit(crtChar)) {
return unSigned();
}
// signed or add
else if (crtChar == '+') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
value = "+";
return ConstSet.ADDSYM;
}
// signed or sub
else if (crtChar == '-') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (Character.isDigit(crtChar)) {
type = unSigned();
if (type == ConstSet.REAL)
realValue = -realValue;
else if (type == ConstSet.INTEGER) {
value = new String('-' + value);
intValue = -intValue;
}
return type;
} else {
value = "-";
return ConstSet.SUBSYM;
}
} else if (crtChar == '*') {
value = "*";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.MULSYM;
} else if (crtChar == '/') {
value = "/";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.DIVSYM;
} else if (crtChar == ',') {
value = ",";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.COMMA;
} else if (crtChar == ';') {
value = ";";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.SEMICOLON;
} else if (crtChar == ':') {
value = ":";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.COLON;
}
// Character
else if (crtChar == '\'') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '+' || crtChar == '-' || crtChar == '*'
|| crtChar == '/' || crtChar == '_'
|| Character.isLetterOrDigit(crtChar)) {
int tmpVal = charVal(crtChar);
if (tmpVal != -1)
value = "" + tmpVal;
} else {
ErrorManager.error(21);
if (lSkip(21) != 0)
return ConstSet.STOP;
value = "";
return ConstSet.CHARACTER;
}
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '\'') {
ch = getChar();
return ConstSet.CHARACTER;
} else {
ErrorManager.error(23);
if (lSkip(23) != 0)
return ConstSet.STOP;
return ConstSet.CHARACTER;
}
}
// String
else if (crtChar == '\"') {
value = "";
sLength = 0;
do {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar != '"') {
value += crtChar;
sLength += 1;
}
} while (crtChar != '\"' && sLength < 20);
if (sLength == 20) {
ErrorManager.error(24);
if (lSkip(24) != 0)
return ConstSet.STOP;
}
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.STRING;
} else if (crtChar == '(') {
value = "(";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.LEFT_PRENTHESES;
} else if (crtChar == ')') {
value = ")";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RIGHT_PRENTHESES;
} else if (crtChar == '{') {
value = "{";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.LEFT_CURLY;
} else if (crtChar == '}') {
value = "}";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RIGHT_CURLY;
}
// < or <=
else if (crtChar == '<') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '=') {
value = "<=";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RELA_OPR;
} else {
value = "<";
return ConstSet.RELA_OPR;
}
}
// > or >=
else if (crtChar == '>') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '=') {
value = ">=";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RELA_OPR;
} else {
value = ">";
return ConstSet.RELA_OPR;
}
} else if (crtChar == '=') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '=') {
value = "==";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RELA_OPR;
} else {
value = "=";
return ConstSet.EVALUATE;
}
} else if (crtChar == '!') {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (crtChar == '=') {
value = "!=";
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
return ConstSet.RELA_OPR;
} else {
ErrorManager.error(25);
if (lSkip(25) != 0)
return ConstSet.STOP;
return ConstSet.WRONG_CHAR;
}
} else {
value = "?";
ErrorManager.error(28);
if (lSkip(28) != 0)
return ConstSet.STOP;
return ConstSet.UNKNOWN_CHAR;
}
}
public static String getValue() {
return val;
}
private static int lSkip(int errNum) {
do {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (!found(crtChar, ErrorManager.lexErrSet[errNum]));
return 0;
}
private static boolean found(char aChar, char[] charSet) {
int len = charSet.length;
for (int idx = 0; idx < len; idx++) {
if (aChar == charSet[idx])
return true;
}
return false;
}
@SuppressWarnings("deprecation")
private static char getChar() {
try {
if (cCount == 0) {
bufLine = in.readLine();
if (bufLine == null) {
ErrorManager.error(0);
return ConstSet.EXCEPTION_EXIT;
} else {
lineNo += 1;
ConsolePane.write(bufLine + '\n');
lLength = bufLine.length();
if (lLength == 0) {
crtChar = ' ';
} else {
crtChar = bufLine.charAt(cCount);
cCount += 1;
}
}
} else {
if (cCount == lLength) {
cCount = 0;
crtChar = ' ';
if (isDebug)
thr.suspend();
} else {
crtChar = bufLine.charAt(cCount);
cCount += 1;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return crtChar;
}
private static boolean isReserved() {
idx = Arrays.binarySearch(ReservedTable.rsvWord, new String(crtWord, 0,
wLength));
if (idx >= 0) {
return true;
} else {
return false;
}
}
private static int unSigned() {
nLength = 0;
if (crtChar != '0') {
do {
crtNum[nLength] = crtChar;
nLength += 1;
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (Character.isDigit(crtChar));
} else {
do {
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (crtChar == '0');
crtNum[0] = '0';
nLength += 1;
if (Character.isDigit(crtChar)) {
ErrorManager.warning(0);
do {
crtNum[nLength] = crtChar;
nLength += 1;
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (Character.isDigit(crtChar));
}
}
if (crtChar == '.') {
crtNum[nLength] = '.';
nLength += 1;
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
if (Character.isDigit(crtChar)) {
do {
crtNum[nLength] = crtChar;
nLength += 1;
ch = getChar();
if (ch == ConstSet.EXCEPTION_EXIT)
return ConstSet.STOP;
} while (Character.isDigit(crtChar));
value = new String(crtNum, 0, nLength);
realValue = Float.parseFloat(value);
return ConstSet.REAL;
} else {
ErrorManager.error(22);
if (lSkip(22) != 0)
return ConstSet.STOP;
value = new String(crtNum, 0, nLength - 1);
intValue = Integer.parseInt(value);
return ConstSet.INTEGER;
}
} else {
value = new String(crtNum, 0, nLength);
intValue = Integer.parseInt(value);
return ConstSet.INTEGER;
}
}
public static void setThread(Thread t) {
thr = t;
}
public static void init() {
lineNo = 0;
crtWord = new char[30];
crtNum = new char[30];
bufLine = new String();
crtChar = ' ';
cCount = 0;
lLength = 0;
sLength = 0;
val = new String();
bufValue1 = new String();
bufValue2 = new String();
isEpt1 = true;
isEpt2 = true;
}
public static int charVal(char chr) {
if (Character.isLetterOrDigit(chr) || chr == '+' || chr == '-'
|| chr == '*' || chr == '/' || chr == '_')
return chr - 'A' + 65;
else
return -1;
}
public static int lineNo;
private static String value;
private static char[] crtWord;
private static char[] crtNum;
private static BufferedReader in;
private static String bufLine;
static char crtChar;
public static int cCount;
private static int lLength;
private static int sLength;
public static int intValue;
public static float realValue;
private static int wLength;
private static int nLength;
private static int type;
private static int idx;
private static char ch;
private static int bufSym1;
private static int bufSym2;
private static Thread thr;
private static String val;
private static String bufValue1;
private static String bufValue2;
private static boolean isEpt1;
private static boolean isEpt2;
private static boolean isDebug = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -