实验2-自顶向下语法分析1的目的是让学生深入理解LL(1)分析法,特别是FIRST集和FOLLOW集的计算,以及如何判断LL(1)文法和进行语法分析。这个实验通过手工编程的方式实现了一个简单的计算器,运用了递归下降分析方法。
实验内容包括将递归下降分析应用于算术表达式文法,生成抽象语法树,并设计一个计算器。递归下降分析是一种自顶向下的解析策略,其中每个非终结符对应一个函数,函数的调用顺序反映了文法的产生式结构。在这个实验中,给出的文法如下:
G[E]: E --> TE^ E^ --> +TE^ | $ T --> FT^ T --> *FT^ | $ F --> (E) | ii --> (0|1|2|3|4|5|6|7|8|9)*
实验的算法思想是模拟递归下降分析器的工作过程。程序首先将文法的产生式右部逆序压入栈中,每个函数代表产生式右部的最左边元素。在计算器部分,输入的算术表达式被分解成两个栈:算符栈和数字栈。由于算术运算符的优先级,例如+的优先级高于*,在遇到优先级高的运算符时,所有优先级低的运算符都会被弹出并组合成结果。例如,输入"2+3*4",程序会先处理"+",然后处理"*"。
在设计过程中,可能会遇到的问题包括如何动态输入上下文无关文法(CFG)进行分析。虽然最初设想较为复杂,但最终选择了将文法写死在程序中。计算器的实现参考了网上的资料,为了避免字符串到整数转换的复杂性,采用了两个栈分别存储运算符和数字。
实验特色在于计算器可以处理多次计算,并且对于复杂的算术表达式也能准确求解,具有较高的精度。
具体实现方面,程序定义了几个关键变量,如输入的字符串str、中间变量input_num、位置指针location、标志flag、存储输入的vector vec和两个栈char数组fz和sz分别表示符号栈和数字栈,以及对应的指针fhead和shead。此外,还有针对非终结符T、E、E1、T1、F的函数,这些函数在匹配文法规则时被调用,如E1()函数的例子所示,它处理文法规则E1-->+TE^|$。
match(char a)函数用于匹配终结符并移动指针,而invt(char a)函数用于识别非数值字符,如括号和运算符。jsq()函数是计算器的核心,负责解析和计算表达式。
这个实验旨在训练学生掌握编译原理中的自顶向下语法分析技术,通过实现一个简单的计算器,加深对LL(1)文法的理解和应用。通过解决实际问题,学生可以更好地掌握编译器设计的基本原理和方法。