精华内容
下载资源
问答
  • 2020-06-15 21:04:57

    Lex使用指南

    Lex是由美国Bell实验室M.Lesk等人用C语言开发的一种词法分析器自动生成工具,它提供一种供开发者编写词法规则(正规式等)的语言(Lex语言)以及这种语言的翻译器(这种翻译器将Lex语言编写的规则翻译成为C语言程序)。

    Lex是linux下的工具,本实验使用的编译工具是cygwin(cygwin在windows下模拟一个linux环境)下的flex,它与lex的使用方法基本相同,只有很少的差别。

    一、Lex的基本原理和使用方法

    Lex的基本工作原理为:由正规式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。
    其中正规式由开发者使用Lex语言编写,其余部分由Lex翻译器完成.翻译器将Lex源程序翻译成一个名为lex.yy.c的C语言源文件,此文件含有两部分内容:一部分是根据正规式所构造的DFA状态转移表,另一部分是用来驱动该表的总控程序yylex()。当主程序需要从输入字符流中识别一个记号时,只需要调用一次yylex()就可以了。为了使用Lex所生成的词法分析器,我们需要将lex.yy.c程序用C编译器进行编译,并将相关支持库函数连入目标代码。Lex的使用步骤可如下图所示:

    二、lex源程序的写法:

    Lex源程序必须按照Lex语言的规范来写,其核心是一组词法规则(正规式)。一般而言,一个Lex源程序分为三部分,三部分之间以符号%%分隔。

    [第一部分:定义段]
    %%
    第二部分:词法规则段
    [%%
    第三部分:辅助函数段]

    其中,第一部分及第三部分和第三部分之上的%%都可以省略(即上述方括号括起的部分可以省略)。以%开头的符号和关键字,或者是词法规则段的各个规则一般顶着行首来写,前面没有空格。
    Lex源程序中可以有注释,注释由//括起,但是请注意,注释的行首需要有前导空白。
    1. 第一部分定义段的写法:
    定义段可以分为两部分:
    第一部分以符号%{和%}包裹,里面为以C语法写的一些定义和声明:例如,文件包含,宏定义,常数定义,全局变量及外部变量定义,函数声明等。这一部分被Lex翻译器处理后会全部拷贝到文件lex.yy.c中。注意,特殊括号%{和%}都必须顶着行首写。例如:

    %{
      #define LT 1
      int yylval;
    %}
    

    第二部分是一组正规定义和状态定义。正规定义是为了简化后面的词法规则而给部分正规式定义了名字。每条正规定义也都要顶着行首写。例如下面这组正规定义分别定义了letter,digit和id所表示的正规式:

    letter	[A-Za-z]
    digit		[0-9]
    id		{letter}({letter}|{digit})*
    

    注意:上面正规定义中出现的小括号表示分组,而不是被匹配的字符。而大括号括起的部分表示正规定义名。
    状态定义也叫环境定义,它定义了匹配正规式时所处的状态的名字。状态定义以%s开始,后跟所定义的状态的名字,注意%s也要顶行首写,例如下面一行就定义了一个名为COMMENT的状态和一个名为BAD的状态,状态名之间用空白分隔:

    %s COMMENT BAD
    

    2. 第二部分词法规则段的写法:
    词法规则段列出的是词法分析器需要匹配的正规式,以及匹配该正规式后需要进行的相关动作。其例子如下:

    while	      {return (WHILE);}
    do		      {return (DO);}
    {id}	          {yylval = installID (); return (ID);}
    

    每行都是一条规则,该规则的前一部分是正规式,需要顶行首写,后一部分是匹配该正规式后需要进行的动作,这个动作是用C语法来写的,被包裹在{}之内,被Lex翻译器翻译后会被直接拷贝进lex.yy.c。正规式和语义动作之间要有空白隔开。其中用{}扩住的正规式表示正规定义的名字。
    也可以若干个正规式匹配同一条语义动作,此时正规式之间要用 | 分隔。

    3. 第三部分辅助函数段的写法:
    辅助函数段用C语言语法来写,辅助函数一般是在词法规则段中用到的函数。这一部分一般会被直接拷贝到lex.yy.c中。

    4. Lex源程序中词法规则(即正规式)的相关规定:
    元字符:元字符是lex语言中作特殊用途的一些字符,包括:** + ? | { } [ ] ( ) . ^ $ “ \ - / < >*。

    正文字符:除元字符以外的其他字符,这些字符在正规式中可以被匹配。若单个正文字符c作为正规式,则可与字符c匹配,元字符无法被匹配,如果元字符想要被匹配,则需要通过“转义”的方式,即用” ”包括住元字符,或在元字符前加\。例如”+”和+都表示加号。C语言中的一些转义字符也可以出现在正规式中,例如\t \n \b等。

    部分元字符在lex语言中的特殊含义:

    表示补集:[…]表示补集,即匹配除之后所列字符以外的任何字符。如[0-9]表示匹配除数字字符0-9以外的任意字符。除^ - \以外,任何元字符在方括号内失去其特殊含义。如果要在方括号内表示负号-,则要将其至于方括号内的第一个字符位置或者最后一个字符位置,例如[-+0-9] [+0-9-]都匹配数字及+ - 号。

    . ^ $ /:
    点运算符 . 匹配除换行之外的任何字符,一般可作为最后一条翻译规则。
    ^ 匹配行首字符。如:^begin匹配出现在行首的begin
    $ 匹配行末字符。如:end$ 匹配出现在行末的end
    R1/R2(R1和R2是正规式)表示超前搜索:若要匹配R1,则必须先看紧跟其后的超前搜索部分是否与R2匹配。
    如:DO/{alnum}={alnum},表示如果想匹配DO,则必须先在DO后面找到形式为{alnum}*={alnum}*的串,才能确定匹配DO。

    5. Lex源程序中常用到的变量及函数:
    yyin和yyout:这是Lex中本身已定义的输入和输出文件指针。这两个变量指明了lex生成的词法分析器从哪里获得输入和输出到哪里。默认:键盘输入,屏幕输出。

    yytext和yyleng:这也是lex中已定义的变量,直接用就可以了。
    yytext:指向当前识别的词法单元(词文)的指针
    yyleng:当前词法单元的长度。

    ECHO:Lex中预定义的宏,可以出现在动作中,相当于fprintf(yyout, “%s”,yytext),即输出当前匹配的词法单元。

    yylex():词法分析器驱动程序,用Lex翻译器生成的lex.yy.c内必然含有这个函数。

    yywrap():词法分析器遇到文件结尾时会调用yywrap()来决定下一步怎么做:
    若yywrap()返回0,则继续扫描
    若返回1,则返回报告文件结尾的0标记。
    由于词法分析器总会调用yywrap,因此辅助函数中最好提供yywrap,如果不提供,则在用C编译器编译lex.yy.c时,需要链接相应的库,库中会给出标准的yywrap函数(标准函数返回1)。

    6. 词法分析器的状态(环境):
    词法分析器在匹配正规式时,可以在不同状态(或环境)下进行。我们可以规定在不同的状态下有不同的匹配方式。每个词法分析器都至少有一个状态,这个状态叫做初始状态,可以用INITIAL或0来表示,如果还需要使用其他状态,可以在定义段用%s 来定义。
    使用状态时,可以用如下方式写词法规则:

    <state1, state2> p0   {action0;}
    <state1> p1         {action1;}
    

    这两行词法规则表示:在状态state1和state2下,匹配正规式p0后执行动作action0,而只有在状态state1下,才可以匹配正规式p1后执行动作action1。如果不指明状态,默认情况下处于初始状态INITIAL。
    要想进入某个特定状态,可以在动作中写上这样一句: BEGIN state; 执行这个动作后,就进入状态state。
    下面是一段处理C语言注释的例子,里面用到了状态的转换,在这个例子里,使用不同的状态,可以让词法分析器在处于注释中和处于注释外时使用不同的匹配规则:

    …
    %s c_comment
    …
    %%
    <INITIAL>“/*”     {BEGIN c_comment;}
    …
    <c_comment>“*/”   {BEGIN 0;}
    <c_comment>.      {;}
    

    7. Lex的匹配策略:

    1. 按最长匹配原则确定被选中的单词
    2. 如果一个字符串能被若干正规式匹配,则先匹配排在前面的正规式。

    三、Lex生成的词法分析器如何使用:
    lex常常与语法分析器的生成工具yacc(第三章会讲到)同时使用。此时,一般来说,语法分析器每次都调用一次yylex()获取一个记号。如果想自己写一个程序使用lex生成的词法分析器,则只需要在自己的程序中按需要调用yylex()函数即可。
    请注意:yylex()调用结束后,输入缓冲区并不会被重置,而是仍然停留在刚才读到的地方。并且,词法分析器当前所处的状态(%s定义的那些状态)也不会改变。

    完整的Lex源程序例子请见exam1.l和exam2.l。

    四、cygwin下编译连接lex源程序的命令:

    1. 用lex翻译器编译lex源程序命令(假设filename.l是lex源程序名): flex filename.l
    2. 用gcc编译器编译lex翻译器生成的c源程序(lex翻译器生成的c源程序名固定为lex.yy.c): gcc [-o outfile] lex.yy.c –lfl
      其中,-lfl是链接flex的库函数的,库函数中可能包含类似yywrap一类的标准函数。-o outfile是可选编译选项,该选项可将编译生成的可执行程序命名为outfile,如果不写该编译选项,默认情况下生成的可执行程序名为a.exe(linux下实际为a.out)。
    3. 调用词法分析器yylex()的main函数可以写在lex源程序的辅助函数部分,也可以写在其他的c文件中。如果main函数写在main.c中,则编译时需要和lex.yy.c一起编译链接,即编译链接命令为:gcc [-o outfile] lex.yy.c main.c –lfl
    4. 运行可执行文件a.exe的命令(假设a.exe处于当前目录下,且忽略运行参数的情况):./a.exe
      其中,./表示当前目录。如果a.exe处于其他路径,则运行时请给出完整路径名。

    五、关于cygwin

    1. 网址:www.cygwin.com 是cygwin的官方网站,可以从上面下载安装cygwin。
    2. 下载和安装:从上述网址下载setup.exe运行,即可选择从网络上安装cygwin,也可选择下载到本地,然后再从本地安装。
      本地安装的过程:
      1) 将setup.exe及安装包下载到本地
      2) 运行setup.exe  选择Install from Local Directory  选一个root directory(例如可以选D:\cygwin,不要选中文路径名) 选一个Local Package Directory(选择存放安装包的那个目录)select packages(其它都可以default, 重要的是选中Devel下的bison,flex,gcc-core,gcc-g++, make,vim)
    3. 使用cygwin:
      安装完成后,检查环境变量中有没有HOME变量,如果有,先将HOME变量改名(方法:右键我的电脑属性高级环境变量,在你自己的用户变量列表中找到HOME变量,改名)。
      运行安装目录(root directory)下的cygwin.bat启动cygwin。第一次运行cygwin会生成home目录,如果home目录创建不成功,则很可能是HOME环境变量的缘故,先将这个变量改名,再运行cygwin.bat。
      第一次运行成功后,所在目录应该是/home/your-user-name,请把你的文件存于该目录下。其中home目录实际上是在你选择的root directory下。

    这里是编译原理老师,提供的版本。本人在进行实验时,没有使用第四个和第五个模块
    由于时间有限,该手册难免疏漏之处,如发现问题,请联系green.lyn@gmail.com指出。{原作者,引用,网上这篇文章已经很多了}
    下一篇,记录我的实验,基于win10下lex的使用

    更多相关内容
  • LEX使用

    千次阅读 2017-02-05 11:31:04
    一、Lex的基本原理和使用方法 Lex的基本工作原理为:由正规式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。 其中正规式由开发者使用Lex语言编写,其余部分由Lex翻译器完成.翻译器将Lex源程序翻译成一...

    一、Lex的基本原理和使用方法

    Lex的基本工作原理为:由正规式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。

    其中正规式由开发者使用Lex语言编写,其余部分由Lex翻译器完成.翻译器将Lex源程序翻译成一个名为lex.yy.c的C语言源文件,此文件含有两部分内容:一部分是根据正规式所构造的DFA状态转移表,另一部分是用来驱动该表的总控程序yylex()。当主程序需要从输入字符流中识别一个记号时,只需要调用一次yylex()就可以了。为了使用Lex所生成的词法分析器,我们需要将lex.yy.c程序用C编译器进行编译,并将相关支持库函数连入目标代码。Lex的使用步骤可如下图所示:


    二、lex源程序的写法:

    Lex源程序必须按照Lex语言的规范来写,其核心是一组词法规则(正规式)。一般而言,一个Lex源程序分为三部分,三部分之间以符号%%分隔。

    [第一部分:定义段]

    %%

    第二部分:词法规则段

    [%%

    第三部分:辅助函数段]

    其中,第一部分及第三部分和第三部分之上的%%都可以省略(即上述方括号括起的部分可以省略)。以%开头的符号和关键字,或者是词法规则段的各个规则一般顶着行首来写,前面没有空格。

    Lex源程序中可以有注释,注释由/*和*/括起,但是请注意,注释的行首需要有前导空白。

    1.   第一部分定义段的写法:

    定义段可以分为两部分:

    第一部分以符号%{和%}包裹,里面为以C语法写的一些定义和声明:例如,文件包含,宏定义,常数定义,全局变量及外部变量定义,函数声明等。这一部分被Lex翻译器处理后会全部拷贝到文件lex.yy.c中。注意,特殊括号%{和%}都必须顶着行首写。例如:

    %{

    #define LT 1

    int yylval;

    %}

    第二部分是一组正规定义和状态定义。正规定义是为了简化后面的词法规则而给部分正规式定义了名字。每条正规定义也都要顶着行首写。例如下面这组正规定义分别定义了letter,digit和id所表示的正规式:

    letter [A-Za-z]

    digit [0-9]

    Id {letter}({letter}|{digit})*

    注意:上面正规定义中出现的小括号表示分组,而不是被匹配的字符。而大括号括起的部分表示正规定义名。

    状态定义也叫环境定义,它定义了匹配正规式时所处的状态的名字。状态定义以%s开始,后跟所定义的状态的名字,注意%s也要顶行首写,例如下面一行就定义了一个名为COMMENT的状态和一个名为BAD的状态,状态名之间用空白分隔:

    %s COMMENT BAD

    2.   第二部分词法规则段的写法:

    词法规则段列出的是词法分析器需要匹配的正规式,以及匹配该正规式后需要进行的相关动作。其例子如下:

    while {return (WHILE);}

    do {return (DO);}

    {id} {yylval = installID (); return (ID);}

    每行都是一条规则,该规则的前一部分是正规式,需要顶行首写,后一部分是匹配该正规式后需要进行的动作,这个动作是用C语法来写的,被包裹在{}之内,被Lex翻译器翻译后会被直接拷贝进lex.yy.c。正规式和语义动作之间要有空白隔开。其中用{}扩住的正规式表示正规定义的名字。

    也可以若干个正规式匹配同一条语义动作,此时正规式之间要用|分隔。

    3.   第三部分辅助函数段的写法:

    辅助函数段用C语言语法来写,辅助函数一般是在词法规则段中用到的函数。这一部分一般会被直接拷贝到lex.yy.c中。

    4.   Lex源程序中词法规则(即正规式)的相关规定:

    元字符:元字符是lex语言中作特殊用途的一些字符,包括:*+?|{}[]().^$“\-/<>。

    正文字符:除元字符以外的其他字符,这些字符在正规式中可以被匹配。若单个正文字符c作为正规式,则可与字符c匹配,元字符无法被匹配,如果元字符想要被匹配,则需要通过“转义”的方式,即用” ”包括住元字符,或在元字符前加\。例如”+”和\+都表示加号。C语言中的一些转义字符也可以出现在正规式中,例如\t\n\b等。

    部分元字符在lex语言中的特殊含义:

    ^表示补集:[^…]表示补集,即匹配除^之后所列字符以外的任何字符。如[^0-9]表示匹配除数字字符0-9以外的任意字符。除^-\以外,任何元字符在方括号内失去其特殊含义。如果要在方括号内表示负号-,则要将其至于方括号内的第一个字符位置或者最后一个字符位置,例如[-+0-9][+0-9-]都匹配数字及+-号。

    .^$/:

    点运算符.匹配除换行之外的任何字符,一般可作为最后一条翻译规则。^匹配行首字符。如:^begin匹配出现在行首的begin$匹配行末字符。如:end$匹配出现在行末的end

    R1/R2(R1和R2是正规式)表示超前搜索:若要匹配R1,则必须先看紧跟其后的超前搜索部分是否与R2匹配。

    如:DO/{alnum}*={alnum}*,表示如果想匹配DO,则必须先在DO后面找到形式为{alnum}*={alnum}*的串,才能确定匹配DO。

    5.   Lex源程序中常用到的变量及函数:

    yyin和yyout:这是Lex中本身已定义的输入和输出文件指针。这两个变量指明了lex生成的词法分析器从哪里获得输入和输出到哪里。默认:键盘输入,屏幕输出。

    yytext和yyleng:这也是lex中已定义的变量,直接用就可以了。yytext:指向当前识别的词法单元(词文)的指针yyleng:当前词法单元的长度。

    ECHO:Lex中预定义的宏,可以出现在动作中,相当于fprintf(yyout,“%s”,yytext),即输出当前匹配的词法单元。

    yylex():词法分析器驱动程序,用Lex翻译器生成的lex.yy.c内必然含有这个函数。

    yywrap():词法分析器遇到文件结尾时会调用yywrap()来决定下一步怎么做:

    若yywrap()返回0,则继续扫描

    若返回1,则返回报告文件结尾的0标记。

    由于词法分析器总会调用yywrap,因此辅助函数中最好提供yywrap,如果不提供,则在用C编译器编译lex.yy.c时,需要链接相应的库,库中会给出标准的yywrap函数(标准函数返回1)。

    6.   词法分析器的状态(环境):

    词法分析器在匹配正规式时,可以在不同状态(或环境)下进行。我们可以规定在不同的状态下有不同的匹配方式。每个词法分析器都至少有一个状态,这个状态叫做初始状态,可以用INITIAL或0来表示,如果还需要使用其他状态,可以在定义段用%s来定义。

    使用状态时,可以用如下方式写词法规则:

    <state1,state2>p0{action0;}

    <state1>p1{action1;}

    这两行词法规则表示:在状态state1和state2下,匹配正规式p0后执行动作action0,而只有在状态state1下,才可以匹配正规式p1后执行动作action1。如果不指明状态,默认情况下处于初始状态INITIAL。

    要想进入某个特定状态,可以在动作中写上这样一句:BEGINstate;执行这个动作后,就进入状态state。

    下面是一段处理C语言注释的例子,里面用到了状态的转换,在这个例子里,使用不同的状态,可以让词法分析器在处于注释中和处于注释外时使用不同的匹配规则:

    %sc_comment

    %%

    <INITIAL>“/*” {BEGIN c_comment;}

    <c_comment>“*/” {BEGIN 0;}

    <c_comment>.  {;}

    7.   Lex的匹配策略:

    1)按最长匹配原则确定被选中的单词;

    2)如果一个字符串能被若干正规式匹配,则先匹配排在前面的正规式。

    三、Lex生成的词法分析器如何使用:

    lex常常与语法分析器的生成工具yacc(第三章会讲到)同时使用。此时,一般来说,语法分析器每次都调用一次yylex()获取一个记号。如果想自己写一个程序使用lex生成的词法分析器,则只需要在自己的程序中按需要调用yylex()函数即可。

    请注意:yylex()调用结束后,输入缓冲区并不会被重置,而是仍然停留在刚才读到的地方。并且,词法分析器当前所处的状态(%s定义的那些状态)也不会改变。

    展开全文
  • Lex使用指南

    万次阅读 多人点赞 2015-12-20 20:21:52
    Lex使用指南

                                          Lex使用指南

          Lex是由美国Bell实验室M.Lesk等人用C语言开发的一种词法分析器自动生成工具,它提供一种供开发者编写词法规则(正规式等)的语言(Lex语言)以及这种语言的翻译器(这种翻译器将Lex语言编写的规则翻译成为C语言程序)。

          Lex是linux下的工具,本实验使用的编译工具是cygwin(cygwin在windows下模拟一个linux环境)下的flex,它与lex的使用方法基本相同,只有很少的差别。

    一、Lex的基本原理和使用方法

           Lex的基本工作原理为:由正规式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。

        其中正规式由开发者使用Lex语言编写,其余部分由Lex翻译器完成.翻译器将Lex源程序翻译成一个名为lex.yy.c的C语言源文件,此文件含有两部分内容:一部分是根据正规式所构造的DFA状态转移表,另一部分是用来驱动该表的总控程序yylex()。当主程序需要从输入字符流中识别一个记号时,只需要调用一次yylex()就可以了。为了使用Lex所生成的词法分析器,我们需要将lex.yy.c程序用C编译器进行编译,并将相关支持库函数连入目标代码。Lex的使用步骤可如下图所示:

        

    二、lex源程序的写法:

          Lex源程序必须按照Lex语言的规范来写,其核心是一组词法规则(正规式)。一般而言,一个Lex源程序分为三部分,三部分之间以符号%%分隔。

      [第一部分:定义段]

       %%

      第二部分:词法规则段

       [%%

       第三部分:辅助函数段]


      其中,第一部分及第三部分和第三部分之上的%%都可以省略(即上述方括号括起的部分可以省略)。以%开头的符号和关键字,或者是词法规则段的各个规则一般顶着行首来写,前面没有空格。

      Lex源程序中可以有注释,注释由/*和*/括起,但是请注意,注释的行首需要有前导空白。

      1. 第一部分定义段的写法:

       定义段可以分为两部分:

       第一部分以符号%{和%}包裹,里面为以C语法写的一些定义和声明:例如,文件包含,宏定义,常数定义,全局变量及外部变量定义,函数声明等。这一部分被Lex翻译器处理后会全部拷贝到文件lex.yy.c中。注意,特殊括号%{和%}都必须顶着行首写。例如:

    %{
     #define LT 1
      intyylval;
    %}

       第二部分是一组正规定义和状态定义。正规定义是为了简化后面的词法规则而给部分正规式定义了名字。每条正规定义也都要顶着行首写。例如下面这组正规定义分别定义了letter,digit和id所表示的正规式:

    letter       [A-Za-z]
    digit        [0-9]
    id           {letter}({letter}|{digit})*

        注意:上面正规定义中出现的小括号表示分组,而不是被匹配的字符。而大括号括起的部分表示正规定义名。

    状态定义也叫环境定义,它定义了匹配正规式时所处的状态的名字。状态定义以%s开始,后跟所定义的状态的名字,注意%s也要顶行首写,例如下面一行就定义了一个名为COMMENT的状态和一个名为BAD的状态,状态名之间用空白分隔:

    %s COMMENT BAD

      2. 第二部分词法规则段的写法:

       词法规则段列出的是词法分析器需要匹配的正规式,以及匹配该正规式后需要进行的相关动作。其例子如下:

    while            {return (WHILE);}
    do                 {return (DO);}
    {id}           {yylval = installID (); return (ID);}

       每行都是一条规则,该规则的前一部分是正规式,需要顶行首写,后一部分是匹配该正规式后需要进行的动作,这个动作是用C语法来写的,被包裹在{}之内,被Lex翻译器翻译后会被直接拷贝进lex.yy.c。正规式和语义动作之间要有空白隔开。其中用{}扩住的正规式表示正规定义的名字。

       也可以若干个正规式匹配同一条语义动作,此时正规式之间要用 | 分隔。

      3. 第三部分辅助函数段的写法:

       辅助函数段用C语言语法来写,辅助函数一般是在词法规则段中用到的函数。这一部分一般会被直接拷贝到lex.yy.c中。

      4. Lex源程序中词法规则(即正规式)的相关规定:

       元字符:元字符是lex语言中作特殊用途的一些字符,包括:* + ? | { } [ ] ( ). ^ $ “ \ - / < >。

       正文字符:除元字符以外的其他字符,这些字符在正规式中可以被匹配。若单个正文字符c作为正规式,则可与字符c匹配,元字符无法被匹配,如果元字符想要被匹配,则需要通过“转义”的方式,即用” ”包括住元字符,或在元字符前加\。例如”+”和\+都表示加号。C语言中的一些转义字符也可以出现在正规式中,例如\t \n \b等。

      部分元字符在lex语言中的特殊含义:

        ^表示补集:[^…]表示补集,即匹配除^之后所列字符以外的任何字符。如[^0-9]表示匹配除数字字符0-9以外的任意字符。除^ - \以外,任何元字符在方括号内失去其特殊含义。如果要在方括号内表示负号-,则要将其至于方括号内的第一个字符位置或者最后一个字符位置,例如[-+0-9][+0-9-]都匹配数字及+ - 号。

       .  ^$ /:

       点运算符 . 匹配除换行之外的任何字符,一般可作为最后一条翻译规则。

       ^匹配行首字符。如:^begin匹配出现在行首的begin

       $匹配行末字符。如:end$ 匹配出现在行末的end

       R1/R2(R1和R2是正规式)表示超前搜索:若要匹配R1,则必须先看紧跟其后的超前搜索部分是否与R2匹配。

       如:DO/{alnum}*={alnum}*,表示如果想匹配DO,则必须先在DO后面找到形式为{alnum}*={alnum}*的串,才能确定匹配DO。

     5. Lex源程序中常用到的变量及函数:

      yyin和yyout:这是Lex中本身已定义的输入和输出文件指针。这两个变量指明了lex生成的词法分析器从哪里获得输入和输出到哪里。默认:键盘输入,屏幕输出。

      yytext和yyleng:这也是lex中已定义的变量,直接用就可以了。

      yytext:指向当前识别的词法单元(词文)的指针

      yyleng:当前词法单元的长度。

      ECHO:Lex中预定义的宏,可以出现在动作中,相当于fprintf(yyout, “%s”,yytext),即输出当前匹配的词法单元。

      yylex():词法分析器驱动程序,用Lex翻译器生成的lex.yy.c内必然含有这个函数。

      yywrap():词法分析器遇到文件结尾时会调用yywrap()来决定下一步怎么做:

      若yywrap()返回0,则继续扫描

      若返回1,则返回报告文件结尾的0标记。

      由于词法分析器总会调用yywrap,因此辅助函数中最好提供yywrap,如果不提供,则在用C编译器编译lex.yy.c时,需要链接相应的库,库中会给出标准的yywrap函数(标准函数返回1)。

      6. 词法分析器的状态(环境):

      词法分析器在匹配正规式时,可以在不同状态(或环境)下进行。我们可以规定在不同的状态下有不同的匹配方式。每个词法分析器都至少有一个状态,这个状态叫做初始状态,可以用INITIAL或0来表示,如果还需要使用其他状态,可以在定义段用%s 来定义。

       使用状态时,可以用如下方式写词法规则:

    <state1, state2> p0   {action0;}
    <state1> p1         {action1;}

        这两行词法规则表示:在状态state1和state2下,匹配正规式p0后执行动作action0,而只有在状态state1下,才可以匹配正规式p1后执行动作action1。如果不指明状态,默认情况下处于初始状态INITIAL。

        要想进入某个特定状态,可以在动作中写上这样一句: BEGINstate; 执行这个动作后,就进入状态state。

        下面是一段处理C语言注释的例子,里面用到了状态的转换,在这个例子里,使用不同的状态,可以让词法分析器在处于注释中和处于注释外时使用不同的匹配规则:

    …
    %s c_comment
    …
    %%
    <INITIAL>“/*”     {BEGIN c_comment;}
    …
    <c_comment>“*/”   {BEGIN 0;}
    <c_comment>.      {;}

     7. Lex的匹配策略:

        (1)  按最长匹配原则确定被选中的单词

        (2)  如果一个字符串能被若干正规式匹配,则先匹配排在前面的正规式。

    三、Lex生成的词法分析器如何使用:

        lex常常与语法分析器的生成工具yacc(第三章会讲到)同时使用。此时,一般来说,语法分析器每次都调用一次       yylex()获取一个记号。如果想自己写一个程序使用lex生成的词法分析器,则只需要在自己的程序中按需要调用yylex()函数即可。

         请注意:yylex()调用结束后,输入缓冲区并不会被重置,而是仍然停留在刚才读到的地方。并且,词法分析器当前所处的状态(%s定义的那些状态)也不会改变。

        完整的Lex源程序例子请见exam1.l和exam2.l。
        exam1.l

    /* 这是注释的形式,与C中的/*...* /注释相同。 */
    /* 第一部分是定义、声明部分。这部分内容可以为空。*/
    
    %{
    
    /* 写在 %{...%}这对特殊括号内的内容会被直接拷贝到C文件中。
     *
     * 这部分通常进行一些头文件声明,变量(全局,外部)、常量
     * 的定义,用C语法。
     *
     * %{和%}两个符号都必须位于行首 
     */
    
    /* 下面定义了需要识别的记号名,如果和yacc联合使用,这些记号名都应该在yacc中定义 */
    #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
    
    int yylval;
    /* yylval 是yacc中定义的变量,用来保存记号的属性值,默认是int类型。 
     * 在用lex实现的词法分析器中可以使用这个变量将记号的属性传递给用
     * yacc实现的语法分析器。
     *
     * 注意:该变量只有在联合使用lex和yacc编写词法和语法分析器时才可在lex
     *       中使用,此时该变量不需要定义即可使用。
     *       单独使用lex时,编译器找不到这个变量。这里定义该变量为了“欺骗”编译器。
     */
     
    
    %}
    
    /* 这里进行正规定义和状态定义。
     * 下面就是正规定义,注意,正规定义和状态定义都要顶着行首写。
     */
     
    delim		[ \t \n]
    /* \用来表示转义,例如\t表示制表符,\n表示换行符。*/
    ws			{delim}+
    letter	[A-Za-z_]
    digit		[0-9]
    id			{letter}({letter}|{digit})*
    /* 注意:上面正规定义中出现的小括号表示分组,而不是被匹配的字符。
     *       而大括号括起的部分表示正规定义名。
     */
    number	{digit}+(\.{digit}+)?(E[+-]?{digit}+)?
    
    
    
    /* %%作为lex文件三个部分的分割符,必须位于行首 */
    /* 下面这个%%不能省略 */
    %%
    
      /* 第二部分是翻译规则部分。 */
      /* 写在这一部分的注释要有前导空格,否则lex编译出错。*/
      /* 翻译规则的形式是:正规式  {动作}
       * 其中,正规式要顶行首写,动作要以C语法写(动作会被拷贝到yylex()函数中,),\
       * 正规式和动作之间要用空白分割。
       */
      
    {ws}	          {;/* 此时词法分析器没有动作,也不返回,而是继续分析。 */}
      /* 正规式部分用大括号扩住的表示正规定义名,例如{ws}。
       * 没有扩住的直接表示正规式本身。
       * 一些元字符没办法表示它本身,此时可以用转义字符或
       * 用双引号括起来,例如"<"
       */
    while	          {return (WHILE);}
    do		          {return (DO);}
    {id}	          {yylval = installID (); return (ID);}
    {number}	      {yylval = installNum (); return (NUMBER);}
    "<"	            {yylval = LT; return (RELOP);}
    "<="	          {yylval = LE; return (RELOP);}
    "="	            {yylval = EQ; return (RELOP);}
    "<>"	          {yylval = NE; return (RELOP);}
    ">"	            {yylval = GT; return (RELOP);}
    ">="	          {yylval = GE; return (RELOP);}
    
    .								{yylval = ERRORCHAR; return ERRORCHAR;}
     /*.匹配除换行之外的任何字符,一般可作为最后一条翻译规则。*/
     
    %%
    /* 第三部分是辅助函数部分,这部分内容以及前面的%%都可以省略 */
    /* 辅助函数可以定义“动作”中使用的一些函数。这些函数
     * 使用C语言编写,并会直接被拷贝到lex.yy.c中。
     */
    
    int installID () {
      /* 把词法单元装入符号表并返回指针。*/
    	return ID;
    }
    
    
    int installNum () {
    	/* 类似上面的过程,但词法单元不是标识符而是数 */
      return NUMBER;
    }
    
    
    /* yywrap这个辅助函数是词法分析器遇到输入文件结尾时会调用的,用来决定下一步怎么做:
     * 若yywrap返回0,则继续扫描;返回1,则词法分析器返回报告文件已结束的0。
     * lex库中的标准yywrap程序就是返回1,你也可以定义自己的yywrap。
     */
    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;
        default:break;
      }
      return;
    }
    
    /* 辅助函数里可以使用yytext和yyleng这些外部定义的变量。
     * yytext指向输入缓冲区当前词法单元(lexeme)的第一个字符,
     * yyleng给出该词法单元的长度		*/
    
    /* 如果你的词法分析器并不是作为语法分析器的子程序,
     * 而是有自己的输入输出,你可以在这里定义你的词法
     * 分析器的main函数,main函数里可以调用yylex()
     */
    
    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");
    	  }
    	}
    	/* yyin和yyout是lex中定义的输入输出文件指针,它们指明了
    	 * lex生成的词法分析器从哪里获得输入和输出到哪里。
    	 * 默认:键盘输入,屏幕输出。 
    	 */
    	while (c = yylex()){
    		writeout(c);
    		j++;
    		if (j%5 == 0) writeout(NEWLINE);
    	}
    	if(argc>=2){
    	  fclose(yyin);
    	  if (argc>=3) fclose(yyout);
    	}
    	return 0;
    }
    
       exam2.l

    /* 把注释去掉 */
    
    %{
    
    #include <stdio.h> 
    #define LT					1
    #define	LE					2
    #define GT					3
    #define	GE					4
    #define	EQ					5
    #define NE					6
    #define LLK                                     7
    #define RLK                                     8
    #define LBK                                     9
    #define RBK                                     10
    #define IF                               11
    #define ELSE                             12
    #define EQU                              13
    #define SEM                              14
    
    #define WHILE				18
    #define	DO					19
    #define ID          20
    #define NUMBER      21
    #define RELOP       22
    
    #define NEWLINE     23
    #define ERRORCHAR   24
    #define ADD                       25
    #define  DEC                         26
    #define  MUL                         27
    #define  DIV                        28
    
    
    %}
    
     
    delim		[ \t \n]
    ws			{delim}+
    letter	[A-Za-z_]
    digit		[0-9]
    id			{letter}({letter}|{digit})*
    number	{digit}+(\.{digit}+)?(E[+-]?{digit}+)?
    
    /* 状态(或条件)定义可以定义在这里 
     * INITIAL是一个默认的状态,不需要定义
     */
    %s COMMENT
    %s COMMENT2
    %%
    
    <INITIAL>"/*"						{BEGIN COMMENT;}
    <COMMENT>"*/"						{BEGIN INITIAL;}
    <COMMENT>.|\n						{;}
    <INITIAL>"//"						{BEGIN COMMENT2;}
    <COMMENT2>\n					{BEGIN INITIAL;}
    <COMMENT2>.					{;}
    
     /* ECHO是一个宏,相当于 fprintf(yyout, "%s", yytext)*/
    
    <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 (RELOP);}
    <INITIAL>")"	          {return (RELOP);}
    <INITIAL>"{"	          {return (RELOP);}
    <INITIAL>"}"	          {return (RELOP);}
    <INITIAL>"+"	          {return (RELOP);}
    <INITIAL>"-"	          {return (RELOP);}
    <INITIAL>"*"	          {return (RELOP);}
    <INITIAL>"/"	          {return (RELOP);}
    <INITIAL>";"	          {return (RELOP);}
    
    <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 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 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;
    }

     test1.p:

    while a >= -1.2E-2
     do b<=2

     test2.p:

    while a >= -1.2E-2
    do b<=2
    if else
    +
    -
    *
    /
    ; //的发生过
    /* 请注意:测试文件的格式必须符合要求,
      比如,该文件要求的格式是UNIX格式。*/

    四、cygwin下编译连接lex源程序的命令:

        1. 用lex翻译器编译lex源程序命令(假设filename.l是lex源程序名):

       flex filename.l

        2. 用gcc编译器编译lex翻译器生成的c源程序(lex翻译器生成的c源程序名固定为lex.yy.c): 

       gcc [-o outfile] lex.yy.c –lfl

        其中,-lfl是链接flex的库函数的,库函数中可能包含类似yywrap一类的标准函数。-o outfile是可选编译选项,该选项可将编译生成的可执行程序命名为outfile,如果不写该编译选项,默认情况下生成的可执行程序名为a.exe(linux下实际为a.out)。

         3. 调用词法分析器yylex()的main函数可以写在lex源程序的辅助函数部分,也可以写在其他的c文件中。如果main函数写在main.c中,则编译时需要和lex.yy.c一起编译链接,即编译链接命令为:

       gcc [-o outfile] lex.yy.cmain.c –lfl

         4.运行可执行文件a.exe的命令(假设a.exe处于当前目录下,且忽略运行参数的情况):

       ./a.exe

    其中,./表示当前目录。如果a.exe处于其他路径,则运行时请给出完整路径名。

    五、关于cygwin

        1. 网址:www.cygwin.com 是cygwin的官方网站,可以从上面下载安装cygwin。

        2. 下载和安装:从上述网址下载setup.exe运行,即可选择从网络上安装cygwin,也可选择下载到本地,然后再从本地安装。

         本地安装的过程:

         1)将setup.exe及安装包下载到本地

         2)运行setup.exe à 选择Install fromLocal Directory à 选一个root directory(例如可以选D:\cygwin,不要选中文路径名) à选一个Local Package Directory(选择存放安装包的那个目录)àselectpackages(其它都可以default,重要的是选中Devel下的bison,flex,gcc-core,gcc-g++, make,vim)

       3. 使用cygwin:

         安装完成后,检查环境变量中有没有HOME变量,如果有,先将HOME变量改名(方法:右键我的电脑à属性à高级à环境变量,在你自己的用户变量列表中找到HOME变量,改名)。

         运行安装目录(root directory)下的cygwin.bat启动cygwin。第一次运行cygwin会生成home目录,如果home目录创建不成功,则很可能是HOME环境变量的缘故,先将这个变量改名,再运行cygwin.bat。

         第一次运行成功后,所在目录应该是/home/your-user-name,请把你的文件存于该目录下。其中home目录实际上是在你选择的root directory下。

    展开全文
  • lex的简单使用

    2021-05-13 07:04:39
    Lex & Flex 简介Lex是lexical compiler的缩写,是Unix环境下非常著名的工具, Lex (最早是埃里克·施密特和 Mike Lesk 制作)是许多 UNIX 系统的标准词法分析器(lexical analyzer)产生程式,而且这个工具所作的...

    Lex & Flex 简介

    Lex是lexical compiler的缩写,是Unix环境下非常著名的工具, Lex (最早是埃里克·施密特和 Mike Lesk 制作)是许多 UNIX 系统的标准词法分析器(lexical analyzer)产生程式,而且这个工具所作的行为被详列为 POSIX 标准的一部分。

    Lex的基本工作原理为:由正则表达式生成NFA,将NFA变换成DFA,DFA经化简后,模拟生成词法分析器。

    Lex 主要功能是生成一个词法分析器(scanner)的 C 源码,描述规则采用正则表达式(regular expression)。描述词法分析器的文件 *.l 经过lex编译后,生成一个lex.yy.c 的文件,然后由 C 编译器编译生成一个词法分析器。词法分析器,简言之,就是将输入的各种符号,转化成相应的标识符(token),转化后的标识符很容易被后续阶段处理,如Yacc 或 Bison,过程如图 :

    bVbylrS?w=339&h=186

    在linux系统上,我们最常用的是Flex,Flex (fast lexical analyser generator) 是 Lex 的另一个替代品。它经常和自由软件 Bison 语法分析器生成器 一起使用。Flex 最初由 Vern Paxson 于 1987 年用C语言写成。Flex手册里对 Flex 描述如下:

    FLEX (fast lexical analyzer generator) is a tool/computer program for generating lexical analyzers (scanners or lexers) written by Vern Paxson in C around 1987. It is used together with Berkeley Yacc parser generator or GNU Bison parser generator. Flex and Bison both are more flexible than Lex and Yacc and produces faster code.

    Bison produces parser from the input file provided by the user. The function yylex() is automatically generated by the flex when it is provided with a .l file and this yylex() function is expected by parser to call to retrieve tokens from current/this token stream.

    Lex & Flex 输入文件格式

    Flex 的输入文件包含了三部分,分别是定义区(definitions)、规则区(rules)和用户代码区(user code)并且由单独占一行的两个连续的百分号("%%")分隔开:

    definitions

    %%

    rules

    %%

    user code

    下面对 Flex 输入文件的三个部分做出解释:

    1 定义部分:定义部分包含变量的声明,正则定义,清单常量。在定义部分,文本放在“%{%}”括号中。用花括号括起来的所有内容都会直接复制到lex.yy.c文件中。

    语法

    %{

    // Definitions

    %}

    2 规则部分:rules部分包含一系列规则,格式为:pattern action,并且模式 pattern 位于行首不能缩进,action 也应该起始于同一行,规则部分包含在“%% %%”中。

    语法:

    %%

    pattern action

    %%

    下表显示了一些模式匹配。

    Pattern

    It can match with

    [0-9]

    all the digits between 0 and 9

    [0+9]

    either 0, + or 9

    [0, 9]

    either 0, ‘, ‘ or 9

    [0 9]

    either 0, ‘ ‘ or 9

    [-09]

    either -, 0 or 9

    [-0-9]

    either – or all digit between 0 and 9

    [0-9]+

    one or more digit between 0 and 9

    [^a]

    all the other characters except a

    [^A-Z]

    all the other characters except the upper case letters

    a{2, 4}

    either aa, aaa or aaaa

    a{2, }

    two or more occurrences of a

    a{4}

    exactly 4 a’s i.e, aaaa

    .

    any character except newline

    a*

    0 or more occurrences of a

    a+

    1 or more occurrences of a

    [a-z]

    all lower case letters

    [a-zA-Z]

    any alphabetic letter

    w(x \

    y)z

    wxz or wyz

    3 用户代码部分:这部分包含C语句和其他功能。我们还可以分别编译这些函数并使用词法分析器加载。

    如何运行程序:

    要运行该程序,首先应将其保存为扩展名.l或.lex。在终端上运行以下命令以运行程序文件。

    步骤1:lex filename.l或lex filename.lex取决于扩展文件

    步骤2:gcc lex.yy.c

    步骤3:./ a.out

    步骤4:在需要时将输入提供给程序

    注意:按Ctrl + D或使用某些规则停止接受用户输入。请查看以下程序的输出图像以清除是否有疑问以运行程序。

    简单例子

    计算字符串中的字符数

    /*** Definition Section has one variable

    which can be accessed inside yylex()

    and main() ***/

    %{

    int count = 0;

    %}

    /*** Rule Section has three rules, first rule

    matches with capital letters, second rule

    matches with any character except newline and

    third rule does not take input after the enter***/

    %%

    [A-Z] {printf("%s capital letter\n", yytext);

    count++;}

    . {printf("%s not a capital letter\n", yytext);}

    \n {return 0;}

    %%

    /*** Code Section prints the number of

    capital letter present in the given input***/

    int yywrap(){}

    int main(){

    // Explanation:

    // yywrap() - wraps the above rule section

    /* yyin - takes the file pointer

    which contains the input*/

    /* yylex() - this is the main flex function

    which runs the Rule Section*/

    // yytext is the text in the buffer

    // Uncomment the lines below

    // to take input from file

    // FILE *fp;

    // char filename[50];

    // printf("Enter the filename: \n");

    // scanf("%s",filename);

    // fp = fopen(filename,"r");

    // yyin = fp;

    yylex();

    printf("\nNumber of Captial letters "

    "in the given input - %d\n", count);

    return 0;

    }

    运行:

    bVbylyP?w=533&h=243

    查找读取文本所有整数

    %{

    /*

    用flex写一个查找读取文本所有整数的程序

    */

    int count = 0;

    %}

    %%

    [+-]?[0-9]+ { count++; printf("%s\n", yytext); } /* Print integers */

    \n {} /* newline */

    . {} /* For others, do nothing */

    %%

    void main() {

    yylex();

    printf("Number count is %d\n", count);

    }

    int yywrap() {

    return 1;

    }

    运行:

    bVbylAY?w=568&h=180

    参考文章:

    展开全文
  • windows 下使用lex

    2021-05-23 15:09:34
    官网下载win flex-bison https://sourceforge.net/projects/winflexbison/ 解压 cmd到win——flex的目录 a.l文件内容 ```cpp %{ #include <stdio.h> #include <stdlib.h>...operato
  • 我曾经在Linux上写的一个C程序,借助Lex做词法分析来同时统计N个文本文件的字符数,单词数和行数。让我觉得Lex确实挺有意思的。确实Lex的功能非常强大,用来做小巧的词法分析非常适合,也非常好用。这个程序参考了...
  • 定义语法规则时候,默认第一个方法定义的规则是语法头,
  • 词法分析器生成工具lex使用 《词法分析器生成工具lex使用》,作者:GOD_YCA,原文链接:http://www.cnblogs.com/GODYCA/archive/2013/01/03/2843096.html 分享自:博客园Android客户端(http:...
  • Lex和Yacc工具使用方法

    2013-12-16 00:19:18
    Lex和Yacc工具使用方法,介绍了编译原理课程中的工具lex和yacc的基础使用方法
  • 实验内容:(1)从txt文件中读入字符。 (2)统计行数和列数用于定位。 (3)删除空格类字符,包括... (属性值——token 的机内表示) (5)如果发现错误则报告出错 (6)根据需要是否填写标识符表供以后各阶段使用
  • 编译器 使用 lex 和 yacc ,生成解析树和符号表
  • flex的简单使用(1)将flex.exe和创建的text.lex放在同一文件夹下;(2)在DOS命令提示符下执行编译 flex text.lex 得到目标文件 lex.yy.c;(3)在VC或CB中运行lex,yy.c,产生可执行程序lex.yy.exe(4)运行可执行文件,执行...
  • 该界面允许用户使用文本或语音直接从浏览器与Lex bot进行交互。 功能包括: 具有整页或嵌入式小部件模式的移动就绪响应式UI 支持语音和文本,能够从一种模式无缝切换到另一种模式 语音支持提供自动静音检测,转录...
  • 四个文件: 正则表达式简介.pdf 借助Lex 和Yacc 进行词法语法分析.pdf Lex and YACC primer.pdf O'Reilly Mastering Regular Expressions 3rd.Ed.chm
  • Lex是Ruby中的编译器构建工具lex的实现。 目的是保持原始工具的工作方式,并将其与Ruby的表现力结合起来。 产品特点 非常专注的工具,模仿了基本的lex功能。 100%Ruby实现。 提供全面的错误报告,以协助词法分析...
  • Lex词法分析器.rar

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

    千次阅读 2017-03-20 18:10:19
     Lex自动地表示把输入串词法结构的正规式及相应的动作转换成一个宿主语言的程序,即词法分析程序,它有一个固定的名字yyler,在这里yyler是一个C语言的程序。 Yylex将识别出输入串中的词形,并且在识别出某词...
  • 使用lex和yacc识别程序中的括号

    千次阅读 2019-02-02 19:36:10
      识别单词,可以使用DFA,使用lex工具,需要交给lex的是lex支持的正则表达式。所以识别单词,需要正确地分别对每种单词串构造正确的正则表达式。然后对每种单词串定义相应的动作,如果是换行符、空白、other等,...
  • 使用某种高级语言和Lex实现C语言词法分析程序,对输入的C语言程序能够进行词法分析和字符分类。手工编写的程序是使用Python语言。
  • LEX是UNIX的工具,因此我们需要使用FLEX代替,使得在windows下使用。提供lex,flex ,在win下也能体验编译的快乐
  • yacc lex使用实例

    2016-03-29 22:15:50
    mysql php python中都是使用这个生成词法分析和语法分析器 %{ typedef char* string; #define YYSTYPE string %} %token NAME EQ AGE %% file : record file | record ; record : NAME EQ AGE { printf(...
  • lex与yacc.pdf

    2020-08-05 10:27:44
    这是关于编译原理, 词法分析lex, 与语法分析yacc的相关文档,高清版,但是这只有该书的前5章 第一章 lex与yacc 第二章 lex使用 第三章 yacc使用 第四章 菜单生成与语言 第五章 SQL分析
  • Lex和Yacc教程.pdf

    2019-09-05 23:16:56
    非常通俗易懂的讲解lex和yacc的文档,教科书上把lex的作用的作用叫做“词法分析 lexical analysis ”,这个中文叫法非常让人看不明白(叫做“符号提取”更合适),其实从它的英文单词lexical上来看他的意思其实是...
  • Lexis使用教程.pdf

    2021-09-30 17:48:22
    Lexis使用教程.pdf
  • Python词法分析器 安装 在Debian / Ubuntu发行版中: sudo apt-get install flex 用法 汇编: ./compile.sh 跑步: ./run.sh
  • json-lex:json lex分析

    2021-05-09 14:13:58
    json-lex json lex分析
  • LEX語法分析和運用介紹看了可以對大家很有幫助

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,364
精华内容 10,145
关键字:

lex使用