📄 lexana.java
字号:
/**
* this class is used for word ananalyze.
* @author:贺静
* @version:1.2
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
public class LexAna {
private int state;
private BufferedReader input;
private String token = "";
private int lineNo = 1;
private ReservedWord[] reserve = new ReservedWord[] {
new ReservedWord("class", Type.CLASS),
new ReservedWord("if", Type.IF),
new ReservedWord("else", Type.ELSE),
new ReservedWord("while", Type.WHILE),
new ReservedWord("int", Type.INT),
new ReservedWord("real", Type.REAL),
new ReservedWord("read", Type.READ),
new ReservedWord("write", Type.WRITE) };
private char[] opChar = new char[] { '+', '-', '*', '/', '<', '>', '=',
'{', '}', '(', ')', '[', ']', ';', ',' };
private boolean isOper(char a) {
for (int i = 0; i < opChar.length; i++) {
if (opChar[i] == a)
return true;
}
return false;
}
private int getIdenType(String token) {
for (int i = 0; i < reserve.length; i++) {
if (reserve[i].getName().equals(token)) {
return reserve[i].getType();
}
}
return Type.ID;
}
/*
* i is the ASCII of the char if i is between 97 and 122, i is a-z; if i is
* between 65 and 90, i is A-Z;
*/
private boolean isLetter(char a) {
int i = (int) a;
if ((97 <= i & i <= 122) || (65 <= i & i <= 90)) {
return true;
}
return false;
}
/*
* the ASCII of digits 0-9 is between 48 and 57
*/
private boolean isDigit(char a) {
int i = (int) a;
if (48 <= i & i <= 57) {
return true;
}
return false;
}
// switch the state
private void reSet() throws IOException {
switch (state) {
case 0:
state = 8;
break;
case 8:
state = 11;
break;
case 11:
state = 14;
break;
default:
}
}
// refresh the input,"$" 终止符
public void setBufferInput(String s) {
// s = "+ >";
input = new BufferedReader(new StringReader(s + "$"));
}
/*
* the main method of word annalyze 0:operator; 8:key word or identify;
* 11:number
*/
public Token getToken() throws IOException {
int c = input.read();
char charToken = (char) c;
state = 0;
int lineNO = 0;
String token2 = " ";
while (c != -1) {
switch (state) {
case 0:
if (charToken == ' ')
;
else if (charToken == '\n')
lineNo++;
else if (charToken == '+' || charToken == '>'
|| charToken == '[' || charToken == ']'
|| charToken == '(' || charToken == ')'
|| charToken == '{' || charToken == '}'
|| charToken == ';' || charToken == ',') {
token = String.valueOf(charToken);
switch (charToken) {
case '+':
return new Token(token, Type.ADD, lineNo);
case '>':
return new Token(token, Type.BIGGER, lineNo);
case '{':
return new Token(token, Type.LEFTBig, lineNo);
case '}':
return new Token(token, Type.RIGHTBig, lineNo);
case '[':
return new Token(token, Type.LEFTMid, lineNo);
case ']':
return new Token(token, Type.RIGHTMid, lineNo);
case '(':
return new Token(token, Type.LEFTSmall, lineNo);
case ')':
return new Token(token, Type.RIGHTSmall, lineNo);
case ';':
return new Token(token, Type.SEMI, lineNo);
case ',':
return new Token(token, Type.COMMA, lineNo);
}
} else if (charToken == '<') {
state = 1;
input.mark(2);
} else if (charToken == '=') {
state = 2;
input.mark(2);
} else if (charToken == '-') {
state = 3;
input.mark(2);
} else if (charToken == '/') {
state = 4;
input.mark(2);
} else if (charToken == '*') {
state = 7;
input.mark(2);
} else {
reSet();
break;
}
c = input.read();
charToken = (char) c;
break;
case 1:
if (charToken == '>') {
token = "<>";
return new Token(token, Type.NOTEQUAL, lineNo);
} else {
input.reset();
token = "<";
return new Token(token, Type.LESS, lineNo);
}
case 2:
if (charToken == '=') {
token = "==";
return new Token(token, Type.EQUAL, lineNo);
} else {
input.reset();
token = "=";
return new Token(token, Type.ASSIGN, lineNo);
}
case 3:
if (token.equals("+") || token.equals("-") || token.equals("*")
|| token.equals("/") || token.equals("<")
|| token.equals(">") || token.equals("<>")
|| token.equals("=") || token.equals("==")
|| token.equals("(") || token.equals(",")
|| token.equals("[")) {
if (isDigit(charToken)) {
token = "<->";
state = 11;
break;
} else {
token = "-";
input.reset();
return new Token(token, Type.MINUSUNI, lineNo);
}
} else {
token = "-";
input.reset();
return new Token(token, Type.MINUSBI, lineNo);
}
case 4:
if (charToken == '*') {
state = 5;
c = input.read();
charToken = (char) c;
} else {
token = "/";
input.reset();
return new Token(token, Type.DIVID, lineNo);
}
break;
case 5:
if (charToken == '*')
state = 6;
else {
if (charToken == '\n')
lineNO++;
state = 5;
}
c = input.read();
charToken = (char) c;
break;
case 6:
if (charToken == '/') {
lineNo = lineNo + lineNO;
lineNO = 0;
state = 0;
} else if (charToken == '*')
state = 6;
else {
if (charToken == '\n')
lineNO++;
state = 5;
}
c = input.read();
charToken = (char) c;
break;
case 7:
if (charToken == '/') {
return new Token("*/", -30, lineNo);
} else {
token = "*";
input.reset();
return new Token(token, Type.MULTI, lineNo);
}
case 8:
if (isLetter(charToken)) {
state = 9;
token2 = String.valueOf(charToken);
input.mark(2);
c = input.read();
charToken = (char) c;
} else
reSet();
break;
case 9:
if (isLetter(charToken) || isDigit(charToken)
|| charToken == '_') {
token2 += String.valueOf(charToken);
state = 9;
input.mark(2);
c = input.read();
charToken = (char) c;
} else
state = 10;
break;
case 10:
token = token2;
if (token2.endsWith("_")) {
return new Token(token, -31, lineNo);
} else {
input.reset();
return new Token(token, getIdenType(token), lineNo);
}
case 11:
if (isDigit(charToken)) {
state = 12;
token2 = String.valueOf(charToken);
input.mark(2);
c = input.read();
charToken = (char) c;
} else
reSet();
break;
case 12:
if (isDigit(charToken) || charToken == '.') {
token2 += String.valueOf(charToken);
state = 12;
input.mark(1);
c = input.read();
charToken = (char) c;
} else
state = 13;
break;
case 13:
if (isLetter(charToken)) {
token = token2 + charToken;
return new Token(token, -32, lineNo);
} else {
try {
if (token2.contains(".")) {
if (token2.endsWith(".")) {
token = token2;
return new Token(token, -33, lineNo);
} else {
double num = Double.parseDouble(token2);
token2 = "" + num;
}
} else {
int num = Integer.parseInt(token2);
token2 = "" + num;
}
if (token.equals("<->")) {
token = "-" + token2;
} else
token = token2;
input.reset();
return new Token(token, Type.NUM, lineNo);
} catch (NumberFormatException nfe) {
token = token2;
return new Token(token, -35, lineNo);
}
}
case 14:
if (isOper(charToken)) {
state = 0;
} else if (isLetter(charToken)) {
state = 8;
} else if (isDigit(charToken))
state = 11;
else
state = 15;
break;
case 15:// 16:error
token = String.valueOf(charToken);
if (charToken == '$' & input.readLine() == null) {
return new Token(token, Type.END, lineNo);
} else {
return new Token(token, -34, lineNo);
}
}
}
if (state == 5 || state == 6) {
return new Token("/*", -30, lineNo);
}
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -