精华内容
下载资源
问答
  • Lex词法分析器

    千次阅读 2017-11-14 21:31:11
    Lex词法分析器一.设计内容 熟悉并实现一个简单的词法分析器 二.设计目的 了解高级语言单词的分类,了解如何识别单词规则,掌握状态图到识别程序的编程。 源程序中,存在许多编辑用的符号,他们对程序逻辑功能无...

    Lex词法分析器

    一.设计内容

    熟悉并实现一个简单的词法分析器

    二.设计目的

    了解高级语言单词的分类,了解如何识别单词规则,掌握状态图到识别程序的编程。
    源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。

    三.实验步骤

    Lex输入文件由3个部分组成:

    定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。

    这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下 :

    {definitions}
    %%
    {rules}
    %%
    {auxiliary routines}

    将每个单词符号进行不同类别的划分。单词符号可以划分成5种:

    1. 标识符:用户自己定义的名字,常量名,变量名和过程名。
    2. 常数:各种类型的常数。
    3. 保留字(关键字):如if、begin、then、while、do等。
    4. 运算符:如+、-、*、<、>、=等。
    5. 界符:如逗号、分号、括号等。

    将各类单词对应到lex中:

    词法分析器所输出单词符号常常表示成单词种别,单词符号的属性值的二元式:

    单词种别通常用整数编码。标识符一般统归为一种。常数则宜按类型(整、实、布尔等)分种。关键字可将其全体视为一种。运算符可采用一符一种的方法。界符一般用一符一种的方法。对于每个单词符号,除了给出了种别编码之外,还应给出有关单词符号的属性信息。单词符号的属性是指单词符号的特性或特征。

    1. 保留字:

    定义识别保留字规则

    reserved_word [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln]

    由于在lex中不区分大小写,所以将保留字写成:

    reserved_word [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|
    [bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]
    [lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]
    [wW][rR][iI][tT][eE][lL][nN]

    1. 常数:

    digit ([0-9])+

    1. 标识符:

    letter [A-Za-z] ([A-Za-z][0-9])*

    1. 运算符:

    operator +|-|*|\/|:=|>=|<=|#|= /在lex中,有特殊意义的运算符要加转义字符\,如+、及*、/

    1. 分界符:

    delimiter [,.;]

    词法分析器要求跳过分隔符(如空格,回车,制表符)

    delim [“”\n\t]
    whitespace{delim}+

    为lex制定一些规则,统计给出程序的词法分析:

    {reserved_word}{line_num++;printf(“\t%d\t(1,‘%s’)\n”,line_num,yytext);}
    {operator} {line_num++;printf(“\t%d\t(2,‘%s’)\n”line_num,yytext); }
    {delimiter}{line_num++;printf(“\t%d\t(3,‘%s’)\n”,line_num,yytext);}
    {digit}{line_num++;printf(“\t%d\t(4,‘%s’)\n”,line_num,yytext);}
    {letter}{line_num++;printf(“\t%d\t(5,‘%s’)\n”,line_num,yytext);}
    {whitespace} {/* do nothing*/ }

    子程序:

    void main() {
      printf("THE LEXICAL ANALYSIS GENERATOR LEX:\n");
      printf("1:reserved_word\n");
      printf("2:oprator\n");
      printf("3:delimiter\n");
      printf("4:digit\n");
      printf("5:leter\n");
      printf("\n");
      yyin=fopen("example.txt","r"); 
      yylex(); /* start the analysis*/ 
      fclose(yyin);
      system("PAUSE");
    }

    example.txt为测试的程序片段
    当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了。
    用lex编译工具编译源程序a.l,然后生成了lex.yy.c文件,然后在有程序片的目录下编译运行该.c文件,读取example.txt,查看输出的结果既可看到分析的结果。

    测试程序example.txt:

    def ChangeInt( a ):
        a = 10
    b = 2
    ChangeInt(b)
    print b

    源程序a.l:

    %{
      #include <stdio.h>
      #include <stdlib.h> 
      int count = 0;
    %} 
    
    delim [" "\n\t] 
    whitespace {delim}+ 
    operator \+|-|\*|\/|:=|>=|<=|#|=
    reserved_word [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN]
    delimiter [,\.;\(\)]
    digit ([0-9])+
    letter [A-Za-z]([A-Za-z][0-9])*
    %% 
    /*line_num is line number*/
    {reserved_word} {line_num++;printf("%d\t(1,‘%s’)\n",line_num,yytext);}
    {operator} {line_num++;printf("%d\t(2,‘%s’)\n",line_num,yytext); }
    {delimiter} {line_num++;printf("%d\t(3,‘%s’)\n",line_num,yytext);}
    {digit} {line_num++;printf("%d\t(4,‘%s’)\n",line_num,yytext);}
    {letter} {line_num++;printf("%d\t(5,‘%s’)\n",line_num,yytext);} 
    /*ignore whitespace*/
    {whitespace} { /* do    nothing*/ } 
    
    %% 
    void main() {
      printf("THE LEXICAL ANALYSIS GENERATOR LEX:\n");
      printf("1:reserved_word\n");
      printf("2:oprator\n");
      printf("3:delimiter\n");
      printf("4:digit\n");
      printf("5:leter\n");
      printf("\n");
      yyin=fopen("test.txt","r"); 
      yylex(); /* start the analysis*/ 
      fclose(yyin);
      system("PAUSE");
    }
    int yywrap() 
    { 
      return 1; 
    } 

    测试结果:

    这里写图片描述

    展开全文
  • Lex词法分析器.rar

    2020-07-09 17:28:49
    LEX实现一个C语言子集的词法分析器,该词法分析器读入一个C语言的源程序,完成有以下功能。  滤掉空格。(其中空白符、制表符和换行符均视为空格,用来分隔单词)  滤掉注释。(其中注释包括两种形式:/*…*/和/...
  • 一个简单的词法分析器例子,运用lex编程实现将一段C语言程序转换为词法单元识别。
  • 【编译原理】Lex词法分析器

    千次阅读 2013-12-20 16:55:36
    设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。   二、实验内容 通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。 要求分析一下...

    一、实验目的

    设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。

     

    二、实验内容

    通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。

    要求分析一下程序片段:

    [delphi] view plaincopy在CODE上查看代码片派生到我的代码片
    1. const a=10;  
    2. var b,c;  
    3. procedure p;  
    4.   begin  
    5.     c:=b+a;  
    6.   end;  
    7.   
    8. begin  
    9.  read(b);  
    10.  while b#0 do  
    11.   begin  
    12.    call p;writeln(2*c);read(b);  
    13.   end  
    14. end.  

    该程序片段存放在example.txt中。


    三、实验步骤

     1、对PL\0文法中各类单词分类:

      (1)保留字:const、var、procedure、begin、end、if、then、while、do、read、call、write、writeln

      (2)常数:由0-----9这几个数字组成

      (3)标识符:由字母打头的字母和数字的字符串

      (4)运算符:+,-,*,/,:=,>=,<=,#

      (5)分界符:,、.、(、)、;

      2、将各类单词对应到lex中:

      (1)保留字:

    reservedWord [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln],由于在lex中不区分大小写,所以将保留字写成:

    reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|

    [bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]

    [lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]

    [wW][rR][iI][tT][eE][lL][nN]

      (2)常数:

    constant ([0-9])+  /*0---9这几个数字可以重复*/

      (3)标识符:

          identfier [A-Za-z]([A-Za-z][0-9])*

      (4)运算符:

          operator \+|-|\*|\/|:=|>=|<=|#|=  /*在lex中,有特殊意义的运算符要加转义字符\,如+、*及*、/

      (5)分界符:

          delimiter [,\.;\(\)]

      3、PL/0的语言的词法分析器要求跳过分隔符(如空格,回车,制表符),对应的lex定义为:

         delim [""\n\t]

    whitespace{delim}+

      4、为lex制定一些规则:

         {reservedWord}{count++;printf("\t%d\t(1,‘%s’)\n",count,yytext);}   /*对保留字定规则,输出设置*/

         {operator} {count++;printf("\t%d\t(2,‘%s’)\n",count,yytext); }

         {delimiter}{count++;printf("\t%d\t(3,‘%s’)\n",count,yytext);}

    {constant}{count++;printf("\t%d\t(4,‘%s’)\n",count,yytext);}

    {identfier}{count++;printf("\t%d\t(5,‘%s’)\n",count,yytext);}

    {whitespace} {/* do    nothing*/ }         /*遇到空格,什么都不做*/

      5、写子程序:

       voidmain()

    {

       printf("词法分析器输出类型说明:\n");

             printf("1:保留字\n");

             printf("2:运算符\n");

             printf("3:分界符\n");

             printf("4:常  数\n");

             printf("5:标识符\n");

             printf("\n");

             yyin=fopen("example.txt","r");

                 yylex(); /* start the analysis*/

             fclose(yyin);

             system("PAUSE");/*暂停*/

    }

     intyywrap()

     {

            return 1;

    }

    当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了,否则,返回 0。


    四、实现的源代码

    1. %{  
    2.     #include <stdio.h>  
    3.     #include <stdlib.h>   
    4.     int count = 0;  
    5. %}   
    6.   
    7. delim [" "\n\t]   
    8. whitespace {delim}+   
    9. operator \+|-|\*|\/|:=|>=|<=|#|=  
    10. reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN]  
    11. delimiter [,\.;\(\)]  
    12. constant ([0-9])+  
    13. identfier [A-Za-z]([A-Za-z][0-9])*  
    14. %%   
    15. {reservedWord} {count++;printf("%d\t(1,‘%s’)\n",count,yytext);}  
    16. {operator} { count++;printf("%d\t(2,‘%s’)\n",count,yytext); }  
    17. {delimiter} {count++;printf("%d\t(3,‘%s’)\n",count,yytext);}  
    18. {constant} {count++;printf("%d\t(4,‘%s’)\n",count,yytext);}  
    19. {identfier} {count++;printf("%d\t(5,‘%s’)\n",count,yytext);}   
    20. {whitespace} { /* do    nothing*/ }   
    21.   
    22. %%   
    23. void main()   
    24. {  
    25.     printf("词法分析器输出类型说明:\n");  
    26.     printf("1:保留字\n");  
    27.     printf("2:运算符\n");  
    28.     printf("3:分界符\n");  
    29.     printf("4:常  数\n");  
    30.     printf("5:标识符\n");  
    31.     printf("\n");  
    32.     yyin=fopen("example.txt","r");   
    33.         yylex(); /* start the analysis*/   
    34.     fclose(yyin);  
    35.     system("PAUSE");/*暂停停,  使DOS窗口停住*/  
    36. }   
    37.  int yywrap()   
    38.  {   
    39.     return 1;   
    40.  }   

    五、实操作

    将源代码存储为a.l,然后用flex(Lex)进行编译,输入flex a.l,编译后生成lex.yy.c文件,用c编译器打开(确保example.txt存储在相同目录下),编译运行即可!


    六、运行结果


    Lex与yacc确实是很不错的工具!如果单用编程语言,如C,C++,Java写的话,代码就多了不少。


    展开全文
  • 编译原理----Lex词法分析器

    万次阅读 2012-12-08 21:27:51
    设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。   二、实验内容 通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。 要求分析一下程序片段: ...

    一、实验目的

    设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。

     

    二、实验内容

    通过使用自己熟悉的语言设计并实现一个词法分析器,是此法分析器按要求的格式输出经过分析的程序段。

    要求分析一下程序片段:

    const a=10;
    var b,c;
    procedure p;
      begin
        c:=b+a;
      end;
    
    begin
     read(b);
     while b#0 do
      begin
       call p;writeln(2*c);read(b);
      end
    end.

    该程序片段存放在example.txt中。


    三、实验步骤

     1、对PL\0文法中各类单词分类:

      (1)保留字:const、var、procedure、begin、end、if、then、while、do、read、call、write、writeln

      (2)常数:由0-----9这几个数字组成

      (3)标识符:由字母打头的字母和数字的字符串

      (4)运算符:+,-,*,/,:=,>=,<=,#

      (5)分界符:,、.、(、)、;

      2、将各类单词对应到lex中:

      (1)保留字:

    reservedWord [const|var|procedure|begin|end|if|then|while|do|read|call|write|writeln],由于在lex中不区分大小写,所以将保留字写成:

    reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|

    [bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI]

    [lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]

    [wW][rR][iI][tT][eE][lL][nN]

      (2)常数:

    constant ([0-9])+  /*0---9这几个数字可以重复*/

      (3)标识符:

          identfier [A-Za-z]([A-Za-z][0-9])*

      (4)运算符:

          operator \+|-|\*|\/|:=|>=|<=|#|=  /*在lex中,有特殊意义的运算符要加转义字符\,如+、*及*、/

      (5)分界符:

          delimiter [,\.;\(\)]

      3、PL/0的语言的词法分析器要求跳过分隔符(如空格,回车,制表符),对应的lex定义为:

         delim [""\n\t]

    whitespace{delim}+

      4、为lex制定一些规则:

         {reservedWord}{count++;printf("\t%d\t(1,‘%s’)\n",count,yytext);}   /*对保留字定规则,输出设置*/

         {operator} {count++;printf("\t%d\t(2,‘%s’)\n",count,yytext); }

         {delimiter}{count++;printf("\t%d\t(3,‘%s’)\n",count,yytext);}

    {constant}{count++;printf("\t%d\t(4,‘%s’)\n",count,yytext);}

    {identfier}{count++;printf("\t%d\t(5,‘%s’)\n",count,yytext);}

    {whitespace} {/* do    nothing*/ }         /*遇到空格,什么都不做*/

      5、写子程序:

       voidmain()

    {

       printf("词法分析器输出类型说明:\n");

             printf("1:保留字\n");

             printf("2:运算符\n");

             printf("3:分界符\n");

             printf("4:常  数\n");

             printf("5:标识符\n");

             printf("\n");

             yyin=fopen("example.txt","r");

                 yylex(); /* start the analysis*/

             fclose(yyin);

             system("PAUSE");/*暂停*/

    }

     intyywrap()

     {

            return 1;

    }

    当lex 读完输入文件之后就会调用函数 yywrap 。如果返回1 表示程序的工作已经完成了,否则,返回 0。


    四、实现的源代码

    %{
    	#include <stdio.h>
    	#include <stdlib.h> 
    	int count = 0;
    %} 
    
    delim [" "\n\t] 
    whitespace {delim}+ 
    operator \+|-|\*|\/|:=|>=|<=|#|=
    reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN]
    delimiter [,\.;\(\)]
    constant ([0-9])+
    identfier [A-Za-z]([A-Za-z][0-9])*
    %% 
    {reservedWord} {count++;printf("%d\t(1,‘%s’)\n",count,yytext);}
    {operator} { count++;printf("%d\t(2,‘%s’)\n",count,yytext); }
    {delimiter} {count++;printf("%d\t(3,‘%s’)\n",count,yytext);}
    {constant} {count++;printf("%d\t(4,‘%s’)\n",count,yytext);}
    {identfier} {count++;printf("%d\t(5,‘%s’)\n",count,yytext);} 
    {whitespace} { /* do    nothing*/ } 
    
    %% 
    void main() 
    {
        printf("词法分析器输出类型说明:\n");
    	printf("1:保留字\n");
    	printf("2:运算符\n");
    	printf("3:分界符\n");
    	printf("4:常  数\n");
    	printf("5:标识符\n");
    	printf("\n");
    	yyin=fopen("example.txt","r"); 
        	yylex(); /* start the analysis*/ 
    	fclose(yyin);
    	system("PAUSE");/*暂停停,  使DOS窗口停住*/
    } 
     int yywrap() 
     { 
     	return 1; 
     } 

    五、实操作

    将源代码存储为a.l,然后用flex(Lex)进行编译,输入flex a.l,编译后生成lex.yy.c文件,用c编译器打开(确保example.txt存储在相同目录下),编译运行即可!


    六、运行结果


    Lex与yacc确实是很不错的工具!如果单用编程语言,如C,C++,Java写的话,代码就多了不少。




    展开全文
  • Fast Lex词法分析工具

    热门讨论 2008-08-19 14:20:56
    Lex是一个基于正则表达式的描述词法分析器的工具,已经广泛用于产生各种语言的词法分析器,也称为Lex编译器。它的输入使用Lex语言编写的源程序,在Lex源程序中,要将基于正则表达式的模式说明与词法分析器要完成的...
  • 基于lex词法分析器

    2012-07-14 10:25:14
    编译原理课程设计 运用c语言 外加lex进行词法分析
  • LEX/FLEX词法分析器

    万次阅读 多人点赞 2015-09-22 01:14:07
    LEX/FLEX词法分析器CONTENTS:LEXFLEX词法分析器 LexFlex词法分析器 Flex的安装和使用 Lex语法格式 definitions rules user subroutines FLEX实例这篇文章的内容包括: lex语法格式 linux下flex的安装和使用 flex...

    LEX/FLEX词法分析器

    CONTENTS:

    这篇文章的内容包括:

    • lex语法格式

    • linux下flex的安装和使用

    • flex实例

    • flex源代码的编译和使用


    Lex/Flex词法分析器

    Lex是LEXical compiler的缩写,是Unix环境下非常著名的工具,主要功能是生成一个词法分析器(scanner)的C源码,描述规则采用正则表达式(regular expression)。描述词法分析器的文件*.l,经过lex编译后,生成一个lex.yy.c 的文件,然后由C编译器编译生成一个词法分析器。词法分析器,简单来说,其任务就是将输入的各种符号,转化成相应的标识符(token),转化后的标识符 很容易被后续阶段处理。 —— [ 百度百科 ]

    Flex的安装和使用

    在使用apt软件包管理器linux系统上我们可以非常方便地安装并使用flex。在终端中输入以下代码安装flex:(可能需要root权限)

    $> sudo apt-get install flex

    flex代码的源文件往往是以.l为后缀名的。
    .l文件通过以下命令编译(以文件名为scanner.l为例):

    $> flex scanner.l

    编译后在源代码相同目录下会生成一个lex.yy.c,这就是生成的能够执行上述scanner.l功能的c语言代码。使用gcc编译即可生成词法分析程序1

    $> gcc lex.yy.c -o scanner

    然后将需要分析的文件(以input.txt为例)作为参数传递给scanner执行分析:

    $> ./scanner input.txt

    Lex语法格式

    flex的语法被分为三个部分:

    {definitions}
    %%
    {rules}
    %%
    {user subroutines}

    definitions:

    LABEL REGULAR_EXPRESSION

    LABEL是这里类字符串的名称,REGULAR_EXPRESSION则是匹配这种字符串的正则表达式。正则表达式的语法主要包括:

    符号 含义
    |
    [] 括号中的字符取其一
    - a-z表示ascii码中介于a-z包括a.z的字符
    \ 转义(flex不能识别除字母外的字符)
    * 0或多个字符
    ? 0或1个字符
    + 1或多个字符
    ^ 除此之外的其余字符
    . 除\n外的所有字符,等价于^\n

    示例:

    1. INT [1-9][0-9]*|[0]  /*整数类型,0或不以0开头的由0-9组成的字符串*/
    2. FLOAT [0-9]*[.][0-9]+([eE][+-]?[0-9]*|[0])?f?    /*浮点数格式*/
    3. LP \(    /*一个左圆括号*/

    注:用%{ %}括起来的语句将被完全写入编译后的c语言文件中。
    例如
    %{
    #include <stdio.h>
    int num_id = 0;
    %}

    rules:

    规则部分的语法如下:

    {LABEL1} |
    {LABLE2} |
    ...
    { 
    /*TODO*/
    }

    TODO部分是告诉编译器在匹配到字符串之后程序需要做些什么。
    例如在匹配到整数后打印这个整数:

    {INT} {
        printf("Pick up an integer, value is %d", atoi(yytext));
        printf("Pick up an integer, value is %s", yytext);
    }

    其中atoi()函数将字符串转换为整数。

    user subroutines

    此处主要是放置用户需要执行的c语言代码。他们会被原封不动地加入到lex.yy.c文件的末尾。
    这里一般用来存放main函数,详细会在后面说明。

    FLEX实例

    下面通过一个实例来具体展示flex的使用方式,主要功能是扫描并匹配文件中的字符串,并回显其类型和内容,代码如下:

    /************************
     * scanner.l
     * @author mist
     * 2015-9-21 23:08
     ************************/
    %{
    #include "stdio.h"
    #include "stdlib.h"
    %}
    
    INT_DEX [1-9][0-9]*|[0]
    INT_HEX [0][Xx]([1-9][0-9]*|[0])
    INT_OCT [0][0-7]
    FLOAT [0-9]*[.][0-9]+([eE][+-]?[0-9]*|[0])?f?
    SEMI [;]
    COMMA [,]
    ASSIGNOP [=]
    RELOP [>]|[<]|[>][=]|[<][=]|[=][=]|[!][=](^[=])
    PLUS [+]
    MINUS [-]
    STAR [*]
    DIV [/]
    AND [&][&]
    OR [|][|]
    DOT [.]
    NOT [!]
    TYPE int|float
    LP \(
    RP \)
    LB \[
    RB \]
    LC \{
    RC \}
    STRUCT struct
    RETURN return
    IF if
    ELSE else 
    WHILE while
    SPACE [ \n\t]
    ID [a-zA-Z_][a-zA-Z_0-9]*
    /*end of definition*/
    
    %%
    {SEMI} {
        printf("get semmi : %s\n", yytext);
    
    }
    
    {COMMA} {
        printf("get comma : %s\n", yytext);
    }
    {ASSIGNOP} {
        printf("get assignop : %s\n", yytext);
    }
    
    {INT_DEX} |
    {INT_HEX} |
    {INT_OCT} {
        printf("get an integer: %s\n", yytext);
    }
    
    {FLOAT} {
        printf("get a float: %s\n", yytext);
    }
    
    {PLUS} | 
    {MINUS} |
    {DIV} |
    {STAR} {
        printf("get an operator: %s\n", yytext);
    }
    
    {RELOP} {
        printf("get a relop: %s\n", yytext);
    }
    
    {AND} |
    {OR} |
    {NOT} {
        printf("get a logic operator: %s\n", yytext);
    }
    
    {DOT} {
        printf("get a dot: %s\n", yytext);
    }
    {STRUCT} |
    {RETURN} |
    {IF} |
    {ELSE} |
    {WHILE} {
        printf("get keyword: %s\n", yytext);
    }
    
    {TYPE} {
        printf("get type: %s\n", yytext);
    }
    
    {LP} |
    {RP} |
    {LB} |
    {RB} |
    {LC} |
    {RC} {
        printf("get brackets : %s\n", yytext);
    }
    
    {SPACE} |
    . {
    /*ABANDON THESE CHARACTORS*/
    }
    
    {ID} {
        printf("get an ID: %s\n", yytext);
    }
    %%
    int yywrap() {
      return 1;
    }
    
    int main(int argc, char** argv) {
       if (argc > 1) {
           if (!(yyin = fopen(argv[1], "r"))) {   
               perror(argv[1]);
               return 1;
           }
       }
       while (yylex());
       return 0;

    我们需要为生成的分析程序编写main函数。首先需要通过yyin来获取指向被分析文件的文件FILE指针,一般文件的路径通过控制台的第二个参数获得。分析部分的实体在函数yylex()中。
    yywrap()用于判断是否已经扫描完了所有的文件。如果它在最后一个文件的末尾被调用,则返回值为1。此时程序将停止分析,可以用来扫描多个文件。

    输入文本:
    int float {}()[] 0
    0x0 0x123
    123.5
    .3e-10f
    = >= || && ! ; ,
    this_is_an_id
    id123
    if then else

    输出:

    get type: int
    get type: float
    get brackets : {
    get brackets : }
    get brackets : (
    get brackets : )
    get brackets : [
    get brackets : ]
    get an integer: 0
    get an integer: 0x0
    get an integer: 0x123
    get a float: 123.5
    get a float: .3e-10f
    get assignop : =
    get a relop: >=
    get a logic operator: ||
    get a logic operator: &&
    get a logic operator: !
    get semmi : ;
    get comma : ,
    get an ID: this_is_an_id
    get an ID: id123
    get keyword: if
    get an ID: then
    get keyword: else

    另外附上词法要求:
    INT  /* A sequence of digits without spaces1 */
    FLOAT  /* A real number consisting of digits and one decimal point. The deci-
    mal point must be surrounded by at least one digit2 */
    ID  /* A character string consisting of 52 upper- or lower-case alphabetic, 10
    numeric and one underscore characters. Besides, an identifier must not start
    with a digit3 */
    SEMI  ;
    COMMA  ,
    ASSIGNOP  =
    RELOP  > | < | >= | <= | == | !=
    PLUS  +
    MINUS  -
    STAR  *
    DIV  /
    AND  &&
    OR  ||
    DOT  .
    NOT  !
    TYPE  int | float
    LP  (
    RP  )
    LB  [
    RB  ]
    LC  {
    RC  }
    STRUCT  struct
    RETURN  return
    IF  if
    ELSE  else
    WHILE  while

    1) 词法单元INT表示的是所有(无符号)整型常数。一个十进制整数由0~9十个数字组
    成,数字与数字中间没有如空格之类的分隔符。除“0”之外,十进制整数的首位数字
    不为0。例如,下面几个串都表示十进制整数:0、234、10000。为方便起见,你可以
    假设(或者只接受)输入的整数都在32bits位之内。

    2) 整型常数还可以以八进制或十六进制的形式出现。八进制整数由0~7八个数字组成并以
    数字0开头,十六进制整数由0~9、A~F(或a~f)十六个数字组成并以0x或者0X开头。
    例如,0237(表示十进制的159)、0xFF32(表示十进制的65330)。

    3) 词法单元FLOAT表示的是所有(无符号)浮点型常数。一个浮点数由一串数字与一个
    小数点组成,小数点的前后必须有数字出现。例如,下面几个串都是浮点数:0.7、
    12.43、9.00。为方便起见,你可以假设(或者只接受)输入的浮点数都符合IEEE754单
    精度标准(即都可以转换成C语言中的float类型)。

    4) 浮点型常数还可以以指数形式(即科学记数法)表示。指数形式的浮点数必须包括基
    数、指数符号和指数三个部分,且三部分依次出现。基数部分由一串数字(0~9)和一
    个小数点组成,小数点可以出现在数字串的任何位置;指数符号为“E”或“e”;指
    数部分由可带“+”或“”(也可不带)的一串数字(0~9)组成,“+”或“”(如
    果有)必须出现在数字串之前。例如01.23E12(表示1.23  1012)、43.e-4(表示43.0 
    10-4)、.5E03(表示0.5  103)。

    5) 词法单元ID表示的是除去保留字以外的所有标识符。标识符可以由大小写字母、数字
    以及下划线组成,但必须以字母或者下划线开头。为方便起见,你可以假设(或者只
    接受)标识符的长度小于32个字符。

    6) 除了INT、FLOAT和ID这三个词法单元以外,其它产生式中箭头右边都表示具体的字
    符串。例如,产生式TYPE  int | float表示:输入文件中的字符串“int”和“float”都
    将被识别为词法单元TYPE。
    2.2
    High-level Definitions


    1. 生成词法分析程序 可能会发生yywrap未定义的错误。yywrap必须由用户亲自编写,一般按如下形式即可
      void yywrap() { return 1; }
    展开全文
  • 编译原理课程设计:用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析。附加完整实验报告(已排版,可直接打印)
  • 自制Lex-词法分析器生成器(C++)

    万次阅读 2016-10-31 23:03:26
    前一阵子,编译原理课实验内容是要去做一个词法分析器,实现后,觉得没有把正规表达式和NFA、DFA这些知识用上,所以就产生了想自己去实现一个lex的想法,于是就有了这篇博文。 如果还不知道词法分析器该怎么实现...
  • 编译原理课程设计:用高级语言(c++)实现词法分析器、用lex实现词法分析器、LL1实现语法分析。前两个是我自己写的,也测试过,正常;LL1不是我写的,也没经过测试...大家慎重使用LL1
  • Lex:词法分析器的生成器

    千次阅读 2014-06-19 08:50:16
    Lex是一种词法分析器的生成器,
  • 它适合于编辑脚本类型的变换,和为解析例程做准备工作而分解输入。 Lex 源码是正则表达式和相应的程序片段的表格。Lex 把这个表格变换成读取输入流、复制它到输出流、并把输入划分到匹配给定表达式的字符串中的一...
  • 基于LEX的语言词法分析器,包括LEX环境配置,手写版+LEX版,北邮大三编译原理作业。
  • LEX自动生成词法分析器

    千次阅读 2015-11-08 23:34:48
    词法分析器作为编译器的一个重要组成部分,原理很简单,代码也都没什么技术含量,但是如果让你手工写一个词法分析器,哪怕是一个简单的词法分析器,工作量无疑是巨大的。现代的词法分析器一般都是依靠工具自动生成,...
  • 学会用lex设计一个词法分析器,并考虑其与后续语法分析器的链接问题。 实验内容: 修改上次实验2的词法分析器,使其满足下列要求。 实验要求: 要求每次调用词法分析函数yylex时,只返回一个记号(token); 为记号...
  • 学会用lex设计一个词法分析器。 实验内容: 使用lex为下述文法语言写一个词法分析器。 语言文法: <程序> --> PROGRAM <标识符> ; <分程序> <分程序> --> <变量说明> BEGIN <...
  • Yacc 与 Lex-词法分析器工具

    千次阅读 2017-04-24 11:33:36
    1.下载词法分析器工具 http://download.csdn.net/download/pikaxuji/4382949 2.解压后如图所示 先安装flex-2.5.4a-1.exe 再安装第一个文件,安装后会在同一个目录 以我的为例:D:\Mysoft\GnuWin32\GnuWin32 ...
  • 利用LEX实现词法分析器(vs2010 + Parser Generator版) 前言  最近在学习编译原理,需要利用LEX自动生成一个词法分析器。下面把我个人的经验与大家分享一下。  关于词法分析器生成工具LEX简介请大家...
  • lex一个词法分析器的生成器_翻译版,编译原理课程的上机题目
  • 这是一个编译原理lex工具,具备词法分析器的功能,方便了解编译原理词法分析器的功能
  • 词法分析器

    2018-04-22 10:41:42
    lex词法分析器用于消除二义性的两条规则 There are two important disambiguation rules used by Lex and other similar lexical-analyzer generators: Longest match: The longest initial substring of the ...
  • 词法分析器生成工具lex使用 《词法分析器生成工具lex使用》,作者:GOD_YCA,原文链接:http://www.cnblogs.com/GODYCA/archive/2013/01/03/2843096.html 分享自:博客园Android客户端(http:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 499
精华内容 199
关键字:

lex词法分析器