📄 lex.java
字号:
//---------------------------------------------------------
// 类描述: 词法分析,分离词法单词并返回单词类型,供语法分析程序调用
// 文件名: Lex.java
//---------------------------------------------------------
package cp;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class Lex{
final int OK = 1;
final int END = -1;
final int SIZE = 2048;
final String Double_OP[] = {"!", "<", ">","="};//两个字符的操作符
final String Empty[] = {" ", "\t", "\r", "\n"};
final String OP_Words[] = {"+","-","*","=","!",">","<"};
final String Delimiter[] = {",", ";", "(", ")", "[", "]", "{", "}", "'", "\""};
String sym = null;//symbol
char ch=' ';
int line = 1; //统计行数
StringBuffer sb = new StringBuffer(SIZE);//每次读取文件SIZE Bytes
static int sbPoint = 0;//sb位置变量
InputStreamReader in = null;
// 输入初始化
Lex(String fp){
try{
in = new InputStreamReader(new FileInputStream(fp));
}catch(FileNotFoundException fe){
System.out.println("File"+fp+"not found!");
}
}
// 读取文件一个字符
int getch(){
int c = 0;
try{
c=in.read();
}catch(IOException ie){
System.out.println("Reading file error...!");
}
return c;
}
//读取文件1024B到缓冲区变量sb
int getSB(){
sb.delete(0,sb.length());
sbPoint = 0;
int c =0;
while((c=getch())==32);
sb.append((char)c);
if(c==-1)
return END;
for(int i=0; i<sb.capacity(); i++){
c=getch();
sb.append((char)c);
if(c==-1) break;
if(i>sb.capacity()-200&&( (char)c=='/'||c==32 )) break;//避免读取不完整的单词
}
return OK;
}
// 读取缓冲区一个词法单词并返回类型号
int getSYM(){
int type = 0;
if(pretreatment()==-1) return END;//预处理=读数据到sb+清除前导空格
if(ch==(char)(-1)) return END;
sym += ch;
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') type = 1;
if(ch>='0'&&ch<='9') type = 5;
//标识符+保留字+数字
if(type==1 || type==5){
while( sbPoint < sb.length()&&(ch=sb.charAt(sbPoint++))!= ' ' && ch!='\r' ) {
if( ch==(char)( -1))return type;
if (matches(ch, OP_Words) || matches(ch, Delimiter)){
sbPoint--;
break;
}
sym += ch;
}
if(sym.charAt(0)>='0'&&sym.charAt(0)<='9');
else{
if (sym.matches(Compiler.DE_WORDS)) type = 1;//定义性字符
else if (sym.matches(Compiler.VALUE_WORDS)) type = 2; //保留值ture|false
else if (sym.matches(Compiler.CON_WORD)) type = 3; //控制字符
else if (sym.matches(Compiler.ID)) type = 4;//用户标识
}
return type;
}
else if(ch=='\'' || ch=='\"') {//字符型常量
while( sbPoint < sb.length()){
ch = sb.charAt(sbPoint++);
if (ch == (char)( -1))return 6;
sym += ch;
if (ch == '\'' || ch == '\"') {
if (sbPoint < sb.length()) {
ch = sb.charAt(sbPoint);
if (ch == ' ' || ch == ';' || ch == ',' || ch == ')')
break;
}
}
}
return 6;
}
else if(matches(ch, OP_Words)||matches(ch, Delimiter) ){//运算符及界符
if( matches(ch, Double_OP) ){//处理双字运算符
if(sbPoint<sb.length()&&(sb.charAt(sbPoint))=='=') {
sym += sb.charAt(sbPoint++);
}
}
return 7;
}
else if(ch == '/' && sb.charAt(sbPoint)=='/' ){//过滤注释
while( sbPoint<sb.length() &&( (ch=sb.charAt(sbPoint++))!='\n'))
;
line++;
}
else {
while( sbPoint<sb.length()&&(ch=sb.charAt(sbPoint++))!=' ' ){
if(ch=='\n') line++;
sym += ch;
}
return 0; //错字符
}
return getSYM();
}
boolean matches(char ch, String regex[]){
boolean m = false;
String s = "";
s += ch;
for(int i = 0; i<regex.length; i++)
if(s.equals(regex[i])){//未完整
m = true;
break;
}
return m;
}
//预处理=读数据到sb+清除前导空格
int pretreatment(){
if(sbPoint>=sb.length()) {
if(getSB()==-1)
return END;
}
sym = "";
ch = ' ';
while( sbPoint < sb.length() && matches(ch=sb.charAt(sbPoint++), Empty))
if( ch=='\n' ) line++ ;
if(ch==' ' && sbPoint>=sb.length()){
pretreatment();
}
return 1;
}
//----------------------------以下全为测试所用---------------------------------------------
void test(){
int i=-1;//记录sym的类型号
System.out.println("单词\t"+"类型号\t"+"行号");
while((i=getSYM())!=-1){
System.out.print(sym);
System.out.print("" + '\t' + i + '\t'+line+'\n');
}
try{
in.close();
}catch(IOException ie){
System.out.println("Closing file exception!");
}
}
public static void main(String args[]){
//Lex lex = new Lex("E:\\Java\\work\\N46020117\\cpLab\\classes\\test.txt");//调试后删除
Lex lex = new Lex(args[0]);
lex.test();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -