欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

编译原理 实验一:词法分析器的自动实现(Lex词法分析)-5.2 完整代码

最编程 2024-08-14 16:14:13
...
%{
  #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”);”同理。

最后识别两个右大括号。读取到文件结束符后,程序结束。

七、实验感悟