编译原理实验 实验一 词法分析设计 Java实现

一、实验目的 
       通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。 
      二、实验内容 
       用 VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;同时进行标识符登记符号表的管理。 
       以下是实现词法分析设计的主要工作: 
    (1)从源程序文件中读入字符。 
    (2)统计行数和列数用于错误单词的定位。 
    (3)删除空格类字符,包括回车、制表符空格。 
    (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 的机内表示) 
    (5)如果发现错误则报告出错 
    (6)根据需要是否填写标识符表供以后各阶段使用。 
     单词的基本分类: 
 关键字:由程序语言定义的具有固定意义的标识符。也称为保留字例如 if、    for、while、printf ; 单词种别码为 1。 
 标识符:用以表示各种名字,如变量名、数组名、函数名; 
 常数: 任何数值常数。如 125, 1,0.5,3.1416; 
 运算符:+、-、*、/; 
 关系运算符: <、<=、= 、>、>=、<>; 
 分界符: ;、,、(、)、 [、]; 

话不多说,直接上代码:

package WordAnalyzise;
/**
* @author Zou
* @file_name WordAnalyzise.java
* @date 2019年10月28日
*/
import java.util.*;
import java.io.*;
public class WordAnalyzise {
    static String k[]={"do","end","then","if","printf","scanf","then","while","auto","break","case","char",
            "const","continue","default","double","else","enum","extern","float","goto","int","long","register",
            "return","short","signed","sizeof","static","struct","switch",
            "typedef","union","unsigned","void","volatile","inline"};//1 关键字
    static char s[]={',',';','(',')','[',']','{','}'};//2 分界符
    static char m[]={'+','-','*','/'};//3 算术运算符
    static String r []={"<","<=","=",">",">=","<>"};//4 关系运算符
    ArrayList ci= new ArrayList<>();//5 常数
    ArrayList id= new ArrayList<>();//6 标识符
    int pint;// 搜索指示器
    String strtoken="";// 存放构成单词符号的字符串
    int row;// 行数
    int line;// 列数
    char ch;// 存放最新读入源程序字符
    String instring;// 存放输入源程序
    WordAnalyzise(){// 初始化
        instring="if i=0 then n++;\na<= 3b %);";// 默认输入源程序
        row=1;// 行数置 1
        line=1;// 列数置 1
        pint=-1;// 搜索指示器置 -1
    }
    public static void main(String args[]) throws Exception{
    	WordAnalyzise one = new WordAnalyzise();
        System.out .println(" 单 词 二 元 序 列 类 型 位 置(行,列) ");
        one.handle();
        // one.readstr();
        // one.readtext();
    }
    boolean isdigit( char c){// 判断字符 c是否是数字
        if (c>=48&&c<=57) return true ;
        return false ;
    }
    boolean isletter( char c){// 判断字符 c是否是字母
        if ((c>64&&c<91)||(c>96&&c<123)) return true ;
        return false ;
    }
    boolean isline( char c){// 判断字符 c是否是下划线
        if (c=='_') return true ;
        return false ;
    }
    boolean remove(){// 用于在判断关系运算符时,判断是否是要再读一个字符
        char b=instring.charAt(pint+1);
        if (b=='='||b=='>'){// 当其后的字符是 =或>时, 要再读一个字符。否则不要再读。
            return true ;
        }
        return false ;
    }
    boolean sremove(){//用于判断算数运算符时,是否需要再读一个字符
        char b = instring.charAt(pint);
        char bn=instring.charAt(pint+1);
        String s = Character.toString(b)+Character.toString(bn);
        if ("++".equals(s)||"--".equals(s)){
            return true;
        }
        return false;
    }
    void getbc(){// 检查空白直到读入字符非空白
        while (ch==' '){
            getchar();
        }
    }
    void getchar(){// 读入下一个字符
        pint++;
        if (pint<=instring.length()-1){// 当指针没有越界时, 可读字符
            ch=instring.charAt(pint);
            if (ch=='\n'){// 当读到换行符时,行数加一,列数置一。再读下一个字符
                change_r_l();
                getchar();
            }
        }
        else ch=' ';// 当指针越界时,置 ch为空白符
    }
    void retract(){// 读入前一个字符
        pint--;
        ch=instring.charAt(pint);
    }
    void words(){// 识别字符串
        strtoken="";// 先将strtoken 置空
        while (isletter(ch)||isdigit(ch)||isline(ch)){// 当是字母,数字,下划线时继续识别字符串
            strtoken=strtoken+ch;// 将新识别的字符加到 strtoken后
            getchar();
        }
    }
    void num(){// 识别数字串
        strtoken="";// 先将strtoken 置空
        while (isdigit(ch)){// 当数字时继续识别数字串
            strtoken=strtoken+ch;// 将新识别的字符加到 strtoken后
            getchar();
        }
        if (isletter(ch)||isline(ch)){// 识别完数字串而其后是字母,下划线时出错处理
            while (isletter(ch)||isline(ch)||isdigit(ch)){// 当是字母,数字,下划线时继续识别错误数字串
                strtoken=strtoken+ch;// 将 新 识 别 的 字 符 加 到strtoken 后
                getchar();
            }
            show(0,strtoken,' ');// 输出错误数字串
            strtoken="";// 将strtoken 置空返回
        }
    }
    void show( int i,String s, char a){// 各种输出处理
        switch (i){
            case -1:System. out .println(a+" "+"Error"+" Error "+"("+row+","+line+")");
                break ;
            case 0:System. out .println(s+" "+"Error"+" Error "+"("+row+","+line+")");
                break ;
            case 1:System. out .println(s+" "+"(1,"+s+")"+" 关 键 字"+"("+row+","+line+")");
                break ;
            case 2:System. out .println(a+" "+"(2,"+a+")"+" 分 界 符"+"("+row+","+line+")");
                break ;
            case 3:System. out .println(a+" "+"(3,"+a+")"+" 算 术 运 算 符"+"("+row+","+line+")");
                break ;
            case 4:System. out .println(s+" "+"(4,"+s+")"+" 关 系 运 算 符"+"("+row+","+line+")");
                break ;
            case 5:System. out .println(s+" "+"(5,"+s+")"+" 常 数"+"("+row+","+line+")");
                break ;
            case 6:System. out .println(s+" "+"(6,"+s+")"+" 标 识 符"+"("+row+","+line+")");
                break ;
        }
        line++;// 列数加一
    }
    void change_r_l(){// 改变行列数
        row++;
        line=1;
    }
    void handle(){// 输入串处理
        pint=-1;// 将搜索指示器置 -1
        System.out .println(" 要处理的语句为 : "+instring);
        getchar();// 读入一个字符
        while (pint

 

你可能感兴趣的:(编译原理)