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

📄 lex.java

📁 编译原理词法语法分析器课程设计,包含文档与代码.
💻 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 + -