java 词法分析器

(一)程序中二元组结构:

1关键字:二元组结构(程序中位置标号,在关键字数组中的位置)(代号1)

二元组结构名称:int[,] keyDbl

 

其中关键字数组为:

String[] keyword={"if","else","int","return","void","while","float"}

 举例示范:如if(5,1)

2 标示符:二元组结构(程序中位置标号,标示符名称) (代号2)

二元组结构名称:String[,] signDbl

3 常量:三元组结构(程序中位置标号,该常量的类型,该常量值的二进制形式)   (代号3)

  二元组结构名称: String[][][] conDbl

说明:

  类型设计:zint 正整型 fint负整型 zflo正浮点型 fflo 负浮点型

  二进制形式规格为8

4 运算符:二元组结构(程序中位置标号,该运算符在表中位置) (代号4)

  二元组结构名称:int[,] calDbl

  运算符数组为:

  String[] calcum={"+","-","*","/","<","<=", ">", ">=", "==", "!=", "="}

5 定界符:二元组结构(程序中位置标号,该定界符在表中的位置)(代号5)

  二元组结构名称:int[,] bunDbl

  定界符数组为:

String[] bunch={ ";", ",", "(", ")", "[", "]", "{", "}", "/*", "*/"}

(二)相关函数介绍:

    1.文件读取函数:publicint readFile()

    2.字符分类函数: publicvoid departPro()

    3.单词归类函数:publicvoid anaWord()

    4.十进制转二进制函数:public String ObtoBe(String word,String kind)

       说明:word为十进制字符串形式 kind为十进制数表示的类型

              返回类型:返回十进制转成二进制后的字符串

    5.各个类型的输出:

       关键字输出函数:publicvoid keywordsOut()

       常数输出函数:publicvoid coustOut()

       标示符输出函数:publicvoid signOut()

       运算符输出函数:publicvoid calOut()

       定界符输出函数:publicvoid bunOut()

    6.查找函数:

       查找某定界符在定界符表中的位置函数:publicint searchBun(String str)

       查找某运算符在运算符表中的位置函数:publicint searchCal(String str)

       查找某关键字在关键字表中的位置函数:publicint searchKey(String str)

 

源代码:

package word;

 

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;

import java.util.Scanner;

 

public class WordAnly {

    private String filename=null;

    char[] program=null;

    public WordAnly(String fileName){

       this.filename=fileName;

    }

   

   

    public String getFilename() {

       return filename;

    }

 

 

    public void setFilename(String filename) {

       this.filename = filename;

    }

 

 

    //读取文件内容

    public int readFile(){

       File file=new File(filename);

      

       if(!file.exists())

       {   System.out.println("该文件不存在");

           return 0;

       }

      

       String message;

       int k=(int) file.length();

      

       if(k==0){

           System.out.println("该文件为空");

           return 0;

       }

      

      

       String tempString = null;

       BufferedReader reader=null;

       StringBuffer contents=new StringBuffer();

      

       try

       {

            program=new char[k];

             System.out.println("以行为单位读取文件内容,一次读一整行:");

             reader = new BufferedReader(new FileReader(file));

             int m=0,n=0;

             while ((tempString = reader.readLine()) != null){

             // 显示行号

                contents.insert(n, tempString);

                n=n+tempString.length();

             }

             tempString=contents.substring(0);

            

             System.out.println(tempString);

             program=tempString.toCharArray();

                reader.close();

               

            } catch (IOException e) {

                e.printStackTrace();

            } finally {

                if (reader != null) {

                    try {

                        reader.close();

                    } catch (IOException e1) {

                    }

                }

            }

       return 1;

    }

   

    //已知数组定义部分

       //关键字

       String[] keyword={"if","else","int","return","void","while","float"};

       //运算符

       String[] calcum={"+","-","*","/","<","<=", ">", ">=", "==", "!=", "="};

       //定界符

       String[] bunch={ ";", ",", "(", ")", "[", "]", "{", "}", "/*", "*/"};

      

       //各个类型的二、三元组名称

       int[][]keyDbl=new int[50][2]; int keyCount=0;

       String[][] signDbl=new String[50][2]; int signCount=0;

       String[][] conDbl=new String[50][3]; int conCount=0;

       int[][]  calDbl=new int[50][2]; int calCount=0;

       int[][] bunDbl=new int[50][2]; int bunCount=0;

       //对应总程序中的单词代号

       int[] wordsFlag=new int[250];

       //对应每个单词

       String[] words=new String[250];

      

       int[] flags;

    //单个字符分析

    public void departPro(){

       int k=program.length;

       //标志位的初始化

       flags=new int[k];

       for(int i=0;i<k;i++){

           flags[i]=0;

       }

          

           for(int i=0;i<program.length;i++){

              //字母判断

              if(program[i]>='A'&&program[i]<='Z'||program[i]>='a'&&program[i]<='z'){

                  flags[i]=1;

                  continue;

              }

              //数字判断

              if(program[i]-48>=0&&program[i]-48<=9){

                  flags[i]=2;

                  continue;

              }

              //空格判断

              if(program[i]==' '){

                  flags[i]=5;

                  continue;

              }

              int j=0;

              while(j<calcum.length)

              {

                  if(program[i]==calcum[j].charAt(0)){

                     flags[i]=3;

                     break;

                  }

                  j++;

              }

             

              if(flags[i]!=3){

                  j=0;

                  while(j<bunch.length){

                     if(program[i]==bunch[j].charAt(0)){

                         flags[i]=4;

                         break;

                     }

                     j++;

                  }

                  if(flags[i]!=4){

                     System.out.println("错误提示: 程序中"+i+"处输入的符号错误");

                  }

              }

             

          

           }

          

           for(int i=0;i<program.length;i++){

              System.out.println(program[i]+"---->"+flags[i]);

           }

       }

   

    public void anaWord(){

       int wordsCount=0;

       int i=0;

       while(i<program.length){

          

           //关键字和标示符确定

           if(flags[i]==1){

              words[wordsCount]="";

              words[wordsCount]=words[wordsCount]+program[i];

              i++;

              while(flags[i]!=3&&flags[i]!=4&&flags[i]!=5){

                  if(flags[i]==2){

                     wordsFlag[wordsCount]=2;

                  }

                  words[wordsCount]=words[wordsCount]+program[i];

                  i++;

              }

             

              int rePosition=searchKey(words[wordsCount]);

              if(wordsFlag[wordsCount]!=2&&rePosition!=-1){

                  //表示该单词为关键字

                  keyDbl[keyCount][0]=wordsCount;

                  keyDbl[keyCount][1]=rePosition;

                  keyCount++;

                  wordsFlag[wordsCount]=1;

              }else{

                  //将标示符添加到对应的二元组中

                  signDbl[signCount][0]=String.valueOf(wordsCount);

                  signDbl[signCount][1]=words[wordsCount];

                  signCount++;

                  wordsFlag[wordsCount]=2;

              }

              wordsCount++;

              continue;

           }

          

           //该处为空格

           if(flags[i]==5){

              i++;

              continue;

           }

          

           //该处为运算符类型或带符号的常数

           if(flags[i]==3){

              words[wordsCount]="";

              words[wordsCount]=words[wordsCount]+program[i];

              i++;

              //若加号后为数字则将其综合

              if(words[wordsCount].equals("+")&&flags[i]==2){

                 

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  if(program[i]=='.'){

                     //说明该项为正浮点类型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                     conDbl[conCount][1]="zflo";

                     i++;

                  }

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  wordsFlag[wordsCount]=3;  //常数型标志

                  if(conDbl[conCount][1]==null){

                     //说明该项为正整型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                     conDbl[conCount][1]="zint";

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"zint");

                     conCount++;

                  }else{

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"zflo");

                     conCount++;

                  }

                  wordsCount++;

                  continue;

              }

             

              //若为“/”且其后为"*"或“*”后为“/”则为定界符

              if(words[wordsCount].equals("/")){

                  if(program[i]=='*'||program[i]=='/'){

                     words[wordsCount]=words[wordsCount]+program[i];

                     bunDbl[bunCount][0]=wordsCount;

                     bunDbl[bunCount][1]=searchBun(words[wordsCount]);

                     bunCount++;

                     wordsFlag[wordsCount++]=5;

                     i++;

                     continue;

                  }

              }

              if(words[wordsCount].equals("*")){

                  if(program[i]=='/'){

                     words[wordsCount]=words[wordsCount]+program[i];

                     bunDbl[bunCount][0]=wordsCount;

                     bunDbl[bunCount][1]=searchBun(words[wordsCount]);

                     bunCount++;

                     wordsFlag[wordsCount++]=5;

                     i++;

                     continue;

                  }

              }

             

              //若减号后为数字则将其综合

              if(words[wordsCount].equals("-")&&flags[i]==2){

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  if(program[i]=='.'){

                     //说明该项为负浮点类型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                      conDbl[conCount][1]="fflo";

                     i++;

                  }

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  wordsFlag[wordsCount]=3;  //常数型标志

                  if(conDbl[conCount][1]==null){

                     //说明该项为负整型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                     conDbl[conCount][1]="fint";

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"fint");

                     conCount++;

                  }else{

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"fflo");

                     conCount++;

                  }

                  wordsCount++;

                  continue;

              }

             

              //若之后为运算符类型

              if(program[i]=='='){

                  words[wordsCount]=words[wordsCount]+program[i];

              }

              calDbl[calCount][0]=wordsCount;

              calDbl[calCount][1]=searchCal(words[wordsCount]);

              calCount++;

              wordsFlag[wordsCount++]=4;

              continue;

           }

          

          

          

           //常量的判断

           if(flags[i]==2){

              words[wordsCount]="";

              words[wordsCount]=words[wordsCount]+program[i];

              i++;

              if(flags[i]==2){

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  if(program[i]=='.'){

                     //说明该项为正浮点类型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                     conDbl[conCount][1]="zflo";

                     i++;

                  }

                  while(flags[i]==2){

                     words[wordsCount]=words[wordsCount]+program[i];

                     i++;

                  }

                  wordsFlag[wordsCount]=3;  //常数型标志

                  if(conDbl[conCount][1]==null){

                     //说明该项为正整型

                     conDbl[conCount][0]=String.valueOf(wordsCount);

                     conDbl[conCount][1]="zint";

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"zint");

                     conCount++;

                  }else{

                     conDbl[conCount][2]=ObtoBe(words[wordsCount],"zflo");

                     conCount++;

                  }

                  wordsCount++;

                  continue;

              }

              if(flags[i]==1){

                  System.out.println("错误提示:"+(i-1)+"处标示符命名错误");

                  continue;

              }

              conDbl[conCount][0]=String.valueOf(wordsCount);

              conDbl[conCount][1]="zint";

              conDbl[conCount][2]=ObtoBe(words[wordsCount],"zint");

              conCount++;

              wordsFlag[wordsCount]=3;

              wordsCount++;

           }

          

           //定界符类型

           if(flags[i]==4){

              words[wordsCount]="";

              words[wordsCount]=words[wordsCount]+program[i];

              bunDbl[bunCount][0]=wordsCount;

              bunDbl[bunCount][1]=searchBun(words[wordsCount]);

              bunCount++;

              wordsFlag[wordsCount++]=5;

              i++;

              continue;

           }

       }

      

       int m=0;

       System.out.println("分词输出:");

       while(words[m]!=null)

       {

           System.out.println(words[m]+"----->"+wordsFlag[m]);

           m++;

       }

    }

   

   

    //十进制转二进制

    public String ObtoBe(String word,String kind){

   

       String transfer="";

       int[] stack=new int[8];

       int top=0;

       int ik;

       float fk;

       if(kind.equals("zint")){

           ik=Integer.parseInt(word);

           //转成二进制

           if(ik==0||ik==1)

              stack[top]=ik;

          

           while(ik/2!=0){

              stack[top++]=ik%2;

              ik=ik/2;

              if(ik==1){

                  stack[top]=1;

              }

           }

           while(top!=-1){

              transfer=transfer+String.valueOf(stack[top]);

              top--;

           }

           for(int i=(8-transfer.length());i>0;i--){

              transfer="0"+transfer;

           }

          

       }else if(kind.equals("fint"))

       {

           //为负整数结果

           ik=Integer.parseInt(word.substring(1));

           //转成二进制

           if(ik==0||ik==1)

              stack[top]=ik;

          

           while(ik/2!=0){

              stack[top++]=ik%2;

              ik=ik/2;

              if(ik==1){

                  stack[top]=1;

              }

           }

           int k=0;

           while(stack[k]==0){

              transfer=String.valueOf(stack[k++])+transfer;

           }

           transfer=stack[k++]+transfer;

           if(k==7){

              System.out.println("输入的数字越界");

              return null;

           }

          

           for(int i=k;i<=top;i++){

              if(stack[i]==0){

                  transfer="1"+transfer;

              }

              if(stack[i]==1){

                  transfer="0"+transfer;

              }

           }

           for(int i=(8-transfer.length());i>0;i--){

              transfer="1"+transfer;

           }

       }else if(kind.equals("zflo"))

       {

       }else

       {

       }

      

       return transfer;

    }

    //返回关键字表中的位置加1

    public int searchKey(String str){

 

       for(int i=0;i<keyword.length;i++)

       {

           if(str.equals(keyword[i])){

              return i;

           }

       }

       return -1;

    }

 

   

   

    //返回运算符的位置

    public int searchCal(String str){

       for(int i=0;i<calcum.length;i++){

           if(str.equals(calcum[i])){

              return i;

           }

       }

       return -1;

    }

   

    //返回定界符的位置

    public int searchBun(String str){

       for(int i=0;i<bunch.length;i++){

           if(str.equals(bunch[i])){

              return i;

           }

       }

       return -1;

    }

   

 

    //关键字的输出1

    public void keywordsOut()

    {

       System.out.println("**************************************");

       System.out.println("输出关键字为:");

       System.out.println("关键字       关键字位置       对应表中位置");

       for(int s=0;s<keyCount;s++){

              System.out.println(keyword[keyDbl[s][1]]+"         "+keyDbl[s][0]+"            "+keyDbl[s][1]);

       }

    }

    //常数的输出3

    public void coustOut(){

       System.out.println("**************************************");

       System.out.println("输出常量值(转换后的二进制形式):");

       System.out.println("常数             位置               类型                     二进制形式");

       for(int s=0;s<conCount;s++){

           System.out.println(Integer.parseInt(words[Integer.parseInt(conDbl[s][0])])+"        "+Integer.parseInt(conDbl[s][0])+

                  "        "+conDbl[s][1]+"       "+conDbl[s][2]);

       }

    }

    //变量输出2

       public void signOut(){

           System.out.println("**************************************");

           System.out.println("输出程序中的变量:");

           System.out.println("变量名             变量位置              标示符表中位置");

           for(int s=0;s<signCount;s++){

                  System.out.println(words[Integer.parseInt(signDbl[s][0])]+"         "+signDbl[s][0]+"            "+s);

             

           }

       }

   

    //运算符的输出4

    public void calOut()

    {

       System.out.println("**************************************");

       System.out.println("输出程序中的运算符:");

       System.out.println("运算符             运算符位置              运算符表中位置");

       for(int s=0;s<calCount;s++){

              System.out.println(words[calDbl[s][0]]+"         "+calDbl[s][0]+"            "+calDbl[s][1]);

       }

    }

   

    //定界符的输出5

       public void bunOut()

       {

           System.out.println("**************************************");

           System.out.println("输出程序中的定界符:");

           System.out.println("定界符             定界符位置             定界符表中位置");

           for(int s=0;s<bunCount;s++){

                  System.out.println(words[bunDbl[s][0]]+"         "+bunDbl[s][0]+"            "+bunDbl[s][1]);

           }

       }

    public static void main(String[] args){

       System.out.println("情输入文件路径和文件名:");

       Scanner sc=new Scanner(System.in);

       String str=sc.next();

   

       WordAnly wra=new WordAnly(str);

       int i=wra.readFile();

       while(i==0){

           System.out.println("情输入文件路径和文件名:");

           wra.setFilename(sc.next());

           i=wra.readFile();

       }

       wra.departPro();

       wra.anaWord();

       wra.keywordsOut();

       wra.calOut();

       wra.bunOut();

       wra.signOut();

       wra.coustOut();

    }

   

}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值