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

    2012-06-23 17:22:39
    lex 词法分析 以及parser generator 和vc6如何配置
  • minipascal的lex词法分析代码
  • 基于lex词法分析

    2012-04-23 08:51:00
    编译原理 课程设计 基于lex词法分析器构造的源代码
  • 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词法分析生成器.doc

    2009-11-12 19:49:07
    lex词法分析生成器,学习编译原理的应该都能用的上哦
  • 编译原理lex词法分析 使用 parser generator , vc++工程实现
  • Lex词法分析实验

    2012-05-12 23:48:47
    编译原理相关,涉及到lex,yacc以及它们在编译技术中的应用,详细介绍了·lex,yacc编程技术!
  • 编译原理课程设计/实验 lex简单词法分析器 只实现了简单功能
  • Fast Lex词法分析工具

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

    2008-11-15 22:10:20
    词法分析 c++ c语言 简单的c语言词法分析
  • lex 词法分析 GNU flex

    2009-05-11 15:17:40
    GNU Flex 通过 设置正则表达式和匹配规则 自动生成词法分析程序,学编译原理的同学要用到
  • lex词法分析 实验代码

    2010-05-16 16:57:21
    lex实验代码 lex实验代码 lex实验代码
  • 简单的lex此法分析程序,用到lex.exe编译
  • yacc和lex的集成开发包,内有编译工具和实例代码
  • lex词法分析工具 下载

    2011-03-04 19:15:08
    文章信息检索,基于概率模型的信息抽取,高效算法,基于HMM模型的信息抽取应用于文章结构的分析可能会很有效
  • yacc语法分析与lex词法分析相结合

    千次阅读 2015-05-17 15:32:40
    语法对于某些应用,我们所完成的简单的词类识别也许足够用了;而另一些应用需要识别特殊的标记序列并执行适当的动作。...词法分析程序和语法分析程序的通信当一起使用lex扫描程序和yacc语法分析程序的时候,语法

    语法

    对于某些应用,我们所完成的简单的词类识别也许足够用了;而另一些应用需要识别特殊的标记序列并执行适当的动作。传统上,对这样的一套动作描述成为语法。

    使用右箭头”->”意味着可以用一个新的符号取代一套特殊的标记。
    例如:

    subject ->noun\pronoun 指示一个新的符号subject是名词或代词。

    词法分析程序和语法分析程序的通信

    当一起使用lex扫描程序和yacc语法分析程序的时候,语法分析程序是比较高级别的例程。当他需要来自输入的标记时,就调用词法分析程序yylex()。然后,词法分析程序从头到尾扫描输入识别标记。他一找到对u语法分析程序有意义的标记就返回到语法分析程序,将返回标记的代码作为yylex()的值。

    词法分析程序和语法分析程序必须对标记代码的内容达成一致。通过让yacc定义标记代码来解决这个问题。在我们的语法中,标记的词性是:NOUN,PRONOUN,VERB,ADVERB,ADJECTIVE,PREPOSITION和CONJUNCTION。yacc使用预处理程序#define将他们每一个都定义为小的整数。下面是一个示例:

    
    #define NOUN 257
    #define PRONOUN 258
    #define VERB 258
    #define ADVERB 260
    #define ADJECTIVE 261
    #define PREPOSITION 262
    #define CONJUNCTION  263
    

    输入的逻辑结束总是返回标记代码零。
    下面这一段程序展示了新的词法分析程序的声明和规则段

    名称为:forth.lex

    %{
    
    /*
    * 我们现在构建一个由高级语法分析程序使用的词法分析程序
    */
    
    #include "y.tab.h"  /* 来自语法分析程序的标记代码 */
    #define LOOKUP 0 /* 默认情况 - 不是一个定义的单词类型 */
    
    int state;
    
    %}
    
    %%
    
    \n { state = LOOKUP; }
    
    \.\n { state = LOOKUP;
        return 0; /* 句子结尾 */ 
    }
    
    ^verb { state = VERB; }
    ^adj  { state = ADJECTIVE;  }
    ^adv  { state = ADVERB;  }
    ^noun { state = NOUN; }
    ^prep { state = PREPOSITION;}
    ^pron { state = PRONOUN; }
    ^conj { state = CONJUNCTION; }
    
    [a-zA-Z]+ {
        if(state != LOOKUP){
                add_word(state,yytext);
        }else{
    
            switch(lookup_word(yytext)){
                case VERB:
                    return(VERB);
                case ADJECTIVE:
                    return(ADJECTIVE);
                case ADVERB:
                    return(ADVERB);
                case NOUN:
                    return(NOUN);
                case PRONOUN:
                    return(PRONOUN);
                case CONJUNCTION:
                    return(CONJUNCTION);
                default:
                    printf("%s: do not recognize!\n",yytext); /* 不返回 忽略 */
            }
        }
    }
    
    . ;
    
    %%
    
    /* 定义一个单词和类型的链表 */
    struct word{
        char *word_name;
        int word_type;
        struct word *next;
    };
    
    struct word *word_list; /* 单词链表中的第一个元素 */
    extern void *malloc();
    
    
    int add_word(int type,char *word)
    {
        struct word *wp;
        if(lookup_word(word) != LOOKUP){
            printf("!! warning: word %s already defined\n",word);
            return 0;
        }
    
        /* 单词不在那里,分配一个新的条目并将它链接到链表上 */
        wp = (struct word *)malloc(sizeof(struct word));
        wp->next = word_list;
    
        /* 还必须复制单词本身 */
        wp->word_name = (char *)malloc(strlen(word)+1);
        strcpy(wp->word_name,word);
        wp->word_type = type;
        word_list = wp;
    
        return 1;  /* 添加成功 */
    }
    
    int lookup_word(char *word)
    {
        struct word *wp = word_list;
    
        /* 向下搜索列表以寻找单词 */
        for(;wp;wp = wp->next){
            if(strcmp(wp->word_name,word) == 0)
                return wp->word_type;
        }
    
        return LOOKUP;
    }
    
    int yywrap()
    {
        return 1;
    }
    

    他和之前的词法分析程序有一下几个区别:
    1:词法分析程序中使用的词性名字改变为与词法分析程序中的标记名字相一致
    2:添加return语句将所识别的单词的标记代码传递给语法分析程序
    3:词法分析程序中定义新单词的标记没有任何return语句,因为语法分析程序不“关心”它们。

    其中,返回语句表明yylex()操作类似与协同程序。每次语法分析程序调用他时,
    都在他停止的那一点进行处理。这样就允许我们渐进地检查和操作输入流。

    同时还增加了一条规则来标记句子的结尾:

    \.\n { state = LOOKUP;
              return 0; /* 句子结尾 */
    }

    句号前面的反斜杠引用这个句号,所以这条规则与后跟一个换行的句号匹配。对词法分析程序所做的另一个改变是省略
    目前语法分析程序中提供的main()例程。

    yacc语法分析程序

    下面程序介绍了yacc语法中的第一步。
    forth.y

    %{
    /*
     * 用于识别英文句子基本语法的词法分析程序
     */
    #include <stdio.h>
    
    %}
    
    %token NOUN PRONOUN VERB ADVERB ADJECTIVE PREPOSITION CONJUNCTION 
    
    %%
    
    sentence: subject VERB object { printf("Sentence is valid.\n"); }
        ;
    
    subject:    NOUN
        |   PRONOUN
        ;
    
    object: NOUN
        ;
    
    %%
    
    extern FILE *yyin;
    
    int main()
    {
        yyparse();
        while(!feof(yyin)){
            yyparse();
        }
    
        return 0;
    }   
    
    yyerror(s)
    char *s;
    {
        fprintf(stderr,"%s\n",s);
    }
    

    yacc语法分析程序的结构类似与lex语法分析程序的结构。使用%{ %}括起的部分为定一段,使用%% %%括起的为规则段,%token 表示采用8个标记,通常规定标记名都用大写字母,而语法分析程序中的其他名字大部分或完全是小写字母.

    最终要的子程序main(),重复调用yyparse()函数知道词法分析程序的输入文件结束,例程yyparse()是由yacc生成的语法分析程序,当词法分析程序看到行的结尾处的句号时返回零标记,表示当前分析的输入已经完成。

    规则段将实际语法描述为一套产生式规则或简称为规则。每条规则由符号”:”操作符左侧的一个名字,右侧的符号列表和动作代码以及指示规则结尾的分号组成。默认情况下,第一条规则是最高级别的规则。典型的简单的规则的右侧有一个符号。规则左侧的符号在其他规则中能像标记一样使用。

    语法中使用特殊字符”|”,表示或;规则的动作部分由C块组成,以”{}”括起。因为sentence是最高层的符号,所以整个输入必须匹配sentence。当词法分析程序报告输入结束的时候,分析程序返回到他的调用程序。在该情况下就是主程序。随后对yyparse()的调用重置状态并再次开始处理。如果看到输入标记的”subject VERB object”列表,则示例打印一条消息,如果不匹配的话,则会调用yyerror()函数,识别特殊的规则error。可以提供错误恢复代码。尝试将分析程序返回到能够继续分析的状态。如果错误恢复失败,即没有错误恢复代码,yyparse()在发现错误后,返回调用程序。

    下面是我们的Makefile程序:

    all:
        lex forth.lex
        yacc -d forth.y
        gcc -c lex.yy.c y.tab.c
        gcc -o hello lex.yy.o y.tab.o -ll
    
    clean:
        rm lex.yy.o y.tab.o lex.yy.c y.tab.c y.tab.h hello
    

    下面我们使用命令:

    make

    对文件进行编译,编译完成之后,我们运行该程序:

    ./hello

    程序的输出结果,我们来测试一下,运行之后,我们输入下面的语句:

    verb are
    noun you man
    you are man 
    

    下面是程序的输出结果:
    这里写图片描述

    下面一篇博客将会使用该代码进行扩展,扩展一个简单的小学英语语法分析程序。

    展开全文
  • 作业:Lex词法分析

    2010-01-23 13:14:35
    编译原理的大作业 一个lex分析器 用VS2008编写
  • 使用lex进行词法分析时发现yylex()函数后的代码没有执行,代码如下,并没有输出“hello” int main(int argc,char *argv[]) { printf("请输入您要进行词法分析的程序段\n"); yylex(); printf("hello\n"); return...

    问题

    使用lex进行词法分析时发现yylex()函数后的代码没有执行,代码如下,并没有输出“hello”

    int main(int argc,char *argv[])
    {
       printf("请输入您要进行词法分析的程序段\n");  
       yylex();
       printf("hello\n");
    return 0;
    }
    

    类似于此:
    在这里插入图片描述

    解决方法

    不执行的原因是当前还没有退出yylex(),还在等待继续输入
    操作方法:ctrl+z 然后回车
    结果如图,问题解决
    在这里插入图片描述

    展开全文

空空如也

空空如也

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

lex词法分析