【编译原理】lex写简单的词法分析程序


实验要求

读懂exam1.l和exam2.l两个例子,使用flex工具将exam1.l和exam2.l编译并调试通过。并且修改exam2.l,在其基础上增加如下记号:
左右大小括号:{ } ( )
将关系算符改写成C中的形式
分号、赋值号:; =
关键字:if else
双斜线表示的注释://
算术运算符号:+ - * /
将标识符改为可含有下划线,并且可以以下划线开头
将注释内容忽略

核心代码

%{

#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 ID          		20
#define NUMBER      		21
#define RELOP       		22

#define NEWLINE     		23
#define ERRORCHAR   		24

#define LEFTPARENTHESIS		25	/*小括号*/
#define RIGHTPARENTHESIS	26	/*小括号*/
#define LEFTBRACE			27	/*大括号*/
#define RIGHTBRACE			28	/*大括号*/
#define SEMICOLON			29	/*分号*/
#define ASSIGNMENT			30	/*赋值号*/
#define IF					31	
#define ELSE				32	
#define ARITHMETIC			33	/*算术运算*/
#define STRING				34	/*字符串*/

%}

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

/*匹配的字符:非特况;是特况?是\,是转义*/

/* 状态(或条件)定义可以定义在这里 
 * INITIAL是一个默认的状态,不需要定义
 */
%s COMMENT
%s LINECOMMENT

%%

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


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

<INITIAL>{string}	      { return (STRING);}
<INITIAL>{ws}	          {;}
<INITIAL>while					{ return (WHILE);}
<INITIAL>do		          { return (DO);}
<INITIAL>if	          { return (IF);}
<INITIAL>else	          { return (ELSE);}
<INITIAL>{id}	          { return (ID);}
<INITIAL>{number}	      { return (NUMBER);}
<INITIAL>"<"	          { return (RELOP);}
<INITIAL>"<="	          { return (RELOP);}
<INITIAL>"=="	          { return (RELOP);}
<INITIAL>"!="	          { return (RELOP);}
<INITIAL>">"	          { return (RELOP);}
<INITIAL>">="	          { return (RELOP);}
<INITIAL>"("	          { return (LEFTPARENTHESIS);}
<INITIAL>")"	          { return (RIGHTPARENTHESIS);}
<INITIAL>"{"	          { return (LEFTBRACE);}
<INITIAL>"}"	          { return (RIGHTBRACE);}
<INITIAL>";"	          { return (SEMICOLON);}
<INITIAL>"="	          { return (ASSIGNMENT);}
<INITIAL>"+"|"-"|"*"|"/"  { return (ARITHMETIC);}

<INITIAL>.							{ return ERRORCHAR;}

 
%%

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 NUMBER: fprintf(yyout, "(NUM, \"%s\") ", yytext);break;
    case ID: fprintf(yyout, "(ID, \"%s\") ", yytext);break;
    case NEWLINE: fprintf(yyout, "\n");break;

	case LEFTPARENTHESIS: fprintf(yyout, "(LEFTPARENTHESIS, \"%s\") ", yytext);break;
	case RIGHTPARENTHESIS: fprintf(yyout, "(RIGHTPARENTHESIS, \"%s\") ", yytext);break;
	case LEFTBRACE: fprintf(yyout, "(LEFTBRACE, \"%s\") ", yytext);break;
	case RIGHTBRACE: fprintf(yyout, "(RIGHTBRACE, \"%s\") ", yytext);break;
	case SEMICOLON: fprintf(yyout, "(SEMICOLON, \"%s\") ", yytext);break;
	case ASSIGNMENT: fprintf(yyout, "(ASSIGNMENT, \"%s\") ", yytext);break;
	case IF: fprintf(yyout, "(IF, \"%s\") ", yytext);break;
	case ELSE: fprintf(yyout, "(ELSE, \"%s\") ", yytext);break;
	case ARITHMETIC: fprintf(yyout, "(ARITHMETIC, \"%s\") ", yytext);break;
	case STRING: fprintf(yyout, "(STRING, %s) ", yytext);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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

in&de

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值