实验任务
-
使用
bison
实现c--
语法分析器- 完成语法分析,生成语法分析树
- 识别语法错误,输出错误信息,完成错误恢复
- 识别单行和多行注释,不支持嵌套注释(识别为语法错误)
-
实现效果源码
// 例1.2 int main() { float a[10][2]; int i; a[5,3] = 1.5; if(a[1][2] == 0) i = 1 else i = 0; a(x); }
// 例1.3 int inc() { int i; i = i + 1; }
// 例1.4 struct Complex { float real, image; }; int main() { struct Complex x; y.image = 3.5; }
// 例1.5 int main() { int i = 0123; int j = 0x3F; }
// 例1.6 int main() { int i = 09; int j = 0x3G; }
// 例1.7 int main() { float i = 1.05e-4; }
// 例1.8 int main() { float i = 1.05e; }
// 例1.9 int main() { // line comment /* block comment */ int i = 1; }
// 例1.10 int main() { /* comment /* nested comment */ */ int i = 1; }
实验步骤一、熟悉bison
文件结构,和flex
的联合
- 实验指导书
1.2.7-1.2.15
- 参考
实验步骤二、熟悉bison
文件编写
-
首部包含
lex.l
生成的词法分析程序lex.yy.c
%{ #include "lex.yy.c" %}
-
syntax.y
词法单元(非终结符)声明%token INT %token FLOAT %token SEMI %token COMMA %token ASSIGNOP %token RELOP %token PLUS %token MINUS %token STAR %token DIV %token AND %token OR %token DOT %token NOT %token TYPE %token LP %token RP %token LB %token RB "]" %token LC %token RC %token STRUCT %token RETURN %token IF %token ELSE %token WHILE %token ID
-
syntax.y
产生式规则(此处无生成语法树相关内容)/* 全局变量及函数定义 */ Program : ExtdefList { printf("规约为正确的程序\n"); } ; ExtdefList : Extdef ExtdefList { printf("规约为定义全局变量或函数\n"); } | /* empty */ { printf("所有全局变量及函数定义完毕\n"); } ; Extdef : Specifier ExtDecList SEMI { /* 声明变量列表 */ /* 结构体全局变量 */ printf("规约为定义全局变量\n"); } | Specifier SEMI /* 声明结构体 */ { printf("规约为定义结构体\n"); } | Specifier FunDec CompSt /* 声明函数 */ { printf("规约为定义函数\n"); } ; ExtDecList : VarDec { printf("规约为定义最后一个全局变量\n"); } | VarDec COMMA ExtDecList { printf("规约为继续定义全局变量\n"); } ; /* 变量类型 */ Specifier : TYPE { /* 基本类型 */ printf("规约为基本类型\n"); } | StructSpecifier /* 结构体 */ { printf("规约为结构体类型\n"); } ; StructSpecifier : STRUCT OptTag LC DefList RC /* 定义结构体 */ { printf("规约为结构体定义语句\n"); } | STRUCT Tag /* 声明结构体变量 */ { printf("规约为结构体声明语句\n"); } ; OptTag : ID { printf("规约为结构体名(定义语句中)\n"); } | /* empty */ { printf("规约为空结构体\n"); } ; Tag : ID { printf("规约为结构体名(声明语句中)\n"); } ; /* 变量函数定义 */ VarDec : ID { /* 变量名 */ } | VarDec LB INT RB { /* 数组 */ printf("规约为数组\n"); } ; FunDec : ID LP VarList RP { /* 有参函数 */ printf("规约为定义有参函数\n"); } | ID LP RP { /* 无参函数 */ printf("规约为无参函数\n"); } ; VarList : ParamDec COMMA VarList { /* 参数列表 */ printf("规约为定义函数参数列表\n"); } | ParamDec { printf("规约为最后一个函数参数\n"); } ; ParamDec : Specifier VarDec { /* 单个参数 */ printf("规约为定义函数参数\n"); } ; /* 函数体 */ CompSt : LC DefList StmtList RC { printf("规约为定义函数体/语句块\n"); } ; StmtList : Stmt StmtList { printf("规约为定义多个语句块\n"); } | /* empty */ { printf("规约为语句块定义结束\n"); } ; Stmt : Exp SEMI { printf("规约为定义表达式\n"); } | CompSt { printf("规约为定义内部函数体/语句块\n"); } | RETURN Exp SEMI { printf("规约为定义返回语句\n"); } | IF LP Exp RP Stmt %prec LOWER_THAN_ELSE { /* 加优先级 */ printf("规约为定义if语句\n"); } | IF LP Exp RP Stmt ELSE Stmt { printf("规约为定义if-else语句\n"); } | WHILE LP Exp RP Stmt { printf("规约为定义while语句\n"); } ; /* 局部变量 */ DefList : Def DefList { printf("规约为定义多个类型的局部变量\n"); } | /* empty */ { printf("规约为定义局部变量结束\n");