⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanner.java

📁 编译原理实验
💻 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 + -