实验内容:
编制一个读单词过程,源程序为一个文件,读取该文件,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、界符五大类。并依次输出各个单词的内部编码及单词符号自身值。
单词的内部编码如下:
1、保留字:if、int、for、while、do、return、break、continue;单词种别码为1;
2、标识符:除保留字外的以字母开头,后跟字母、数字的字符序列;单词种别码为2;
3、常数为无符号整形数;单词种别码为3;
4、运算符包括:+、-、*、/、=;单词种别码为4;
5、分隔符包括:,、;、{、}、(、); 单词种别码为5。
代码实现:
//mainpage.java
/** * 高泽伟 19.11.15 */ package rjgz_CiFaFenXiQi; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.util.Arrays; import java.util.List; public class mainpage { //利用List存放五大单词类 //保存关键字 private static List<String> KeyWords; //保存运算符 private static List<String> Operators; //保存界符 private static List<String> Boundarys; //空格字符 private static List<String> Spaces; //剩下的就是标识符 //初始化单词 static { // 关键字数组 --> 关键字列表 String[] keywordArr = { "public", "private", "protected", "short", "int", "long", "char", "float", "double", "boolean", "static", "void", "for","while" ,"return","continue"}; KeyWords = Arrays.asList(keywordArr);//Arrays.asList(keywordArr)返回指定数组支持的固定大小列表 // 操作符数组 --> 操作符列表 String[] operatorArr = { "+", "-", "*", "/", "%", "=", ">", "<", "&" }; Operators = Arrays.asList(operatorArr); // 界符数组 --> 界符列表 String[] boundaryArr = { "" + '{', "" + '}', "" + '[', "" + ']', "" + '(', "" + ')', "" + ';' , "" + '.' }; Boundarys = Arrays.asList(boundaryArr); // 空格字符数组 --> 空格字符列表 String[] SpaceArr = { " ", " ", " " }; Spaces = Arrays.asList(SpaceArr); } static String str="";//存储文件内容的字符串 static StringBuffer strb = new StringBuffer();//字符串缓冲 static boolean isDelimiter = false;//判断是否有分隔符 //主函数 public static void main(String[] args) { String inStr = readFileByChars("E:/课程学习资料/软件构造 刘丹/软件构造/源程序代码test.txt"); //System.out.println("+++"+inStr); System.out.println("---------------------词法分析器---------------------"); for (char ch : inStr.toCharArray()) {//toCharArray() 方法将字符串转换为字符数组。 // System.out.println(ch); match(ch); } } /* * 将文件里的源码以String格式存入str字符串,并且排除了‘~’符(为啥?) */ public static String readFileByChars(String fileName) { Reader reader = null; try { //System.out.println("以字符为单位读取文件内容,一次读多个字符:"); // 一次读多个字符 char[] tempchars = new char[300];//char[] 字符数组 int charread = 0; reader = new InputStreamReader(new FileInputStream("E:/课程学习资料/软件构造 刘丹/软件构造/源程序代码test.txt")); // 读入多个字符到字符数组中,charread为一次读取字符数 /* * read()会返回一个布尔值,有数据则为true,没有数据就是false * reader.read(char[])返回字符的个数( 占两个字符) */ while ((charread = reader.read(tempchars)) != -1) { //这一步运行了charread = reader.read(tempchars) System.out.println("-------读取过程:-------"); System.out.println("charread="+charread); //排除'~'符 if ((charread == tempchars.length) && (tempchars[tempchars.length - 1] != '~')) { System.out.print(tempchars+"1"); } else { for (int i = 0; i < charread; i++) { if (tempchars[i] == '~') { continue; } else { str+=tempchars[i]; System.out.println(tempchars[i]); } } System.out.println("-------源程序str:-------"); System.out.println(str); } } } catch (Exception e1) { e1.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e1) { } } } return str; } /* * 识别单词并分类 */ static void match(char ch) { // 分割符缓冲 StringBuffer bouStrb = new StringBuffer(); // 1. 判断字符类型 /** * 以(界符、空格符、运算符)作为(关键字和一般标识符)的划分 * 即,(关键字和一般标识符)两边一定是(界符、空格符、运算符) */ // 1.0 空格,返回空格 if (Spaces.indexOf(ch + "") >= 0) { /* * indexOF(String) * 返回字符中indexof(string)中字串string在父串中首次出现的位置, * 从0开始!没有返回-1;方便判断和截取字符串! */ isDelimiter = true; } // 1.1. 操作符, 返回"operator" if (Operators.indexOf(ch + "") >= 0) { isDelimiter = true; bouStrb = new StringBuffer(ch + " 是操作符 单词种别码为4"); } // 1.2 界符, 返回"boundary" if (Boundarys.indexOf(ch + "") >= 0) { isDelimiter = true; bouStrb = new StringBuffer(ch + " 是界符 单词种别码为5"); } /** * 如果是分隔符,则判断已经存入strb内的内容是常数、关键字还是标识符 */ if (isDelimiter) { if (strb.length() > 0) { //charAt() 方法可返回指定位置的字符。 if (strb.charAt(0) >= '0' && strb.charAt(0) <= '9') { System.out.println(strb + " 是常数 单词种别码为3"); } else if (KeyWords.indexOf(strb.toString()) >= 0) { //toString()方法返回反映这个对象的字符串 System.out.println(strb + " 是关键字 单词种别码为1"); } else { System.out.println(strb + "是标识符 单词种别码为2"); } } if (bouStrb.length() > 0) System.out.println(bouStrb); strb.setLength(0); isDelimiter = false; return; } /** * 如果不是分隔符,则将该字符存入strb内,直到出现分隔符 */ strb.append(ch); } }
源程序文件内容:
//源程序代码test.txt if i>j then ~i=0 else j=1
实验结果截图:
发现自己好多java基础的东西都不会,借这次实验把一些不会的东西从网上找到答案,用注释写在代码里了,以后还要多加学习,补习java。