📄 cifaanalyse.java
字号:
package ecust.edu.cn.pl0;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class CiFaAnalyse// 词法分析类
{
String line; // string变量用于存放读取的一行源代码
int lineLength;// 存放line中的字符数
int lineNum = 0;// 存放line的号码
public char Cha; // 存放读取的字符
int index;// 存放当前读取的字符位置
int al = 10; // 定义标识符长度
int nmax = 4;// 定义整数位数
public int errorNumber = 0; // 用于保存词法分析中的错误数目
BufferedReader in;
static token word[];
public CiFaAnalyse(String filename) { //构造函数,根据传过来的文件名.建立一个输入流
// 定义保留字表word
word = new token[13];
word[0] = new token("begin", "beginsym");
word[1] = new token("call", "callsym");
word[2] = new token("const", "constsym");
word[3] = new token("do", "dosym");
word[4] = new token("end", "endsym");
word[5] = new token("if", "ifsym");
word[6] = new token("odd", "oddsym");
word[7] = new token("procedure", "procsym");
word[8] = new token("read", "readsym");
word[9] = new token("then", "thensym");
word[10] = new token("var", "varsym");
word[11] = new token("while", "whilesym");
word[12] = new token("write", "writesym");
// 根据文件名建立文件输入流
try {
FileInputStream fis = new FileInputStream(filename);
in = new BufferedReader(new InputStreamReader(fis));
line = in.readLine().trim(); // 读取一行源代码.并去除开头和结尾的空格
lineLength = line.length();
lineNum = 1;
while (lineLength == 0) { // 如果此行源代码为空,则继续读取下一行
line = in.readLine().trim();
lineLength = line.length();
lineNum++;
}
index = 0;
GetCh();
} catch (FileNotFoundException a) {
System.out.println("没有找到文件!!");
} catch (IOException b) {
System.out.println("文件读取错误");
}
}
public int getErroNumber() { //返回发生错误的个数
return errorNumber;
}
public void GetCh()// 利用方法GetCh()在原文件中取得一个符号
{
try {
if (index == lineLength)// 如果到达行尾,则重新读取一行源码
{ // 其实读取有效行可以写一个方法
line = in.readLine().trim();
lineLength = line.length();
lineNum++;
while (lineLength == 0) {
line = in.readLine().trim();
lineLength = line.length();
lineNum++;
}
index = 0;
Cha = line.charAt(index);
index++;
} else {
Cha = line.charAt(index);
index++;
}
} catch (NullPointerException e) {
System.out
.println("*****************************源程序读取完毕*******************************");
} catch (IOException c) {
}
}
public token GetToken()// 返回一个token对象 其中名字和类型已经赋值(相当于getsym())
{
int charNum1;// 记录当前单词的开始索引
int charNum2;// 记录当前单词的结束索引
String tokenName;// 当前单词
int n = 0; // 用于记录保留字数组的下标
while (Cha == ' ') {
GetCh();
}
if (Cha >= 'a' && Cha <= 'z') {
charNum1 = index - 1;
while ((Character.isLetter(Cha) || Character.isDigit(Cha))
&& index < lineLength) {
GetCh();
}
charNum2 = index;
if ((charNum2 - charNum1) > al) {
new erro(lineNum, 19);
errorNumber++;
tokenName = line.substring(charNum1, charNum1 + al);
}// 标识符长度越界
else {
if (Character.isLetter(Cha) || Character.isDigit(Cha)) {
tokenName = line.substring(charNum1);
GetCh();
} else {
tokenName = line.substring(charNum1, charNum2 - 1);
}
}
// 判断保留字过程
while (n < 13 && (!word[n].getNam().equals(tokenName))) {
n++;
}
if (n == 13) // 如果保留字表中没有找到 则为标识符
{
return new token(tokenName, "ident", lineNum);
} else {
word[n].setLineNum(lineNum);
return word[n];
}
} // 判断是否是整数
else if (Character.isDigit(Cha)) {
charNum1 = index - 1;
charNum2 = index;
while (Character.isDigit(Cha) && index < lineLength) {
charNum2 = index;
GetCh();
}
if (Character.isDigit(Cha))// 判断while为什么停止循环的,如果cha还是数字,则表明是因为此行读完而停止的,如果cha不是数字,表示因为读到非数字而停止
{
tokenName = line.substring(charNum1);
GetCh();
} else
tokenName = line.substring(charNum1, charNum2);
if ((charNum2 - charNum1) > nmax) {
new erro(lineNum, 8);
errorNumber++;
tokenName = tokenName.substring(0, nmax);
}
return new token(tokenName, "number", lineNum);
} else if (Cha == ':') {
GetCh();
if (Cha == '=') {
GetCh();
return new token(":=", "becomes", lineNum);
} else
return new token(":", "null", lineNum);
} else if (Cha == '<') {
GetCh();
if (Cha == '=') {
GetCh();
return new token("<=", "leg", lineNum);
} else
return new token("<", "lss", lineNum);
} else if (Cha == '>') {
GetCh();
if (Cha == '=') {
GetCh();
return new token(">=", "geq", lineNum);
} else
return new token(">", "gtr", lineNum);
} else {
String sym;
String sr = Character.toString(Cha);
switch (Cha) {
case '+':
sym = "plus";
break;
case '-':
sym = "minus";
break;
case '*':
sym = "times";
break;
case '/':
sym = "slash";
break;
case '(':
sym = "lparen";
break;
case ')':
sym = "rparen";
break;
case '=':
sym = "eql";
break;
case '#':
sym = "neq";
break;
case ',':
sym = "comma";
break;
case '.':
sym = "period";
break;
case ';':
sym = "semicolon";
break;
default:
sym = "nul";
}
GetCh();
return new token(sr, sym, lineNum);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -