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

📄 lexer.java

📁 一个C语言子集的编译器
💻 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 + -