📄 lexical.java~48~
字号:
//词法分析器
package compiler;
import java.io.*;
import java.util.*;
import javax.swing.*;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class Lexical {
private BufferedReader bReader;//程序源文件
private String sourceLine="";//字符串缓冲,用于存放源程序的一行
private String[] buffer;//字符串缓冲,用于存放将要分析的10个字符
private char ch;//最近读入的源程序字符
private int bufferNum=0;//buffer数组读取计数器
private int charNum=-1;//ch字符读取计数器
private String strToken="";//构成单词符号的字符串
private HashMap keyword;//关键字散列表
private HashMap operator;//运算符及界符散列表
private boolean isFinished=false;//标识词法分析是否结束
private final char END_OF_FILE=0;//编译器默认的文件结束标志
private final char CHANG_LINE=1;//编译器默认的换行符
private int LineNum=0;//编译器的行计数器
private JTextArea resultArea;//打印输出结果的面板
//构造函数
public Lexical(File f,JTextArea area) {
try{
FileReader fReader = new FileReader(f);
bReader=new BufferedReader(fReader);
}catch(IOException e){
System.err.println("读取程序源文件时出错!");
}
buffer=new String[2];
buffer[0]=buffer[1]="";
getBuffer();
keyword=Symbol.hKeyword;
operator=Symbol.hOperator;
}
//词法分析
public void analyse()
throws LexicalAnalysisFinishedException,LexicalException{
strToken="";
getChar();
getBC();
if(ch==END_OF_FILE){//读到源程序文件结尾,词法分析结束
throw(new LexicalAnalysisFinishedException());
}
if(ch==CHANG_LINE){//读到换行符,行数增加
LineNum++;
return;
}
if(isLetter()){//以字母开头,有可能是标识符或关键字
while(isLetter()|isDigit()){
concat();
getChar();
}
retract();
int code=checkKeyword();
if(code==-1){//不是关键字,是一般标识符
print("标识符");
return;
}else{//是关键字
print("关键字");
return;
}
}
else if(isDigit()){//以数字开头,有可能是整型常量
while(isDigit()){
concat();
getChar();
}
if(isLetter()){//一串数字之后紧跟字母的情况,词法错误
procError();
}
retract();
print("整型常量");
return;
}
else if(ch==':'){//以':'开头,有可能是":="
getChar();
if(ch!='='){
procError();
}
strToken=":=";
print("操作符");
return;
}
else if(ch=='>'){//以'>'开头,有可能是">="
getChar();
if(ch=='='){
strToken=">=";
print("操作符");
return;
}
strToken=">";
print("操作符");
retract();
}
else if(ch=='<'){//以'<'开头,有可能是"<="
getChar();
if(ch=='='){
strToken="<=";
print("操作符");
return;
}
strToken="<";
print("操作符");
retract();
}
//检查是否为单符号操作符
else{
int code=checkOperator();
if(code!=-1){//是单符号操作符
concat();
print("操作符");
}else{
procError();
}
}
}
//词法错误处理
private void procError()throws LexicalException{
throw(new LexicalException());
}
//打印词法分析结果
private void print(String s){
resultArea.append(strToken+"是一个"+s+"\n");
}
//过滤空字符
private void getBC(){
while(ch==' '){
getChar();
}
}
//将ch添加到strToken的结尾
private void concat(){
strToken=strToken+ch;
}
//向缓冲区退回一个字符
private void retract(){
if(charNum==0){
charNum=9;
bufferNum=(bufferNum+1)%2;
}else{
charNum--;
}
ch=buffer[bufferNum].charAt(charNum);
}
//从缓冲区读入一个字符
private void getChar(){
charNum++;
bufferNum+=(charNum/10);
bufferNum%=2;
if((charNum/10)==1){
getBuffer();
charNum%=10;
}
try{
ch=buffer[bufferNum].charAt(charNum);
}catch(Exception e){
//当出现异常时,说明已经读到程序源文件的结尾
ch=END_OF_FILE;
isFinished=true;
}
}
//将字符串从sourceLine读入缓冲区
private void getBuffer(){
if(sourceLine.length()<10){
getSourceLine();
}
if(sourceLine.length()<10){
buffer[bufferNum]=sourceLine;
}else{
buffer[bufferNum]=sourceLine.substring(0,10);
String str;
str=sourceLine.substring(10,sourceLine.length());
sourceLine=str;
}
}
//从源文件中读取若干行字符串添加到sourceLine,直到sourceLine的长度大于10或读到文件结尾
private void getSourceLine(){
try{
String str;
do{
str=bReader.readLine();
sourceLine=sourceLine+CHANG_LINE+str;
}while(sourceLine.length()<10&&str!=null);
if(str==null){
sourceLine=sourceLine.substring(0,sourceLine.length()-4);
}
}catch(IOException e){
System.err.println("读取程序源文件时出错!");
}
}
//判断ch是否为字母
private boolean isLetter(){
if(ch>='a'&&ch<='z'){
return true;
}else if(ch>='A'&&ch<='Z'){
return true;
}
return false;
}
//判断ch是否为数字
private boolean isDigit(){
if(ch>='0'&&ch<='9'){
return true;
}
return false;
}
//判断ch是否为操作符
private boolean isOperator(){
String str=(String)operator.get(""+ch);
if(str!=null){
return true;
}
return false;
}
//检查strToken是否为关键字,是则返回相应值,否则返回-1
private int checkKeyword(){
String str=(String)keyword.get(strToken);
if(str!=null){
int i=(new Integer(str)).intValue();
return i;
}
return -1;
}
//检查ch是否为(单符号)操作符,是则返回相应值,否则返回-1
private int checkOperator(){
String str=(String)operator.get(""+ch);
if(str!=null){
int i=(new Integer(str)).intValue();
return i;
}
return -1;
}
//得到编译器行计数器的值
public int getLineNum(){
return LineNum;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -