编译原理实验一 TINY语言的词法分析

    技术2023-09-25  85

    实验一 TINY语言的词法分析

    一、实验目的 (评价依据,描述是否准确到位) 构造tiny语言的词法分析器(扫描器),要求利用第三方的lex工具进行构造。实验结果:构造出的扫描器,能够读入教材样例中给出的tiny语言的示例代码,分解成token输出。

    二、实验设计 (评价依据实验方案设计是否合理) 一. Tiny语言记号

    Reserved words Special Symbols Other If + Then - Else * number(1 or more digits) End < Repeat = Until / Read ( Write ) identifier(1 or more letters) : :=

    二、构造Tiny语言DFA

    ID:letter(letter)*

    Number:digit(digit)*

    三、内容和步骤 1代码: 下面是tiny语言的代码如书上:

    { sample progarm in tiny language - computer factorial } read x;{ input an integer } if x < 0 then { don’t compute if x <= 0} fact := 1; repeat fact := fact * x; x := x - 1 until x = 0; write fact {output factorial of x} End

    2.下面是demo.l文件代码 %{ #include “stdio.h” int lineNum; %} digit [0-9]+ keyword read|if|then|repeat|until|write|end letter [a-zA-Z]+ comment {[^}]} operator “:=”|"="|"+"|"-"|""|"/"|">"|"<" ignore [","|";"|" “|\t|\n]+ %% {comment} { printf(”%s : comment\n",yytext); } {digit} { printf("%s : digit\n",yytext); } {keyword} { printf("%s : keyword\n",yytext); } {letter} { printf("%s : letter\n",yytext); } {operator} { printf("%s : operator\n",yytext); } {ignore} { /nothing/ } %% int yywrap() { return 1; } void main() { lineNum = 0; yylex(); return 0; } 通过flex demo.l命令将demo.l文件编译为一个c文件,将这个c文件编译运行,得到一个exe文件,用这个程序来解析tiny语言即可。 2、结果:

    四、实验结论: 1 理论基础(评价依据 理论知识非常清楚) 我们采用flex进行词法分析。flex是一个用来生成扫描器(scanners)的工具,其中扫描器就是可以识别文本中词法模式的程序。具体流程为:flex读取给定的输入文件,或标准输入(当没有给定文件名时)读取信息来生成一个扫描器。信息以正则表达式和C代码组成,这种形式称为规则(rule)。flex生成C源代码文件lex.yy.c,其中定义了一个函数yylex()。这个文件通过编译,并用-lfl 链接生成可执行文件。当可执行文件被执行时,它分析输入中可能存在的符合正则表达的内容。当找到任何一个与正则表达式相匹配内容时,相应的C 代码将被执行。 flex输入文件由三段组成:定义(definitions),规则(rules),用户代码(user code)

    2、分析和总结(评价依据:是否能够对实验结果作出完整和准确的描述,是否能够捕捉到实验中的各种现象,是否有强的信息综合能力,是否能得出正确的结论。) 实验过程中需要配置flex和bison的环境变量,在对原输入串进行分析的预处理在嵌套判断上出现了问题,调试了几次后才发现是计数值应该减少2。通过这次实验对词法分析器的运行机制有了更深的了解,状态转换图让我了解了一些编程语言的词法分析器是怎么书写的。 3、对工具的评价(优缺点及其局限性的总结) flex的设计目标就是生成一个高性能的扫描器。它已经对处理大量rule 做了优化。除了用-C 选项进行表格压缩之外,还有一些option/action 会影响到扫描器的速度。 比如javascript,就不适合使用flex作为词法分析器,Javascript 正则表达式字面量和除法操作符的二义性, 很难用 lex 解决, 一般只用 lex 做很少很少的事情, 然后把真正含义的辨清延迟到 parse 阶段. 真正复杂的问题是bison搞不定的,譬如说C++需要语义分析和语法分析同时做,让语义分析的结果来指导语法分析到底要选择哪条grammar rule来resolve conflict。

    Processed: 0.013, SQL: 9