Cygwin环境的熟悉和lex的使用2

10 篇文章 7 订阅
9 篇文章 4 订阅

                   Cygwin环境的熟悉和lex的使用2

一.目的:

      熟悉cygwin环境的使用,学习使用lex写简单的词法分析程序,会在cygwin环境下使用flex调试lex写的程序。

二. 内容:

   在上一篇“Cygwin环境的熟悉和lex的使用1”所改写的程序的基础上增加string记号。string是字符串,如果”出现在字符串中,则必须转义,写成\”形式;如果\出现在字符串中,也必须转义,写成\\形式。

三.要求:

   在cygwin下用flex和gcc工具将实验调试通过,并写出测试例测试正确性。同时该实验必须满足如下要求:

       1. string是字符串,它是以双引号括起的一串字符。

       2. 双引号内的字符可包括:

           除”和\外的所有可打印字符(可打印字符请查ASCII码表)

           空格和制表符。

           转义字符。转义字符至少应该包括:\n,\t,\”,\\,\^c, \ddd,其中c表示任意可打印字符,d表示数字。

       3. 字符串内不可包含换行。

四.源代码:

        2.l:
%{
#include <stdio.h> 
#define LT					1
#define	LE					2
#define GT					3
#define	GE					4
#define	EQ					5
#define NE					6
#define ADD					7
#define JIAN					8
#define CHEN					9
#define CHU					10
#define WHILE				18
#define	DO				19
#define IF				11
#define	ELSE				12
#define STRING      16
#define ID          20
#define NUMBER      21
#define RELOP       22
#define NEWLINE     23
#define ERRORCHAR   24

int yylval;
%}

delim		[ \t \n]
ws			{delim}+
letter	[A-Za-z]
digit		[0-9]
id			(_)*{letter}(_)*({letter}|{digit})*
number	{digit}+(\.{digit}+)?(E[+-]?{digit}+)?
string   \"[^\"]+\"
/* 状态(或条件)定义可以定义在这里 
 * INITIAL是一个默认的状态,不需要定义
 */
%s COMMENT  
%s ZHUSHI
%%

<INITIAL>"/*"						{BEGIN COMMENT;ECHO;}
<COMMENT>"*/"						{BEGIN INITIAL;ECHO;}
<COMMENT>.|\n						{ECHO;}
<INITIAL>"\\"						{BEGIN ZHUSHI;;}
<ZHUSHI>"\t"						{BEGIN INITIAL;;}
<ZHUSHI>.|\n	          {;}
 /* ECHO是一个宏,相当于 fprintf(yyout, "%s", yytext)*/

<INITIAL>{ws}	          {;}
<INITIAL>while					{return (WHILE);}
<INITIAL>if					{return (IF);}
<INITIAL>else					{return (ELSE);}
<INITIAL>do		          {return (DO);}
<INITIAL>{id}	          {yylval = installID ();return (ID);}
<INITIAL>{number}	      {yylval = installNum ();return (NUMBER);}
<INITIAL>{string}	      {yylval = installSTRING ();return (STRING);}
<INITIAL>"<"	          {yylval = LT;return (RELOP);}
<INITIAL>"<="	          {yylval = LE;return (RELOP);}
<INITIAL>"="	          {yylval = EQ;return (RELOP);}
<INITIAL>"!="	          {yylval = NE;return (RELOP);}
<INITIAL>">"	          {yylval = GT;return (RELOP);}
<INITIAL>">="	          {yylval = GE;return (RELOP);}
<INITIAL>"{"	          {return (RELOP);}
<INITIAL>"}"	          {return (RELOP);}
<INITIAL>"("	          {return (RELOP);}
<INITIAL>")"	          {return (RELOP);}
<INITIAL>";"	          {return (RELOP);}
<INITIAL>"+"	          {yylval = ADD;return (RELOP);}
<INITIAL>"-"	          {yylval = JIAN;return (RELOP);}
<INITIAL>"*"	          {yylval = CHEN;return (RELOP);}
<INITIAL>"/"	          {yylval = CHU;return (RELOP);}
<INITIAL>.							{return ERRORCHAR;}
%%

int installID () {
  /* 把词法单元装入符号表并返回指针。*/
	return ID;
}
int installNum () {
	/* 类似上面的过程,但词法单元不是标识符而是数 */
  return NUMBER;
}
int installSTRING () {
	/* 类似上面的过程,但词法单元不是标识符而是数 */
  return STRING;
}
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 STRING: fprintf(yyout, "(STRING, \"%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;
    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;
}

   
  Test.p:

while _a >= -1.2E-2  do b_x<=2  {if(c!=5)c=(d+e)*f; else c=(e-f)/2;} "sfjjjg1323\n" 
/*请注意*/ \\ 请注意:测试文件的格式必须符合要求,比如,该文件要求的格式是UNIX格式。

五.结果及分析:

(WHILE,while),(ID,_a),( RELOP,>=),( NUM,-1.2E-2),(DO,do),(ID,b_x),( RELOP,<=), ( NUM,2), ( RELOP,{), ( RELOP,(), (ID,c), ( RELOP,!=), (NUM,5), ( RELOP,)), (ID,c), ( RELOP,==), ( RELOP,(), (ID,d), ( RELOP,+), (ID,e), ( RELOP,*), ( ID,f), ( RELOP,;), ( ELSE,else), (ID,c), ( RELOP,=), ( RELOP,(), (ID,e), ( RELOP,-), (ID,f), ( RELOP,)), ( RELOP,/), ( NUM,2), ( RELOP,;),  (RELOP,}), (STRING, sfjjjg1323\n),

     词法分析器从第一个字符开始扫描,将相应的字符与匹配的类别输出在屏幕上,忽略空格和换行字符,将注释也忽略,能识别字符串(除”和\外的所有可打印字符,空格和制表符,转义字符【转义字符至少应该包括:\n,\t,\”,\\,\^c, \ddd,其中c表示任意可打印字符,d表示数字】,字符串内不可包含换行)。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值