LEX实现一个C语言子集的词法分析器,该词法分析器读入一个C语言的源程序,完成有以下功能。
a. 滤掉空格。(其中空白符、制表符和换行符均视为空格,用来分隔单词)
b. 滤掉注释。(其中注释包括两种形式:/…/和//)
c. 遇到非法单词时可显示“Error”,然后跳过错误部分继续显示
d. 将识别出来的合法单词分为以下五大类,依次输出各个单词的内部编码(编码为1—5,如下)及单词符号自身值。
- 关键字
- 标识符
- 常数:包括整数和实数(包括十进制小数形式,如1.23和指数形式如1.2e5或1.2E5)
- 运算符:如= + - * / < <= > >= == != 等符号
- 分隔符:; { } 等符号
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yywrap();
int lineno=1;
%}
delim [ \t]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
integer [+-]?{digit}+
decimal [+-]?{integer}"\."{integer}
sciencenumber ({integer}|{decimal})[eE]{integer}
number ({integer}|{decimal}|{sciencenumber})
error_id (({digit})+({letter})+|"\."(\.)*{integer}|{integer}"\."(\.|{integer})*)
enter [ \n]
spchar ("{"|"}"|"["|"]"|"("|")"|";"|","|"'"|":")
ariop ("+"|"-"|"*"|"/")
relop ("<"|"<="|">"|">="|"=="|"!="|"=")
comment_1 \/\*(\*[^/]|[^*])*\*\/
comment_2 \/\/([^\n])*[\n]
reswd (auto|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|extern|return|union|const|float|short|unsigned|continue|for|signed|void|default|goto|sizeof|volatile|do|if|while|static)
%%
{ws} {}
{comment_1} {}
{comment_2} {}
{enter} {lineno++;}
{reswd} {fprintf(yyout,"1, %s\n",yytext);}
{spchar} {fprintf(yyout,"5, %s\n",yytext);}
{id} {fprintf(yyout,"2, %s\n",yytext);}
{number} {fprintf(yyout,"3, %s\n",yytext);}
{error_id} {fprintf(yyout,"error, %s\n",yytext);}
{ariop} {fprintf(yyout,"4, %s\n",yytext);}
{relop} {fprintf(yyout,"4, %s\n",yytext);}
%%
int yywrap() {return 1;}
int main(void)
{
char infilename[100];
printf("input filename:");
scanf("%s",infilename);
yyin = fopen(infilename,"r");
yyout = fopen("result.txt","w");
yylex();
return 0;
}