1、 实验一 简单词法分析器构造(4 学时)一 实验目的1、 掌握正则表达式、有限自动机2、 构造简单的词法分析器二 词法规则(C 语言分析及状态转换图)1、C 语言说明C 语言有以下记号及单词(1)标识符:以字母或下划线开头的,后跟字母、数字或下划线组成的符号串。(2)保留字:标识符的子集。(3)无符号数:(4)关系运算符:、=、 0)errorLine -;point -;int InsertId(char *str)int i;for(i=0; i kind = ID;pDu-value = value;elsepDu-kind = code;pDu-value = -1;return tr
2、ue;case D:while(isdigit(ch)wordgeti+ = ch;GetChar();wordgeti = 0;Retract();value = InsertConst(wordget);pDu-kind = CONST;pDu-value= value;return true;case “:dowordgeti+ = ch;GetChar();while(ch != “ wordgeti+ = ch; wordgeti = 0;if(ch = 0)printf(“%s“,wordget);ProcError(3);pDu-kind = ERROR;pDu-value =
3、0;elsevalue = InsertConst(wordget);pDu-kind = CONST;pDu-value = value;return true;case :wordgeti+ = ch; GetChar();wordgeti+ = ch;if(ch = ) GetChar(); wordgeti+ = ch;GetChar();wordgeti+ = ch;wordgeti = 0;if(ch != )printf(“%s“,wordget);ProcError(2);pDu-kind = ERROR;pDu-value = 0;elsevalue = InsertCons
4、t(wordget);pDu-kind = CONST;pDu-value = value;return true;case (:case ):case :case :case .:case ,:case :case ?:case :case ;:case :case :case #:wordgeti+ = ch; wordgeti = 0;pDu-kind = DIVIDE; pDu-value = -1;return true;case !:wordgeti+ = ch;GetChar();if (ch=) wordgeti+ = ch;else Retract();wordgeti=0;
5、break;case :wordgeti+ = ch;GetChar();if (ch = | ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case =:wordgeti+ = ch;GetChar();if (ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case GetChar();if (ch = else Retract();wordgeti=0;break;case |:wordgeti+ = ch;GetChar();if (ch = | | ch =
6、=) wordgeti+ = ch;else Retract();wordgeti=0;break;case +:wordgeti+ = ch;GetChar();if (ch = + | ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case -:wordgeti+ = ch;GetChar();if (ch = - | ch = = | ch = ) wordgeti+ = ch;else Retract();wordgeti=0;break;case *:wordgeti+ = ch;GetChar();if (ch = *
7、 | ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case /:wordgeti+ = ch;GetChar();if (ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case %:wordgeti+ = ch;GetChar();if (ch = =) wordgeti+ = ch;else Retract();wordgeti=0;break;case :wordgeti+ = ch;GetChar();if (ch = =) wordgeti+ = ch;el
8、se Retract();wordgeti=0;break;case 0:return false;default:ProcError(1);return false;pDu-kind = OPERAT;return true;int main(int argc, char* argv)Dualistic tmp;pDualistic ptmp = FILE *fin, *fout;int i;char c;printf(“源代码读入n“);if (fin=fopen(“Test.c“,“r“) = NULL)printf(“Cannot open infilen“);return 0;i =
9、 0;while(c = fgetc(fin) != EOF)if(i = PRO_MAX_LEN-1)printf(“n 程序代码太长,无法处理a“);return 0;proBufferi+ = c;fclose(fin); proBufferi+ = 0;printf(“n*n 源代码读入成功,源代码如下:n%s“,proBuffer);printf(“n 按任意键继续n“); getch();printf(“n 预处理n“);pretreatment();printf(“n*n 预处理成功,去掉注释后的源代码为:n%s“,proBuffer);printf(“n 按任意键继续n“);
10、getch();printf(“n 词法分析n“);point = 0;if (fout=fopen(“Result.txt“,“wb“) = NULL)printf(“建立文件 Result.txt 失败。n“);return 0;i = 0;errorLine = 0; doif(i+ PRO_MAX_LEN)break;if(!wordAnalyse(ptmp)break;if (ptmp-value = -1)fprintf(fout, “t“,ptmp-kind);elsefprintf(fout, “t“,ptmp-kind, ptmp-value);switch(ptmp-kin
11、d)case ERROR:fprintf(fout, “(出 错:%s)“,wordget);break;case ID:fprintf(fout, “(标识符:%s)“,wordget);break;case CONST:fprintf(fout, “(常 量:%s)“,wordget);break;case OPERAT:fprintf(fout, “(运算符:%s)“,wordget);break;case DIVIDE:fprintf(fout, “(界 符:%s)“,wordget);break;default:;if(ptmp-kind = 1 fprintf(fout, “rn“
12、); while(1);fclose(fout);printf(“n*n 写回常量表和标识符表n“);if (fout=fopen(“Const.txt“,“wb“) = NULL)printf(“建立文件 Const.txt 失败。n“);return 0;for(i = 0; i pointCTB; +i)fprintf(fout, “%3d %srn“,i, constTabi);fclose(fout);if (fout=fopen(“Sign.txt“,“wb“) = NULL)printf(“建立文件 Sign.txt 失败。n“);return 0;for(i = 0; i pointSTB; +i)fprintf(fout, “%3d %srn“,i, signTabi);fclose(fout);printf(“n 写入完毕n 按任意键继续n“); getch();return 0;