zoukankan      html  css  js  c++  java
  • flex and bison学习笔记01

    工作需要,学习一下Flex and bison,以前在编译原理的课上听老师说过他们的前辈,lex and yacc。Flex and bison就是lex and yacc的升级版。

    参考书:flex 与 bison

    1、Flex and bison简介

    Flex和bison是两个用来生成程序的工具,它们生成的程序分别叫做词法分析器和语法分析器,工作中主要是用来生成SQL语句的词法和语法分析器。

    2、词法分析器和语法分析器是如何工作的?

    任何一种语言,都是有一定的语法规则的,不管是人类的语言,还是计算机语言(如C/C++编程语言等),因此,可以利用这些已知的规则,来对相应的语言进行分析。举个例子,汉语中的一个句子,基本的格式是:主(名词/代词)+谓(动词)+宾(名词/代词),当你在说一句话的时候,我们把你说的话(输入)先拆分成一个个有意义的字或者词组,然后对照该语法,看词性及组合,是否符合既定的语法规范,如果符合,则可以知道你说的话是符合规范的。比如,你说“我吃饭”,输入会被依次拆成“我”“吃”“饭”,它们分别是代词、动词、名词,因此符合上面的语法规则,因此这句话是OK的。而如果说“我饭吃”,则会发现与上面的规范不符合(也没有其他符合的规范),因此这句话语法上市有问题的。Flex和bison生成的词法和语法分析器就是干这两件事的,Flex生成的词法分析器将输入拆分成一个个记号(token),bison生成的语法分析器根据已有的规则,分析这些token的组合,是否符合语法规范。

    3、Flex源文件格式

     4 Flex是用来生成词法分析器的
     5 Flex源文件扩展名.l
     6 分为三个段:定义段、规则段、用户子程序段
     7 /* 定义段 */
     8 %{
     9 ...
    10 %}
    11 ...
    12 
    13 %%
    14     /* 规则段 */
    15 ...
    16 %%
    17 
    18     /* 用户子程序段 */
    19 ...
    20 
    21 三个段用%%进行分隔
    22 1.定义段
    23     这一部分一般是一些声明及选项设置等。C语言的注释、头文件包含等一般就放在%{%}之间,这一部分的内容会被直接复制到输出文件的开头部分.
    24 2.规则段
    25 
    26     规则段为一系列匹配模式和动作,模式一般使用正则表达式书写,动作部分为C代码:
    27     模式1 {动作1 (C代码)}
    28     在输入和模式1匹配的时候,执行动作部分的代码。
    29 3.用户子程序段
    30     
    31     这里为C代码,会被原样复制到输出文件中,一般这里定义一些辅助函数等,如动作代码中使用到的辅助函数。
    32     
    33     词法分析器所做的,就是在输入中寻找字符的模式(pattern)。在词法分析器中,我们要给定我们需要识别的模式,因此需要使用一种方式来描述模式,这就是常用的正则表达式。学习正则表达式

    4、Flex小例子

    1.编写以下Flex源文件(01.l,注意后缀名是l字母)

    %{
        #include <stdio.h>
    %}
    
    %%
    
    [a-zA-Z]+ {printf("get word:%s
    ", yytext);}
    [0-9]+ {printf("get number:%d
    ", yytext);}
    
     {printf("New line
    ");}
    . {}
    
    %%

    代码中定义了四条规则,前面的部分就是模式,处于一行的开始位置,后面部分是动作,也就是,输入中匹配到了这个模式的时候,对应进行什么动作(就像机器人接受到了什么样的指令,然后会执行相应的动作一样)

    第一个模式,匹配连续一到多个字符串,匹配之后就将其打印出来。yytext:在输入中匹配到该模式的时候,匹配的部分就存储在这个yytext里面了。这里的动作是把它作为字符串直接输出。

    第二个模式,匹配连续一个或者多个数字,匹配到之后就将其输出。

    第三个模式,匹配一个换行符,匹配到之后就打印一个新行的信息。

    第四个模式,匹配出了 之外的字符,没有任何动作。

    总体来说,这个规则就是匹配到英语单词,则将其输出;匹配到连续数字,则将其输出;匹配到换行符,打印一条信息;匹配到任何其他字符直接忽略({}也就是动作为空,就是什么都不做了。)

    源文件写好了之后就是编译、生成可执行程序,然后测试是否按我们所想的那样了。

    找一个安装有Flex、bison的机器试一下吧,如果没有自行安装

    centos下使用下面命令安装,

    yum install flex

    yum nistall bison

    生成C代码:felx ./01.l

    编译生成的C代码:gcc -o scanner ./lex.yy.c -lfl

    然后运行scanner程序即可。

    第二个小例子的代码:

     1 %{
     2     int chars = 0;
     3     int words = 0;
     4     int lines = 0;
     5 %}
     6 
     7 %%
     8 
     9 [a-zA-Z]+ {words++; chars += strlen(yytext);}
    10 
     {chars++; lines++;}
    11 . {chars++;}
    12 
    13 %%
    14 
    15 main(int argc, char **argv)
    16 {
    17     yylex();
    18     printf("lines:%8d
    words:%8d
    chars:%8d
    ", lines, words, chars);
    19 }

    这个例子的规则是,统计输入的单词数,字符数以及行数。

  • 相关阅读:
    弹框只弹一次(cookie)
    多个列表求笛卡尔积的几种方法
    mysqlrouter 8.0.17启动失败
    Eclipse启动项目成功,IDEA报错java.lang.ClassNotFoundException: javax.servlet.Filter
    java的回调机制,讲得很清楚
    Java 命令行 -D
    spring boot项目中,webservice生成客户端,wsdl可配置
    一个老项目的高并发改造,遇到的redis连接不释放问题。
    ExecuterService实现线程池
    子线程获取不到请求中变量的问题
  • 原文地址:https://www.cnblogs.com/lit10050528/p/3944489.html
Copyright © 2011-2022 走看看