软件构造——制作词法分析器

Posted jmdd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件构造——制作词法分析器相关的知识,希望对你有一定的参考价值。

实验内容:

编制一个读单词过程,源程序为一个文件,读取该文件,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、界符五大类。并依次输出各个单词的内部编码及单词符号自身值。

单词的内部编码如下:

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。

 

 

 

 

 

 

 

 

 

以上是关于软件构造——制作词法分析器的主要内容,如果未能解决你的问题,请参考以下文章

java编译器源码分析之词法分析器

编译原理 — 用Flex构造词法分析器

S3-词法分析

软件构造——递归下降分析法

软件构造实验三-递归下降分析分析法

编译原理 实验一 java语言实现对C语言词法分析