程序实现原理:
将TXT文本中的数据读出,并按照其类别的不同,将关键字、数字以及运算符识别出来。
一、词法分析实验步骤
1. 熟悉TPL语言
2. 编写TPL语言程序,至少3个,一个简单,一个复杂的(包括循环,分支,以及它们的相互嵌套),一个错误的(带非法字符的,如$ 和 整数位数>8的整数)
3.根据指导书中的第三章中的DFA 编写词法分析程序。 程序输入:上面的三个TPL程序,程序输出: 分离出的单词。注:单词需要保存,为语法分析做准备
4.将单词分类,对每类单词都进行简化,均简化成一个字符(整数除外),分类表见指导书表3-1。在此基础上编写程序,将上面分离出的单词进化简化并保存。注:所有的关系运算符均简化为同一个字符r. 所有的自定义标识符均简化为 i
二、词法分析器的功能
1.能够识别数字、字符、运算符、界符和部分特殊符号
2.能有一定的纠错能力(如数字长度超长,括号不匹配等)
代码如下:
package bianyiyuanliTS; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class test01 { public static boolean SZCW=false; //数字错误标记 public static boolean KHCW=false; //括号错误标记 public static boolean HKHCW=false; //花括号错误标记 public static boolean WSBDFH=false; //未识别的符号错误标记 public static int kuohao=0; //记录括号的数量 public static int huakuohao=0; //记录花括号的数量 public static int CWSL=0; //记录错误的数量 public static int hanghao=1; //记录读取的行号 public int ch; //读取到的字符的ascll码值 public static StringBuffer neirong = new StringBuffer(); //存放构成单词符号的字符串 //用数组存放TPL语言的保留字 public String [] guanjianzi = new String[]{"begin","end","if","then","else","while","do","not","and","or","true","false","until"}; //---------------主函数--------------- public static void main(String[] args) { test01 file=new test01(); file.loadfile(); if(kuohao%2!=0){ //如果括号不匹配 CWSL++; KHCW=true; } if(huakuohao%2!=0){ //如果花括号不匹配 CWSL++; HKHCW=true; } if(WSBDFH){ //如果包含未识别的符号$ CWSL++; } //纠错部分 if(CWSL==0){ //代码中没有错误 System.out.println("-------共有"+hanghao+"行,词法分析结束!当前代码中没有错误!-------"); } else { System.out.println("-------共有"+hanghao+"行,词法分析结束!当前存在"+CWSL+"处错误,代码中【*】表示有错-------"); if(SZCW){ System.out.println("------数值长度错误-------"); } if(KHCW){ System.out.println("-------括号不匹配-------"); } if(HKHCW){ System.out.println("-------花括号不匹配-------"); } if(WSBDFH){ System.out.println("-------代码存在不能识别的符号‘$’-------"); } } } //----------------输出函数--------------- public void Retract(){ if(shibie()== 1){ System.out.println("保留字--"+neirong); }else if(shibie() == 3){ System.out.println("变量--"+neirong); } else if(shibie() == 2){ if(neirong.length()>8){ //检查数字长度是不是超过8位 System.out.println("数字--"+neirong+"超出长度---------------【*】"); CWSL++; SZCW=true; } else{System.out.println("数字--"+neirong);} } neirong.delete(0, neirong.length()); //将已经识别的字符串从全部内容中删去 } //---------判断是否是字母a-z/A-Z --------------- public boolean Iszimu(){ if((ch>=65 && ch <= 90) || (ch >= 97 && ch <=122)){ return true; } return false; } //------------判断是否是数字 0-9 ----------- public boolean Isshuzi(){ if(ch>=48 && ch <= 57){ return true; } return false; } //---------------------识别文本内容函数--------------- public int shibie(){ for(int i = 0;i < guanjianzi.length;i++){ if(neirong.toString().equals(guanjianzi[i])){ // equals()函数,功能:比较字符串的内容 return 1; } } if(neirong.length() != 0){ //还有内容存在 if(neirong.charAt(0)>='0' && neirong.charAt(0)<='9'){ return 2; //是数字 } if(Iszimu()==true || Iszimu()==false){ //是变量 return 3; } } return 0; } //---------------连接字符函数------------- public void Concat(char ch){ neirong.append(ch); //append()函数,功能连接一个字符串到末尾 } //----------------读取文件函数------------ public void loadfile(){ BufferedReader br; //BufferedReader()函数,作用:将字符流放入缓存里 try { br = new BufferedReader(new FileReader("D:/test1.txt")); System.out.println("---------读取文件内容完毕!!----------"); System.out.println("----------词法分析如下:--------------"); System.out.println("-----------第1行开始:"); while((ch = br.read()) != -1){ //正确的读取到字符,rand()函数返回值为-1 时为读取出错 if(ch!=32&&ch!=13&&ch!=10){ //遇到不是空格或者回车符 if(Iszimu()){ //遇到字母 if(Iszimu() == true || Isshuzi() == true){ //遇到字母并且后面是数字 Concat((char) ch); //Concat()函数,作用:将其连接 } }else if(Isshuzi() == true){ //遇到单独数字时追加 Concat((char) ch); } //判断界符,包括:(、)、{、} else if((char) ch == '(') { Retract(); kuohao++; System.out.println("界符--"+(char) ch); } else if((char) ch == ')') { Retract(); kuohao++; System.out.println("界符--"+(char) ch); } else if((char) ch == '{') { Retract(); huakuohao++; System.out.println("界符--"+(char) ch); } else if((char) ch == '}') { Retract(); huakuohao++; System.out.println("界符--"+(char) ch); } //判断运算符,包括:+、-、*、/、:= 、=、<>、>、>=、<、<=。 else if((char) ch == '<') { Retract(); System.out.println("逻辑运算符--'"+(char) ch+"'"); } else if((char) ch == '>') { Retract(); System.out.println("逻辑运算符--'"+(char) ch+"'"); } else if((char) ch == '=') { Retract(); System.out.println("逻辑运算符--'"+(char) ch+"'"); } else if((char) ch == ':') { Retract(); System.out.println("逻辑运算符--'"+(char) ch+"'"); } else if((char) ch == '*') { Retract(); System.out.println("运算符--'"+(char) ch+"'"); } else if((char) ch == '-') { Retract(); System.out.println("运算符--'"+(char) ch+"'"); } else if((char) ch == '+') { Retract(); System.out.println("运算符--'"+(char) ch+"'"); } else if((char) ch == '/') { Retract(); System.out.println("运算符--'"+(char) ch+"'"); } //判断是否有不能识别的符号 else if((char) ch == '$') { Retract(); WSBDFH=true; System.out.println("未识别的符号--'"+(char) ch+"'---------------【*】"); } }else{ Retract(); } //提示行号 if(ch==13){ hanghao++; System.out.println("----------第"+hanghao+"行开始:"); } } } catch (FileNotFoundException e1) { System.out.println("----------找不到文件请检查文件目录--------------"); } catch (IOException e) { System.out.println("----------文件读取异常--------------"); } } }
测试文本(D:/test1.txt)的内容:
{if not (x=y then$ if y1=588882222 then y:=y+1