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

📄 lexical.java~48~

📁 java编的PL/0词法编译器
💻 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 + -