词法分析部分
词法分析部分采用 Lex 自动生成。其中 Lex 使用的版本是 Flex version 2.5。Lex 完整程序见
文件 mipsAsm.l。下面对该程序进行详细解释。
1-15 行是定义段,主要包括头文件的引用、变量定义、函数声明等。其中,第 2 行包含了
词法分析程序中的常量定义(语法符号的内码)。第 6 行定义了一个 int 型变量 lineno,用来保
存当前分析的汇编程序源文件的行号,以便查到错误时报告位置。第 7 行是 str2inth 函数的声明,
该函数的作用是将字符串转为 16 进制 int 型整数。第 10 行表示让 Lex 生成默认版本的 yywrap()
函数。12-15 行定义了一些可能在规则段中用到的变量,alpha 表示英文字母,digitd 表示十进制
数字,digith 表示十六进制数字,alphanum 表示英文字母或十进制数字。
18-242 行是规则段,每行均由一个正规表达式和一段 C 语言程序组成,表示当词法分析器
根据正规表达式匹配到了一个字符串时,执行这段 C 语言程序。其中,18 行表示分析到换行符,
lineno 自增。20-39 行是一些汇编伪指令和标点符号,规则很简单,词法分析器只要遇到这些符
号直接返回一个常量,把控制权交给语法分析器。41-105 行是 mips 的 31 条指令(外加一条 nop
指令),同样,当词法分析器分析到这些字符串时,将返回一个常量给语法分析器。107-233 行
是寄存器的各种表示方法,规则同上。237 行表示词法分析器分析到一个标识符,将把该字符
串传给变量 yylval,然后返回一个常量;这里需要解释的是 yytext 是 Lex 的一个内置变量,存
放当前分析到的字符串,yylval 是 Yacc 的一个内置变量,表示语法符号的语义属性。238 行表
示当分析到一个十六进制整数,将其转换为 int 型,然后赋值给 yylval。239 行表示当分析到一
个十六进制负整数,将其转换为 int 型,然后赋值给 yylval。241 行表示忽略空白符(包括空格、
制表符、回车)。第 242 行表示如果上面 18-241 行所述的正规式都未得到匹配,那么词法分析
器将报错给用户。
246-252 行是用户定义段。上文曾经提到一个函数 str2inth(),其实现在此。
语法分析部分
语法分析部分采用 Yacc 自动生成。其中 Yacc 使用的版本是 Bison version 2.1。Yacc 完整程
序见文件 mipsAsm.y。下面对该程序进行详细解释。
1-49 行是定义段,主要包括头文件的引用、变量定义、函数声明等。其中,21-22 行是声
明了两个在词法分析部分的定义的变量,yyin 是输入文件的指针,lineno 是行号。24 行是词法
分析函数 yylex()的声明。25 行是错误处理函数 yyerror()的声明。28 行是数据段输出文件流定义。
29 行是代码段输出文件流定义。30 定义了一个 int 型变量 addr,用于保存指令或者数据所在存
储器中的地址。31 行定义了一个从字符串到整型的一个映射,作为符号表,map 模板的第三个
参数 KeyComp,是在 9-19 行定义的。34-37 行表示语法符号的语意属性可以是 int 型,也可以
是 char*型。39-43 行定义了一些终结符。45-49 行为一些语法符号指定了语意属性的类型。
52-158 行是规则段。这里用上下文无关文法定义了 mips 指令集汇编的语法规则。各条产生
式中有花括号围起来的是语意规则。也就是说这个汇编器是语意制导翻译的,即边分析边输出
翻译结果,一遍结束。52-53 行的产生式是说,一个程序由数据段和代码段组成。55-69 是数据
段语法的定义。71-158 是代码段语法的定义。
162-205 行是用户子程序段。162-164 行定义了错误处理函数,这个汇编器在发现语法错误
的时候会报告错误行号。167-205 行是整个汇编器的入口函数 main()。
- 1
- 2
前往页