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

📄 scanner.java

📁 cocorj09-一个Java语言分析器
💻 JAVA
字号:
package Taste;
import java.io.*;
import java.util.*;

class Token {
	int kind;    // token kind
	int pos;     // token position in the source text (starting at 0)
	int col;     // token column (starting at 0)
	int line;    // token line (starting at 1)
	String str;  // exact string value
	String val;  // token string value (uppercase if ignoreCase)
}

class Buffer {

// Portability - use the following for Java 1.0
//	static byte[] buf;  // Java 1.0
// Portability - use the following for Java 1.1
//	static char[] buf;  // Java 1.1

	static char[] buf;  // Java 1.1

	static int bufLen;
	static int pos;
	static final int eof = 65535;

	static void Fill(String name) {
		try {
			File f = new File(name); bufLen = (int) f.length();

// Portability - use the following for Java 1.0
//			BufferedInputStream s = new BufferedInputStream(new FileInputStream(f), bufLen);
//			buf = new byte[bufLen];  // Java 1.0
// Portability - use the following for Java 1.1
//			BufferedReader s = new BufferedReader(new FileReader(f), bufLen);
//			buf = new char[bufLen];  // Java 1.1

			BufferedReader s = new BufferedReader(new FileReader(f), bufLen);
			buf = new char[bufLen];  // Java 1.1

			int n = s.read(buf); pos = 0;
		} catch (IOException e) {
			System.out.println("--- cannot open file " + name);
			System.exit(0);
		}
	}

	static void Set(int position) {
		if (position < 0) position = 0; else if (position >= bufLen) position = bufLen;
		pos = position;
	}

	static int read() {
		if (pos < bufLen) return (int) buf[pos++]; else return eof;
	}
}

class Scanner {

	static ErrorStream err;  // error messages

	private static final char EOF = '\0';
	private static final char CR  = '\r';
	private static final char LF  = '\n';
	private static final int noSym = 29;
	private static final int[] start = {
	 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, 10,  0,  7,  4,  9,
	  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  5,  3, 11,  6, 12,  0,
	  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
	  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,
	  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
	  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,
	  0};

	private static Token t;        // current token
	private static char strCh;     // current input character (original)
	private static char ch;        // current input character (for token)
	private static char lastCh;    // last input character
	private static int pos;        // position of current character
	private static int line;       // line number of current character
	private static int lineStart;  // start position of current line
	private static BitSet ignore;  // set of characters to be ignored by the scanner
	private static int offset = 0; // 1 - MsDos, 0 - Unix/Mac

	static void Init (String file, ErrorStream e) {
		ignore = new BitSet(128);
		ignore.set(9); ignore.set(10); ignore.set(13); ignore.set(32); 
		
		err = e;
		Buffer.Fill(file);
		pos = -1; line = 1; lineStart = 0; lastCh = 0;
		NextCh();
	}

	static void Init (String file) {
		Init(file, new ErrorStream());
	}

	private static void NextCh() {
		lastCh = ch;
		strCh = (char) Buffer.read(); pos++;
		ch = strCh;
		if (ch == LF && lastCh == CR) offset = 1; // MS-Dos format
		if ((ch == CR) || (ch == LF) && (lastCh != CR)) {line++; lineStart = pos + 1;}
		if (ch > '\u007f') {
			if (ch == '\uffff') ch = EOF;
			else {
				Scanner.err.SemErr(-1, line, (pos + 1 - lineStart - offset));
				ch = ' ';
			}
		}
	}

	private static boolean Comment() {
		int level, line0, lineStart0; char startCh;
		level = 1; line0 = line; lineStart0 = lineStart;
		if (ch == '(') {
			NextCh();
			if (ch == '*') {
				NextCh();
				for(;;) {
					if (ch == '*') {
						NextCh();
						if (ch == ')') {
							level--;
							if (level == 0) {NextCh(); return true;}
							NextCh();
						}
					} else if (ch == '(') {
						NextCh();
						if (ch == '*') {
							level++; NextCh();
						}
					} else if (ch == EOF) return false;
					else NextCh();
				}
			} else {
				if (ch == CR || ch == LF) {line--; lineStart = lineStart0;}
				pos = pos - 2; Buffer.Set(pos+1); NextCh();
			}
		}

		return false;
	}

	private static void CheckLiteral(StringBuffer buf) {
		t.val = buf.toString();
		switch (t.val.charAt(0)) {
			case 'B': {
				if (t.val.equals("BEGIN")) t.kind = 9;
				else if (t.val.equals("BOOLEAN")) t.kind = 12;
				break;}
			case 'D': {
				if (t.val.equals("DO")) t.kind = 18;
				break;}
			case 'E': {
				if (t.val.equals("ELSE")) t.kind = 16;
				else if (t.val.equals("END")) t.kind = 10;
				break;}
			case 'F': {
				if (t.val.equals("FALSE")) t.kind = 22;
				break;}
			case 'I': {
				if (t.val.equals("IF")) t.kind = 14;
				else if (t.val.equals("INTEGER")) t.kind = 11;
				break;}
			case 'P': {
				if (t.val.equals("PROCEDURE")) t.kind = 8;
				else if (t.val.equals("PROGRAM")) t.kind = 3;
				break;}
			case 'R': {
				if (t.val.equals("READ")) t.kind = 19;
				break;}
			case 'T': {
				if (t.val.equals("THEN")) t.kind = 15;
				else if (t.val.equals("TRUE")) t.kind = 21;
				break;}
			case 'V': {
				if (t.val.equals("VAR")) t.kind = 6;
				break;}
			case 'W': {
				if (t.val.equals("WHILE")) t.kind = 17;
				else if (t.val.equals("WRITE")) t.kind = 20;
				break;}
		}
	}

	static Token Scan() {
		int state, apx;
		StringBuffer buf;
		while (ignore.get((int)ch)) NextCh();
		if ((ch == '(') && Comment()) return Scan();
		t = new Token();
		t.pos = pos; t.col = pos - lineStart + 1 - offset; t.line = line;
		buf = new StringBuffer();
		state = start[ch];
		apx = 0;
		loop: for (;;) {
			buf.append(strCh);
			NextCh();
			switch (state) {
				case 0:
					{t.kind = noSym; break loop;} // NextCh already done
				case 1:
					if (ch >= '0' && ch <= '9'
					  || ch >= 'A' && ch <= 'Z'
					  || ch >= 'a' && ch <= 'z') {break;}
					else {t.kind = 1; CheckLiteral(buf); break loop;}
				case 2:
					if (ch >= '0' && ch <= '9') {break;}
					else {t.kind = 2; break loop;}
				case 3:
					{t.kind = 4; break loop;}
				case 4:
					{t.kind = 5; break loop;}
				case 5:
					{t.kind = 7; break loop;}
				case 6:
					{t.kind = 13; break loop;}
				case 7:
					{t.kind = 23; break loop;}
				case 8:
					{t.kind = 24; break loop;}
				case 9:
					{t.kind = 25; break loop;}
				case 10:
					{t.kind = 26; break loop;}
				case 11:
					{t.kind = 27; break loop;}
				case 12:
					{t.kind = 28; break loop;}
				case 13:
					{t.kind = 0; break loop;}
			}
		}
		t.str = buf.toString();
		t.val = t.str;
		return t;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -