/* 把讨厌的注释去掉 */

%{ #include <stdio.h>

#define LT 1 #define LE 2 #define GT 3 #define GE 4 #define EQ 5 #define NE 6

#define WHILE 18 #define DO 19

#define IF 20 #define ELSE 21

#define ID 22 #define NUMBER 23 #define RELOP 24

#define LEFTSMALL 25 #define RIGHTSMALL 26 #define LEFTBIG 27 #define RIGHTBIG 28 #define SEICOLON 29 #define EQUALS 30 #define OPERATOR 31 #define SEMICOLON 32 #define STRING 33

#define NEWLINE 35 #define ERRORCHAR 36

%}

base \[A-Za-z0-9\"'] strings "({base}|[^\\n"'])" underline [_] delim [ \t \n] ws {delim}+ letter [A-Za-z] digit [0-9] id ({underline}|{letter})({underline}|{letter})({letter}|{digit})* number {digit}+(.{digit}+)?(E[+-]?{digit}+)?

/* 状态(或条件)定义可以定义在这里

  • INITIAL是一个默认的状态,不需要定义 */ %s COMMENT %s LINE_COMMENT

%%

"/" { BEGIN COMMENT; } "/" { BEGIN INITIAL; } "//" { BEGIN COMMENT; } <LINE_COMMENT>\n { BEGIN LINE_COMMENT; } .|\n {}

/* ECHO是一个宏,相当于 fprintf(yyout, "%s", yytext)*/

{ws} {;} while { return (WHILE);} do { return (DO);} "if" { return (IF);} "else" { return (ELSE);} {strings} { return (STRING);} {id} { return (ID);} {number} { return (NUMBER);} "<" { return (RELOP);} "<=" { return (RELOP);} "<>" { return (RELOP);} ">" { return (RELOP);} ">=" { return (RELOP);} "(" { return (LEFTSMALL);} ")" { return (RIGHTSMALL);} "{" { return (LEFTBIG);} "}" { return (RIGHTBIG);} "+"|"-"|"*"|"/" { return (OPERATOR);} ";" { return (SEMICOLON);} "=" { return (EQUALS);}

. { fprintf(yyout, "(ERRORCHAR, "%s") ", yytext); }

\n { fprintf(yyout, "(NEWLINE, "\n") "); }

%%

int yywrap (){ return 1; }

/* 写入词法单元到输出文件 */ void writeout(int c){ switch(c){ case ERRORCHAR: fprintf(yyout, "(ERRORCHAR, "%s") ", yytext);break; case RELOP: fprintf(yyout, "(RELOP, "%s") ", yytext);break;
case WHILE: fprintf(yyout, "(WHILE, "%s") ", yytext);break; case DO: fprintf(yyout, "(DO, "%s") ", yytext);break; case IF: fprintf(yyout, "(IF, "%s") ", yytext);break; case ELSE: fprintf(yyout, "(ELSE, "%s") ", yytext);break; case NUMBER: fprintf(yyout, "(NUM, "%s") ", yytext);break; case ID: fprintf(yyout, "(ID, "%s") ", yytext);break; case LEFTSMALL: fprintf(yyout, "(LEFTSMALL, "%s") ", yytext);break; case RIGHTSMALL: fprintf(yyout, "(RIGHTSMALL, "%s") ", yytext);break; case LEFTBIG: fprintf(yyout, "(LEFTBIG, "%s") ", yytext);break; case RIGHTBIG: fprintf(yyout, "(RIGHTBIG, "%s") ", yytext);break; case OPERATOR: fprintf(yyout, "(OPERATOR, "%s") ", yytext);break; case EQUALS: fprintf(yyout, "(EQUALS, "%s") ", yytext);break; case SEMICOLON: fprintf(yyout, "(SEMICOLON, "%s") ", yytext);break; case STRING: fprintf(yyout, "(STRING, "%s") ", yytext);break; case NEWLINE: fprintf(yyout, "(NEWLINE, "\n") ");break; default:break; } return; }

int main (int argc, char ** argv){ int c,j=0; if (argc>=2){ if ((yyin = fopen(argv[1], "r")) == NULL){ printf("Can't open file %s\n", argv[1]); return 1; } if (argc>=3){ yyout=fopen(argv[2], "w"); } }

while (c = yylex()){
    writeout(c);
    j++;
    if (j%5 == 0) writeout(NEWLINE);
}
if (argc>=2){
    fclose(yyin);
    if (argc>=3) fclose(yyout);
}
return 0;
实验目的:熟悉实验环境学习使用lex写简单的词法分析程序会在实验环境下使用flex调试lex写的程序。实验内容:在实验1所改写的程序的基础上增加识别string记号。string是字符串如果出现在字符串中则必须转义写成形式;如果出现在字符串中也必须转义写成形式。实验要求:在实验环境下用flex和gcc工具将实验调试通过并测试其正确性。同时该实验必须满足如下要求:1	string是字符串它是以双引号

原文地址: https://www.cveoy.top/t/topic/cHTV 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录