【编译原理】词法分析器代码分析报告


一、词法分析器设计思路说明

       该词法分析器基于状态转换图进行设计。首先画出识别特定单词的状态转换图并编写对应的单词识别程序,然后把不同的状态转换图合并为完整的状态转换图,并编写对应的完整的识别程序。完整的识别程序中,根据输入字符的不同调用识别不同单词的程序。

1.全局状态图

全局状态图
       “扫描程序”是将源程序文件从文件中读取存在内存,读到一个字符串缓冲区中了。识别单词就是识别这个字符串中每个字符的类型,然后产找对应的token值插入到token表中。如果在识别单词时,识别结果非单词,则进入异常处理状态,进行报错。在分状态转换图中识别非单词进入异常处理状态都存在且重复,就省略。

2.识别单词的状态转换图

识别单词的状态转换图
       首先识别一个非空字符串,进入首字符类型判断状态,根据不同的类,调用不同的“处理机”,然后查找token表,找到对应的token值,最后添加到集合中。

3.识别注释与除号状态转换图

识别注释与除号状态转换图
        在识别注释与除号的过程中,先进入识别状态识别字符串第一个字符为‘/’,则进入处理注释与除号的“处理机”,并开始识别下一个字符,如果下一个字符是‘/’,则进行迭代,直接读取下一个的内容,如果是‘’,则就行迭代读取,直到读取到前一个字符为‘’,后面接着‘/’,则开始识别下一个字符,处理注释与除号的“处理机”

4.识别字符字符串状态转换图

识别字符字符串状态转化图
       在识别字符与字符串的过程中,第一个字符为‘’’或‘”’则进入字符与字符串的“处理机”,先存进缓存栈,然后删除此字符开始识别下一个字符(第一个字符为‘’’),如果识别的字符为非‘’’则进行循环识别并连接字符,直到识别到‘’’表示识别结束,返回字符的token值,字符串处理类似于字符处理;开始识别下一个字符(第一个字符为‘’’’),则进行循环识别并连接字符,直到识别到‘’’’表示识别结束,返回字符串的token值。

5.识别关键字与常量的状态转换图

识别关键字与常量的状态转换图
       在识别关键词和变量名的过程中,先识别第一个单词如果是字母,则进入关键词和变量名“处理机”,如果就一个单词则直接返回token值,如果后面还有则继续识别,直到识别结束,返回token值,然后查字典,如果在字典中,则说明是一个字符,不在则说明是一个自定义变量。

6.识别界符与运算符的状态转换图

识别界符与运算符的状态转化图
       在识别界定符和运算符的过程中,先进行识别字符,如果字符为界符,则创建token对象。进行下一次识别,如果为运算符则记录此符号之前的符号,并识别此符号下一个字符,如果还有其他字符,则进出处理机处理状态,否则删除缓存队列,进行下一次识别。然后开始自循环遍历缓存栈中所有元素,直到遍历到终结界符,然后返回。


在这里插入图片描述
       先进性识别字符状态,如果识别下一个字符如果是0或1,并自循环判断此数中只出现0和1则返回二进制的token值,同理只存在0到7之间的数可能是八进制,十进制,十六进制,进行下一次判断。如果出现字母A~F则返回十六进制,如出现9但不出现字母,则返回八进制。
例如:识别”//asdeaaq\true”
       因为第一个第二个字符为’/’则调用注释与除号的处理机,直到读取到换行符‘\’,然后进入识别单词的处理机,识别单词true。
查表查表,返回token值为24。

二、TinyScript的词法要求

1.TinyScript的字符集

TinyScript的字符集由英文大写字母,小写字母,数字,下划线和空白符号,以及下述特殊符号构成的:
TinyScript字符集

2.TinyScript中的关键字

关键字

3.TinyScript中的运算符

TinyScript的运算符包括算数运算符、逻辑运算符和关系运算符
运算符


三、词法分析器代码分析

词法分析器包括commom和lexer两个包,分别分析如下。

1.common包

common包内的类分析如下。

1AlphabetHelperAlphabetHelper类的主要作用是定义TinyScript语言的字母表,包含以下4个属性和4个方法。

·ptnLetter属性
ptnLetter是Pattern类型的模式串,用于匹配单个字母,可以是大写字母或小写字母。

·ptnNumber属性
ptnNumber是Pattern类型的模式串,用于匹配0-9中的单个数字。

·ptnLiteral属性
ptnLiteral是Pattern类型的模式串,用于匹配单个大写字母或小写字母或0-9中的单个数字

·ptnOperator属性
ptnOperator是Pattern类型的模式串,用于匹配算数运算符、逻辑运算符、关系运算符等统称为运算符、操作符。

·isLetter()方法
isLetter(char c)返回boolean类型的结果,用于判断参数c是否为字母。

·isNumber()方法
isNumber(char c)返回boolean类型的结果,用于判断参数c是否为数字。

·isLiteral()方法
isLiteral(char c)返回boolean类型的结果,用于判断参数c是否为字母或数字。

·isOperator()方法
isOperator(char c)返回boolean类型的结果,用于判断参数c是否为运算符、操作符。
2PeekIteratorPeekIterator类的主要作用是定义缓存流队列,包含以下5个属性和7个方法。

·It属性
ItIterator<T>类型定义的一个迭代器.来访问一个容器对象中各个元素。

·queueCache属性
queueCache是LinkedList<T>类型定义的链表数据结构,表示缓存队列作为正在处理的字符执行窗口

·stackPutBacks属性
stackPutBacks是LinkedList<T>类型定义的链表数据结构,表示缓存栈存已经处理过的n字符。

·CACHE_SIZE属性
CACHE_SIZE是int类型定义的变量,表示缓存窗口的大小。

·_endToken属性
  _endToken是T类型(即任意类型)定义的变量,表示结束符。
  
·PeekIterator(Stream<T> stream)方法
PeekIterator(Stream<T> stream)初始化构造迭代器,用其缓存元素。

·PeekIterator(Iterator<T> _it, T endToke)方法
PeekIterator(Iterator<T> _it, T endToke)初始化构造迭代器,并初始化结束符号。

·PeekIterator(Stream<T> stream, T endToken)方法
PeekIterator(Stream<T> stream, T endToken)初始化构造流对象,并初始化结束符号。

·peek()方法
peek()方法用于实现获得数据头,不提取仅获得。

·putBack()方法
putBack()方法回退数据操作,从缓存中拿到最后一个数据放到回退栈中

·hasNext()方法
重写实现类IteratorhasNext()方法,返回boolean类型的结果,判断是否存在下一个值

·next()方法
重写实现类Iteratornext()方法,返回下一个值,优先从回退栈中取,栈为空的话从迭代器里拿。

2.lexer包

lexer包内的类分析如下:

1KeywordsKeywords的主要作用是定义TinyScript语言的的保留关键字,实现关键词字典。包含以下2个属性和1个方法。

·keywords属性
keywords是String[]类型定义的字符数组,内包含TinyScript语言的的保留关键字。

·set属性
set是HashSet<String>类型定义的包含keywords的数组。

·isKeyword()方法
isKeyword(String word)返回boolean类型的结果,用于判断参数word中是否与keywords中的保留关键字重复。
2LexerLexer类主要作用是进行词法分析.包含了以下3个方法.
·analyse(PeekIterator<Character> it)方法
analyse(PeekIterator<Character> it)对缓存队列中的元素进行词法分析,主要进行以下操作:
1.读一非空字符
2.首字符分类: 如果首字符为’/’进入删除注释处理; 
如果是",'开头交给字符串状态机处理; 如果是字母交给变量或关键字状态机处理;
 如果是数字交给数字状态机处理; 如果是运算符交给运算符状态机处理
 
·analyse(Stream source)方法
analyse(Stream source)初始化流和结束符号,将词法分析后的单词token值以集合形式返回.

·fromFile(String src)方法
fromFile(String src)从源代码文件加载并解析文件内容.即解析代码程序文件.3Lexical ExceptionLexicalException的主要作用是进行词法分析的异常显示,包含以下1个属性和3个方法。

·msg属性
msg是String类型定义的字符串,用于表示错误信息。

·LexicalException(char c)方法
LexicalException(char c)方法用于将传入的错误的字符c表示为一个句子"Unexpected character %c"。

·LexicalException(String _msg)方法
LexicalException(String _msg)方法用于对传参

·getMessage()方法
重写String类型的getMessage()方法,返回获取的msg的内容。
4TokenToken类的主要作用是保存代码中的Token,
 其中包括关键字/标识符/操作符/字符串/数字等定义的TokenType,以及对词语的提取。
 包含以下2个属性和15个方法。
·_type属性
_type是TokenType类型定义的,表示字符类型

·_value属性
_value是 String类型定义的,表示字符值

·Token()方法
Token(TokenType type, String value)方法用于初始化字符类型和字符值

·getType()方法
getType()方法用于返回type的值

·getValue()方法
getValue()方法用于返回value的值

·toString()方法
重写String类型的toString方法,用于输出type和value的值
    
·isVariable()方法
isVariable()返回boolean类型的结果,用于判断是否为变量。

·isScalar()方法
isScalar()返回boolean类型的结果,用于判断是否为规范的类型。

·isOperator()方法
isOperator()返回boolean类型的结果,用于判断是否为操作符。

·isPostUnaryOperato()方法
isPostUnaryOperator()返回boolean类型的结果,用于判断是否为后置一元运算符

·isType()
isType()返回boolean类型的结果,用于判断是否为定义类型

·isValue()方法
isValue()返回boolean类型的结果,用于判断是否为变量

·isNumber()方法
isNumber()返回boolean类型的结果,用于判断是否为数字

·makeVarOrKeyword(Peeklterator<Character>)方法
用于提取关键字与变量名

·makeString(Peeklterator <Character>)方法
用于提取字符串

·makeOp(Peeklterator<Character>)方法
用于提取操作符

·makeNumber(Peeklterator<Character>)方法
用于提取数字,其中涉及到小数以及正负数的判断
5TokenTypeTokenType类的主要作用是实现符号类型枚举。

四、测试执行过程分析

词法分析器的测试代码位于src/test/java目录下,包括commom和lexer两个包,分别分析如下。
1.common包
common包内的类分析如下。
(1)AlphabetHelperTests类
AlphabetHelperTests类的主要作用是对AlphabetHelper类的4个方法进行测试,通过test()方法验证其能否正确区分是否为相应类型的字符。
在这里插入图片描述

经测试,AlphabetHelper类的4个方法实现了相应功能。

(2)PeekIteratorTests类
PeekIteratorTests类的主要作用是对PeekIterator类的3个方法进行测试,通过
test_peek()方法测试迭代器是否能够正常读取字符.
在这里插入图片描述

test_lookahead2()方法测试检索并删除此列表的最后一个元素,如果此列表为空,则返回 null 。即测试新插入的元素.
在这里插入图片描述

test_endToken()方法测试结束符相关方法是否奏效.
在这里插入图片描述

经测试PeekIterator类的3个方法均实现相应功能.

2.lexer包
lexer包内的类分析如下。
(1)LexerTests类
LexerTests类主要的作用是对Lexer类7个方法的测试.
test_expression()方法测试字符串是否能够被单词识别系统正确识别.
在这里插入图片描述

test_function()方法测试对方法体的识别检测.
在这里插入图片描述

test_deleteComment()方法主要测试对注释的删除屏蔽功能, 之后是否不影响正常代码

在这里插入图片描述

test_deleteErrorComment()方法主要测试对错误注释/*/的异常处理

在这里插入图片描述

test_deleteOneLine()方法主要测试对单行注释的删除屏蔽,之后是否不影响正常代码
在这里插入图片描述

minus()方法主要测试对运算符号’-’的测试,是否成功识别.
在这里插入图片描述

test_loadFile方法主要对加载源文件代码的提取识别进行测试.
在这里插入图片描述

经测试LexerTests类的7个方法均实现相应功能.

(2)TokenTests类
TokenTests类主要的作用是对Token类4个方法的测试.
test_varOrKeyword()方法主要对提取的关键字与变量名进行测试
在这里插入图片描述

test_makeString()方法主要对提取的进行字符串判断测试

在这里插入图片描述

test_makeOperator()方法主要对提取进行操作符判断测试
在这里插入图片描述

test_makeNumber()方法主要对提取的进行数字判断测试
在这里插入图片描述

经测试TokenTests类的7个方法均实现相应功能.

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慢热型网友.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值