📄 scanner.java
字号:
//词法分析
import globle.Error;
import globle.LexType;
import globle.State;
import globle.Token;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class Scanner implements ActionListener {
// 保护的全局静态变量,是给集合,用来保存tokende ,为以后语法分析提供输入
protected static List<Token> list =null;
// 保存源代码
private String sourceCode;
// 用于记录字符在变量sourceCode中的位置
private int item = 0;
// SNL语言保留字表,用映射存放,以便快速查找且确定类别
private Map<String, LexType> reserveTable = new HashMap<String, LexType>();
// SNL语言特殊符号表,
private Map<Character, LexType> signTable = new HashMap<Character, LexType>();
// 字母、数字用红黑树存放,以便快速查找
private Set<Character> letter = new TreeSet<Character>();
private Set<Character> digit = new TreeSet<Character>();
protected static boolean isError=false;
// 保存错误信息
protected static List <Error> error = new ArrayList<Error>();
protected static int number=1; //记录行号
public Scanner() {
// 初始保留字表
reserveTable.put("program", LexType.PROGRAM);
reserveTable.put("var", LexType.VAR);
reserveTable.put("integer", LexType.INTEGER);
reserveTable.put("char", LexType.CHAR);
reserveTable.put("array", LexType.ARRAY);
reserveTable.put("type", LexType.TYPE);
reserveTable.put("procedure", LexType.PROCEDURE);
reserveTable.put("of", LexType.OF);
reserveTable.put("record", LexType.RECORD);
reserveTable.put("begin", LexType.BEGIN);
reserveTable.put("end", LexType.END);
reserveTable.put("if", LexType.IF);
reserveTable.put("then", LexType.THEN);
reserveTable.put("else", LexType.ELSE);
reserveTable.put("fi", LexType.FI);
reserveTable.put("while", LexType.WHILE);
reserveTable.put("do", LexType.DO);
reserveTable.put("endwh", LexType.ENDWH);
reserveTable.put("read", LexType.READ);
reserveTable.put("write", LexType.WRITE);
reserveTable.put("return", LexType.RETURN);
// 初始特殊符号表
// ASSIGN, EQ, LT, PLUS, MINUS, TIMES, OVER, LPAREN, RPAREN, DOT,
// COLON, SEMI, COMMA, LMIDPAREN, RMIDPAREN, UNDERANGE,
signTable.put('+', LexType.PLUS);
signTable.put('-', LexType.MINUS);
signTable.put('*', LexType.TIMES);
signTable.put('/', LexType.OVER);
signTable.put('<', LexType.LT);
signTable.put('.', LexType.DOT);
signTable.put(',', LexType.COLON);
signTable.put(';', LexType.SEMI);
signTable.put('(', LexType.LPAREN);
signTable.put(')', LexType.RPAREN);
signTable.put(':', LexType.COMMA);
signTable.put('[',LexType.LMIDPAREN);
signTable.put(']',LexType.RMIDPAREN);
signTable.put('=',LexType.EQ);
// 初始字母红黑树
letter.add('a');
letter.add('b');
letter.add('c');
letter.add('d');
letter.add('e');
letter.add('f');
letter.add('g');
letter.add('h');
letter.add('i');
letter.add('j');
letter.add('k');
letter.add('l');
letter.add('m');
letter.add('n');
letter.add('o');
letter.add('p');
letter.add('q');
letter.add('r');
letter.add('s');
letter.add('t');
letter.add('u');
letter.add('v');
letter.add('w');
letter.add('x');
letter.add('y');
letter.add('z');
letter.add('A');
letter.add('B');
letter.add('C');
letter.add('D');
letter.add('E');
letter.add('F');
letter.add('G');
letter.add('H');
letter.add('I');
letter.add('J');
letter.add('K');
letter.add('L');
letter.add('M');
letter.add('N');
letter.add('O');
letter.add('P');
letter.add('Q');
letter.add('R');
letter.add('S');
letter.add('T');
letter.add('U');
letter.add('V');
letter.add('W');
letter.add('X');
letter.add('Y');
letter.add('Z');
// 数字
digit.add('0');
digit.add('1');
digit.add('2');
digit.add('3');
digit.add('4');
digit.add('5');
digit.add('6');
digit.add('7');
digit.add('8');
digit.add('9');
}
// 当从界面中点击词法分析时,开始执行此函数,以进行词法分析
public void actionPerformed(ActionEvent e) {
// 从界面文本框中得到源代码
sourceCode = Translate.sourceCode.toString();
// 得到token集合的迭代
list=getTokenList();
Iterator<Token> iterator = list.iterator();
display(iterator);
// 词法分析结束,关闭词法分析选项,打开语义分析选项
Translate.scanner.setEnabled(false);
Translate.parseL.setEnabled(true);
Translate.parse[0].setEnabled(true);
}
// 得到保存token的集合
private List getTokenList() {
LinkedList<Token> linkList = new LinkedList<Token>();
StringBuffer str = new StringBuffer();
// 保存单词类别
LexType lex = LexType.PROGRAM;
// 单词所在行
int line = 0;
State state = State.START;
char ch = '0';
boolean save = false; // 判断是否是是单词然后好保存在Token中
Token token = new Token();
while (item < sourceCode.length()) {
ch = getNextChar();
state = State.START;
if (letter.contains(ch) || digit.contains(ch)
|| signTable.containsKey(ch)) {
save = true;
token = new Token();
// 保存单词语义信息
str = new StringBuffer();
}
// 设置单词所在行
// token.setLineShow((line=getLineShow()));
while (state != State.DONE) {
line = getLineShow();
switch (state) {
case START:
switch (ch) {
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':
state = State.INID;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
state = State.INNUM;
break;
case '+':
case '-':
case '*':
case '/':
case '<':
case '=':
case '(':
case ')':
case '[':
case ']':
case ';':
str.append(ch);
lex = signTable.get(ch);
state = State.DONE;
break;
case ' ':
case '\n':
case '\t':
/*
* if(item<sourceCode.length()) { ch=getNextChar();
* while(ch ==' '||ch == '\n'|| ch == '\t') { if(item<sourceCode.length())
* ch=getNextChar(); else { state=State.DONE; break; } }
* ch=this.ungeNextChar(); state=State.START; } else
*/
state = State.DONE;
break;
case ':':
str.append(ch);
if (item < sourceCode.length()) {
ch = getNextChar();
if (ch == '=')
state = State.INASSIGN;
else {
// 错误处理,先存储,继续往后分析
isError=true;
lex=LexType.ERROR;
error.add(new Error(line,"该语言中没定义此符号,可能后面应该为="));
lex=LexType.COLON;
state = State.DONE;
ungeNextChar();
}
} else {
state = State.DONE;
lex=LexType.UNDERANGE;
// 错误处理,先存储,继续往后分析
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, ":不是正确的程序结尾"));
}
break;
case '{':
state = State.INCOMMENT;
break;
case '.':
str.append(ch);
if (item < sourceCode.length()) {
ch = getNextChar();
if (ch == '.')
state = State.INRANGE;
else {
state = State.DONE;
lex = LexType.DOT;
ungeNextChar();
// error.put(new Integer(line+1), ".在此处是不是多余的,他应该是程序的结束标志");
}
} else {
state = State.DONE;
lex = LexType.DOT;
}
break;
case ',':
str.append(ch);
lex=LexType.COMMA;
state = State.DONE;
break;
case '\'':
state=state.INCHAR;
break;
default:
state = State.DONE;
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, "此" + ch + "不是该语言的定义"));
break;
}
break;
case INNUM:
str.append(ch);
if (item < sourceCode.length()) {
ch = getNextChar();
if (digit.contains(new Character(ch)))
state = State.INNUM;
else {
ungeNextChar();
state = State.DONE;
lex = LexType.INTC; // 无符号整数
}
} else {
lex = LexType.INTC; // 无符号整数
state = State.DONE;
}
break;
case INID:
str.append(ch);
if (item < sourceCode.length()) {
ch = getNextChar();
if (letter.contains(new Character(ch))
|| digit.contains(new Character(ch)))
state = State.INID;
else {
ungeNextChar();
if (reserveTable.containsKey(str.toString()))
lex = reserveTable.get(str.toString());
else
lex = LexType.ID;
state = State.DONE;
}
} else {
if (reserveTable.containsKey(str.toString()))
lex = reserveTable.get(str.toString());
else
lex = LexType.ID;
state = State.DONE;
}
break;
case INCOMMENT:
while (ch != '}') {
if (item < sourceCode.length())
{
ch = getNextChar();
if(ch=='\n')
number++;
}
else
break;
}
state = State.DONE;
break;
case INASSIGN:
str.append(ch);
lex = LexType.ASSIGN;
state = State.DONE;
break;
case INRANGE:
str.append(ch);
lex = LexType.UNDERANGE;
state = State.DONE;
break;
case INCHAR:
if (item < sourceCode.length()) {
ch = getNextChar();
if (digit.contains(ch) || letter.contains(ch)) {
str.append(ch);
state = State.DONE;
if (item < sourceCode.length())
{
if(getNextChar()!='\'')
{
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, "不是正确字符结尾" ));
}
ungeNextChar();
}
else {
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, "不是正确的程序结尾"));
state = State.DONE;
}
} else {
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, "不是字符"));// 继续往下分下
getNextChar();
state = State.DONE;
}
} else {
isError=true;
lex=LexType.ERROR;
error.add(new Error(line, "不是正确的程序结尾"));
state = State.DONE;
}
break;
}
}
if (save) {
token.setLex(lex);
token.setLineShow(line );
token.setSem(str.toString());
linkList.add(token);
save = false;
}
}
return linkList;
}
// 得到下一个字符
private char getNextChar() {
return sourceCode.charAt(item++);
}
// 回退一个字符
private char ungeNextChar() {
return sourceCode.charAt(--item);
}
private int getLineShow()
{
if(sourceCode.charAt(item-1)== '\n')
number++;
return number;
}
// 将词法分析的结果输出到界面显示
private void display(Iterator iterator) {
Translate.scanPane.setBorder(new javax.swing.border.TitledBorder(
"词法分析结果"));
while (iterator.hasNext()) {
Translate.scanArea
.append(((Token) iterator.next()).toString() + '\n');
}
if(isError)
{
Iterator errorIterator=error.iterator();
Translate.scanArea.append("\t词法分析有错,错误如下:\n");
while(errorIterator.hasNext())
{
Error str=(Error)errorIterator.next();
Translate.scanArea.append(str+"\n");
}
}
else
Translate.scanArea.append("\t词法分析无错\n");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -