`

lex和yacc工具说明

阅读更多

转载自:http://bbs.chinaunix.net/viewthread.php?tid=440106

 

Lex工具
-------
   Lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。
1、lex程序的结构

-定义部分
-规则部分
-用户子程序部分

其中规则部分是必须的,定义和用户子程序部分是任选的。

(1) 定义部分
    定义部分起始于"%{"符号,终止于"%}"符号,其间可以是包括include语句、声明语句在内的C语句。
%{
#include "stdio.h"
#include "y.tab.h"
extern int lineno;
%}

(2) 规则部分
   规则部分起始于"%%"符号,终止于"%%"符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分 是由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内 容就代表了所识别出来的单词的内容。

%%
[\t] {;}
[0-9]+\.?|[0-9]*\.[0-9]+
    { sscanf(yytext,"%1f", &yylval.val);
      return NUMBER; }
\n { lineno++;return '\n'; }
.  { return yytex+[0]; }
%%

(3) 用户子程序部分
   用户子程序部分可以包含用C语言编写的子程序,而这些子程序可以用在前面的动作中,这样就可以达到简化编程的目的。下面是带有用户子程序的lex程序片段。
  "/*"   skipcmnts();
   .   /* rest of rules  */
  %%
  skipcmnts()
  {
    for (  ;  ;   )
    {
      while (input()!='*');
      if(input()!='/')
        unput(yytext[yylen-1]);
      else return;
   }

2、lex工具的使用方法
首先编写一个lex程序
vi lex.l
%{
#include "stdio.h"
%}
%%
[\n] ;
[0-9]+   printf("Interger: %s \n",yytext);
[0-9]*\.[0-9]+   printf("Float: %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]*   printf("Word:%s\n",yytext);
.  printf("Other symbol:%c\n",yytext[0]);
%%

然后使用lex将lex.l转换成C语言程序
$lex lex.l
使用上述命令产生的C语言程序为lex.yy.c
然后使用C编译程序将lex.yy.c编译成可执行程序regn
$cc -c lex.yy.c
$cc lex.yy.o -ll -o regn
下面可以使用regn来识别单词
$vi testfile
x=355
y=113
p=x/y

# ./regn < testfile
Word
Other symbol:=
Interger: 355
Word:y
Other symbol:=
Interger: 113
Word:p
Other symbol:=
Word
Other symbol:/
Word:y
#
  
yacc工具
--------
    yacc工具是一种语法分析程序生成器,它可以将有关某种语言的语法说明书转换成相应的语法分析程序,由该程序完成对相应语言中语句的语法分析工作。

1、yacc程序结构
   在使用yacc工具前,必须首先编写yacc程序,因为有关语法分析程序是根据yacc程序生成的。yacc程序实际上是有关语法规则的说明书,它也是 由定义部分、规则部分和子程序部分组成的。yacc程序的定义部分类似于lex程序的定义部分,只是在其后可带有yacc声明,其中包括词法单词、语法变 量、优先级和结合性信息。yacc程序的规则部分由语法规则和相应的动作组成,子程序部分可以包括在前面规则部分用到的子程序定义。接下来是main主程 序,它调用yyparse子程序来对输入进行语法分析,而yyparse反复地调用yylex子程序来获得输入单词,在语法出错时可通过yyerror子 程序来处理。

2、yacc工具的使用方法
实例:我们将yacc程序分成片段,把这些片段组合在一起就是yacc程序。我们要使用的语法规则是一个有关四则运算的语法规则,可用BNF范式描述
list: expr \n
    list expr  \n
expr :NUMBER
      expr + expr
      expr - expr
      expr * expr
      expr / expr
      (expr)
    其含义是list是一个表达式序列,每个后面带有一个新行。表达式是一个数值,或是由运算符连起来的两个表达式,以及用圆括号括起来的表达式。
    下面是有关上述语法规则的yacc程序片段。
  $vi hoc.y
  %{
  #define YYSTYPE double
  %}
  %token NUMBER
  %left '+' '-'
  %left '*' '/'
  %%
  list:
    | list '\n'
    | list expr '\n' { printf("\t%. 8g\n",$2);}
      ;
   expr : NUMBER   {$$=$1;}
     | expr '+' expr {$$ = $1 + $3; }
     | expr '-' expr {$$ = $1 - $3; }
     | expr '*' expr {$$ = $1 * $3; }
     | expr '/' expr {$$ = $1 / $3; }
     | '('expr')'  {$$ = $2; }
    %%
    上述yacc程序片段实际上是它的定义部分和规则部分。在yacc声明部分,%token NUMBER表明了NUMBER是一个单词符号,%left则表明了运算符号的左结合性,并且'*'和'/'和优先级比'+'和'-'的优先级高。在 yacc程序的规则部分,备用规则是用'|'隔开的,规则中的动作实际上是C语句序列,其中$n(即$1,$2等)是用来引用规则中的第几个成份, 而$$则代表了整个规则的返回值。

下面的yacc程序片段是main主程序
  #include <stdio.h>;
  #include <ctype.h>;
    char *progname;
    int  lineno=1;
    main(argc,argv)
    int argc;
    char *argv[];
    {     progname = argv[0];
          yyparse();
    }

    main主程序调用yyparse子程序来处理来处理输入,而yyparse又是通过yylex子程序来获得输入单词并通过yyerror子程序来报告出错信息。下面是有关这两个子程序的yacc程序片段

yylex()
  {  int c;
     while ((c=getchar()) == ' ' || c=='\t') ;
    if (c==EOF)
    return 0;
    if (c=='.'||isdigit(c)){
   ungetc(c,stdin);
   scanf("%lf", &yylval);
   return NUMBER;
}
if(c=='\n')
   lineno++;
   return c;
}
  yyerror(s)
  char *s;
{  warning (s,(char *)0);
}
   warning(s,t)
char *s,*t;
  { fprintf(stderr,"%s:%s",progname,s);
   if(t)
    fprintf(stderr,"%s",t);
    fprintf(stderr," near line %d\n",lineno);
}

这样就完成了整个yacc程序
接下来就使用 yacc将hoc.y转换成C语言程序
$yacc hoc.y
使用上述命令产生的C语言程序为y.tab.c,这时可以使用C编译程序将它编译成可执行程序hoc.
$cc y.tab.c -o hoc

下面是使用hoc的例子
# ./hoc
4*3*2
         24
(1+2)*(3+4)
         21
1/2
         0.5
355/133
         2.6691729
-3-4
./hoc:Syntax error near line 5
上述结果显示中,分别表明了计算结果,最后一次计算出错的原因是由于在规则定义中未来定义单目减运算符号。

 

 

 

 

补充一点:

 

在linux下 可以用 lex -t  xxx. > xxx.c  生成对应的c程序  这样就可以自己命名生成c程序的文件名了,而不是用默认的lex.yy.c

将c程序直接编译为可执行文件 可以直接使用 cc xxx.c -o   xxx -ll  (是字母L 不是 数字1)

 

分享到:
评论

相关推荐

    C语言的lex和yacc工具说明.doc

    C语言的lex和yacc工具是用于编译器设计和解析语言的两个关键工具。它们分别是词法分析器和语法分析器的生成器,帮助开发者构建自定义的解析器和编译器。 首先,让我们深入了解lex工具。Lex是一种词法分析程序生成器...

    Lex和Yacc从入门到精通pdf

    《Lex和Yacc从入门到精通》是一本深入解析Unix工具Lex和Yacc的专业书籍,旨在帮助读者逐步掌握这两款强大的编程工具,从而构建出功能丰富的解析程序。Lex(也称为lex或flex)和Yacc(也称为yacc或bison)是经典的...

    Lex和Yacc工具使用方法

    Lex 和 Yacc 工具使用方法 Lex 和 Yacc 是编译原理课程中的两个重要工具,分别用于词法分析和语法分析。在编译器设计中,Lex 负责将输入串词法结构的正规式及相应的动作转换成一个宿主语言的程序,即词法分析程序...

    lex和yacc工具下载

    在IT领域,`lex`和`yacc`是两个经典的工具,它们主要用于计算机程序的编译和解析过程。这两个工具是构建编译器和解释器的重要组成部分,它们可以帮助开发者高效地处理语言的词法和语法分析。 `lex`,全称`LEX`,是...

    Lex与Yacc第二版高清版

    标签“Lex Flex Yacc”揭示了本书的核心主题,其中Lex和Flex是用于词法分析的工具,而Yacc则是语法分析器生成器。 首先,让我们了解一下Lex(现在通常被称为Flex)。Lex是一种经典的词法分析器生成器,它接受用特定...

    借助Lex和Yacc进行词法语法分析

    Lex和Yacc是两款广泛应用于词法分析和语法分析的工具,它们分别负责词法分析(Lex)和语法分析(Yacc),共同帮助开发者构建出高效、准确的编译器。本文将基于给定的实验内容,深入探讨如何利用Lex和Yacc进行词法和...

    lex和yacc程序

    标题"lex和yacc程序"指的是两个经典的编程工具,它们在编译原理和解析技术领域有着重要地位。Lex(也称为Flex)是用于词法分析的工具,它根据正则表达式定义规则从源代码中识别出一个个的词汇单元,如关键字、标识符...

    编译原理lex和yacc

    6. **相关工具与框架**:在编译原理领域,还有一些其他工具和框架,如ANTLR、JavaCC等,它们提供更现代的解析技术,支持更多的语言特性,并且通常具有更好的错误处理和调试功能。 7. **应用扩展**:除了编译器,lex...

    Lex和Yacc简明教程

    《Lex和Yacc简明教程》是一份深入探讨编译器构造工具的宝贵资源,主要关注于Lex和Yacc这两个经典工具。它们在计算机科学领域,尤其是编译器设计和实现中扮演着至关重要的角色。本文将详尽阐述这两个工具的基本概念、...

    LEX和YACC第二版中文版.zip

    LEX和YACC是计算机科学领域中用于编译器和解释器开发的重要工具,它们在构建解析器时扮演着至关重要的角色。本资源是"LEX和YACC第二版中文版",提供了一本关于这两个工具的详细指南,尤其适合对编译原理感兴趣的读者...

    使用Lex, Yacc开发的算术表达式解析器,以及算术表达式的计算器

    在IT领域,开发一个能解析和计算算术表达式的程序是一项基础且重要的...总之,这个项目展示了如何使用Lex和Yacc这两个经典的编译工具来解析和计算算术表达式,对于学习编译原理和理解软件开发底层逻辑具有重要意义。

    lex和yacc学习资料

    《lex和yacc学习资料》包含了关于编译器构造领域两个关键工具——lex和yacc的深入学习资源,以及它们的现代替代品flex与bison的相关书籍和源代码。这些工具在软件开发中扮演着重要角色,特别是对于理解编译原理和...

    利用LEX,YACC实现SQL编译器

    4. **生成词法和语法分析器**:运行LEX和YACC工具,自动生成词法分析器和语法分析器的源代码。这一步骤是自动化编译器构建的关键,极大地减少了手动编码的工作量,并提高了代码的正确性和效率。 5. **集成与测试**...

    lex_yacc_example

    lex和yacc(也称为flex和bison)是两种广泛使用的工具,用于创建词法分析器和语法分析器。本文将深入探讨lex和yacc的工作原理,并通过一个名为"lex_yacc_example"的实际例子来阐述它们的使用方法。 首先,lex(现在...

    Lex和Yacc的相关文档

    Lex和Yacc是两种广泛应用于构建词法分析器和语法分析器的强大工具,主要用于帮助开发者高效地处理各种语言结构。本文档旨在全面介绍Lex和Yacc的基础知识及其实际应用,为读者提供一套完整的从入门到精通的学习资料。...

    lex-yacc或flex-bison的介绍

    通过使用 lex/flex 和 yacc/bison 工具,我们可以构建一个简单的计算器,并进一步研究 lex 和 yacc 系统生成的输出和信息。 lex 和 yacc 工具可以集成到我们的应用程序中,以完成各项工作,从配置分析到构建您自己的...

    基于lex和yacc的词法分析器+语法分析器(C语言编译器)【100012624】

    本项目专注于词法分析和语法分析这两个编译器设计的重要阶段,利用 lex 和 yacc 工具来实现。以下是关于这两个工具及其在C语言编译器构建中的应用的详细解释。 首先,我们关注的是“词法分析器”,它在编译过程的...

    \lex&yacc

    《lex&yacc》这本书是编译原理领域中的一本经典读物,它深入浅出地介绍了如何使用lex和yacc这两个工具进行编译器构造。lex(也称为flex)和yacc(也称为bison)是两种强大的开源工具,分别用于词法分析和语法分析,...

    完整介绍Lex和Yacc Windows 上的使用

    完整介绍Lex和Yacc Windows 上的使用 及工具的按装, 及环境变量的设置, GNU Bison实际上是使用最广泛的Yacc-like分析器生成器,使用它可以生成解释器,编译器,协议实现等多种程序. 它不但与Yacc兼容还具有许多Yacc不...

Global site tag (gtag.js) - Google Analytics