编译原理 实验一:词法分析器的自动实现(Lex词法分析)-5.2 完整代码
%{ #include <stdio.h> #include <stdlib.h> int count = 0; %} digit [0-9] letter [a-zA-Z] reservedWord [w][h][i][l][e]|[i][f]|[e][l][s][e]|[s][w][i][t][c][h]|[c][a][s][e]|[i][n][t]|[m][a][i][n]|[u][s][i][n][g]|[n][a][m][e][s][p][a][c][e]|[s][t][d]|[p][r][i][n][t][f] id ({letter}|_)({letter}|{digit}|_)* num {digit}+ operator \+|-|\*|<=|<|==|=|>=|>|>>|<< delim [ \t\n\r] whitespace {delim}+ semicolon [\;] str \"[^"]*\" other . %% {reservedWord} {count++;printf("%d\t(reserved word,\'%s\')\n",count,yytext);} {id} {count++;printf("%d\t(id,\'%s\')\n",count,yytext);} {num} {count++;printf("%d\t(num,\'%s\')\n",count,yytext);} {operator} {count++;printf("%d\t(op,\'%s\')\n",count,yytext);} {whitespace} { /* do nothing*/ } {str} {count++;printf("%d\t(string,\'%s\')\n",count,yytext);} "(" {count++;printf("%d\t(left bracket,\'%s\')\n",count,yytext);} ")" {count++;printf("%d\t(right bracket,\'%s\')\n",count,yytext);} "{" {count++;printf("%d\t(left bracket,\'%s\')\n",count,yytext);} "}" {count++;printf("%d\t(right bracket,\'%s\')\n",count,yytext);} ":" {count++;printf("%d\t(colon,\'%s\')\n",count,yytext);} ";" {count++;printf("%d\t(semicolon,\'%s\')\n",count,yytext);} "#".* {count++;printf("%d\t(head,\'%s\')\n",count,yytext);} {other} {printf("illegal character:\'%s\'\n",yytext);} %% int main(){ yyin=fopen("F:/HOMEWORK/Compiler/Lab2/test.c","r"); yylex(); return 0; } int yywrap(){ return 1; }
六、运行结果
编译运行.l文件,加入参数nounistd,生成了可在Windows 10 环境下可以运行的lex.yy.c,如图3所示。
如图4,编写用于测试词法分析器的真实c语言代码。
对lex.yy.c代码进行编译运行,并将结果输出在控制台上,如图5。该词法分析器能自动忽略空格、换行符、tab,按照顺序逐一将每个单词进行编号,并生成二元组(单词种别,单词自身的值)。
图5词法分析结果与图4的测试文件一一对应。
头文件首先被识别出来。识别语句using namespace std
,并识别语句的分号。
识别int main
,并识别紧随其后的左右小括号与大括号。
源代码“int a1=0;
”被识别如下:保留字int,标识符a1,赋值号=,数字0。并识别分号。
源代码“if(a1==1);
”被识别如下:保留字if、左括号、标识符a1、比较相等的符号==、数字1、右括号、分号。
源代码“printf(“hello world”)
”被识别为:保留字printf、左括号、字符串”hello world”、右括号。需要说明的是,”hello world”字符串是一个单词,没有因为中间有空格而被识别为两个单词。
else、switch等单词均为保留字。识别标识符a1、括号的过程都是同理的。
源代码“case 1:printf(“hello”);
”被识别为:保留字case、数字1、保留字printf、左括号、字符串”hello”、右括号、分号。源代码“case 2:printf(“world”);
”同理。
最后识别两个右大括号。读取到文件结束符后,程序结束。
七、实验感悟
下一篇: 用C语言制作的猜数游戏- 重新发现乐趣!