[编译原理] 简单的词法分析器

本文是网易云课堂中国科学技术大学华保健老师教授的《编译原理》课程习题。

1 题目

在这部分中,你将使用图转移算法手工实现一个小型的词法分析器。

  • 分析器的输入:存储在文本文件中的字符序列,字符取自ASCII字符集。文件中可能包括下面几种记号:关键字if、符合C语言标准的标识符、无符号整型数字、空格符、回车符\n。
  • 分析器的输出:打印出所识别的记号的种类、及记号开始行号、开始列号信息。
    注意:1. 忽略空格及回车符;2. 对于标识符和数字,要输出符号的具体词法单元(见下面的示例)。
  • 【示例】对于下面的文本文件:
    ifx if iif if 234
    iff if
    你的输出应该是(注意,因为文本显示的原因,列号信息可能不一定准确):
    ID(ifx) (1, 1)
    IF (1, 4)
    ID(iif) (1, 8)
    IF (1, 13)
    NUM(234) (1, 16)
    ID(iff) (2, 1)
    IF (2, 8)

2 程序框架

2.1 构建表格存储状态转移图

根据题意构建出转移图:

[编译原理] 简单的词法分析器_第1张图片

词法分析器首先要将此转移图存储在特定数据结构中中,为了压缩表格存储,先将转移图中的边所含有的信息进行分类:

[编译原理] 简单的词法分析器_第2张图片

根据上述分类表,转移图针对每一个输入的字符,查找其所属类别,然后根据其类别进行状态转移,这样避免将所有的输入信息存储在状态转移图的数据结构中。状态转移表如下所示:

[编译原理] 简单的词法分析器_第3张图片

可接受的最终状态如下表格所示:

[编译原理] 简单的词法分析器_第4张图片

2.2 读入字符和回滚操作

使用相关IO函数,从文件中读入程序信息,以及在必要的时候执行rollBack()操作。本文使用Java实现,主要使用了API如下:

  • RandomAccessFile.read()从文件中读入1个字节
  • RandomAccessFile.seek()更改文件指针的位置,实现rollBack操作。

注意:要实现高效的词法分析器,应该使用合适的缓冲区,本文力图简单,直接在文件流中进行操作。关于缓冲区的具体实现可以参考文献[1]。

2.2 执行Parse操作

根据上述转移图的信息,逐步对输入文件执行parse操作的伪代码 [1] 如下:

NextWord()
    state = s0 ;
    lexeme = "";
    clear stack;
    push(bad);

    while (state != se) do
        NextChar(char);
        lexeme = lexeme + char;
        if(state in SA)
            then clear stack;
        push(state);
        cat = CharCat[char];
        state = δ[state,cat];
    end;

    while(state not in SA and state != bad) do
        state pop();
        truncate lexeme;
        RollBack();
    end;

    if(state in SA)
        then return Type[state];
    else 
        return invalid;

上述代码首先进行初始化操作,state表示目前所处的状态,lexeme表示目前累计读入的字符串,第一个while循环模拟了状态转移图的转移过程:

  • 读入字符
  • 状态转移

state存储在栈中,以便出现Se后进行回滚操作。CharCatδ分别表示2.1节中的分类表和状态转移表,读入字符后,根据读入的字符和这两张表进行相关的状态转移,直到状态为Se后停止转移。第二个while根据最终的状态是否是可接受的来决定是否进行回滚操作,直到找到可接受的最终状态。最后一段代码返回结果,如果没有可接受的最终状态,那么返回invalid表示已经无法解析出合法的Word。

2.3 总体结构

最终实现的简单词法分析器的具体结构如下:

[编译原理] 简单的词法分析器_第5张图片

使用了内部类Transition来表示状态转移表中的初始状态和读入的字符,并重写了其equals()方法和hashCode()方法,使其可以存储在HashMap中。

3 代码

见 githhub。


参考文献

[1]Torczon L, Cooper K. Engineering A Compiler[M]. Morgan Kaufmann Publishers Inc. 2007.

你可能感兴趣的:(Java)