void E1(); void T(); void T1(); void F(); //测试语法分析
void testSyntaxAnalyse();
//每个非终结符有对应的子程序 void E() { }
void E1() { } void T() { }
void T1() {
T(); E1();
if(strcmp(strToken,\ }
//Follow(E1)={#,)}
else if(strcmp(strToken,\ }
error(\语法分析错误!\getToken(); T(); E1();
F(); T1();
if(strcmp(strToken,\F(); T1(); }
9
getToken();
//Follow(T1)={+,#,)},如果考虑-号的话要加上-号
else if(strcmp(strToken,\strcmp(strToken,\ } void F() { }
//测试语法分析
void testSyntaxAnalyse() {
expression_index=0; getToken(); E();
puts(\语法分析结果如下:\ if(strcmp(strToken,\ }
10
}
error(\语法分析错误!\
if(isNum(strToken)){ } else{ }
if(strcmp(strToken,\ getToken(); } else
error(\语法分析错误!\ E();
if(strcmp(strToken,\ else
error(\语法分析错误!\
getToken();
getToken();
error(\语法分析错误!\ puts(\语法分析正确!\
else{
}
//主函数 int main() { } #endif
运行时要删掉test1.c中的主函数,运行结果
gets(expression); testLexAnalyse(); testSyntaxAnalyse(); return 0;
6、语义分析
要求:需要实现的语义分析程序的功能是,接受一个表达式,分析该表达式,并在分析的过程中建立该表达式的抽象语法树。由于四则运算表达式的抽象语法树可基本上看作是二叉树,因此中序遍历序列应该和输入的表达式一样——除了没有括号之外。可输出中序遍历序列检测程序功能是否正确。如果每个分支节点用一个临时变量标记,则对四则运算表达式的抽象语法树进行后序遍历,可以得到输入表达式所对应的四元式序列
test3.c文件
11
#ifndef TEST3_C #define TEST3_C /**
* 语义分析以及测试语义分析
* 其实这个实验是在test2的代码上进行修改 **/
#include\ /*
消除左递归的翻译模式: E ::= T E' E'1 E'1 E'::= + T E'::= - T E'::= ε T ::= F T'
T'::= * F
{E'.i:=T.nptr}
{E'1.i:=mknode('+',E'.i,T.nptr)} {E'1.i:=mknode('-',E'.i,T.nptr)} {E'.s:= E'.i} {T'.i:=F.nptr}
{T'1.i:=mknode('*',T'.i,F.nptr)}
{E.nptr:=E'.s} {E'.s:=E1.s} {E'.s:=E1.s}
{T.nptr:=T'.s}
T'1 {T'.s:=T1.s} T'::= / F {T'1.i:=mknode('/',T'.i,F.nptr)} T'1
{T'.s:=T1.s}
{T'.s:= T'.i}
T' ::= ε
F ::= (E) {F.nptr:=E.nptr}
F ::= num {F.nptr:=mkleaf(num,num.val)} */
#define MAX_LENGTH 20 //四元式中操作数的最大长度
typedef int ValType; //结点类型
typedef struct ASTNode {
Symbol sym;//类型 ValType val;//值
12

