zoukankan      html  css  js  c++  java
  • 构建词法、语法分析器

    这里通过使用2个工具(Flex和Bison)来构造词法、语法分析程序,语法正确后生成抽象语法树。

    词法

    按Flex要求的格式,编辑Lex.l文件(这里文件名可以自行定义,但扩展名一定要是.l),使用Flex编译后即可得到词法分析源程序Lex.yy.c,其中通过调用 yylex()进行词法分析,每当识别出一个单词,将该单词的(单词种类码,单词的自身值)输出或提供给语法分析程序;

    语法

    按Bison要求的格式,编辑Parser.y文件(这里文件名可以自行定义,但扩展名一定要是.y),使用Bison编译后即可得到语法法分析源程序Parser.tab.c,其中调用
    parser()进行语法分析。

    工作流程

    二者联合完成词法与语法分析时,要统一单词的种类编码,这时可将各个单词在parser.y中逐个以标识符的形式,通过%token罗列出来,作为语法规则的终结符,同时用Bison编译后,生成一个文件Parser.tab.h,该文件中将这些标识符作为枚举常量,每一个就对应一个(类)单词。这些枚举常量提供给Lex.l使用,每一个对应一个单词的种类码;同时在Parser.y中,这些枚举常量,每一个对应一个终结符。联合使用FLEX和Bison构造词法、语法分析器的工作流程图示意图如图所示。

    这个流程中,以语法分析作为主体,在语法分析过程中,每当需要读入下一个符号(单词)时,调用词法分析器,得到一个单词的(单词种类码,单词的自身值),其控制流程如图2-2所示。

    /*实验参考书籍《编译原理实践与指导教程》、《Flex&Bison》*/
    /*yylineno记录行号*/
    %option yylineno
    /*声明部分*/
    %{
        #include "parser.tab.h"	/*bison编译parser.y产生的文件*/
        #include <string.h>
        #include "def.h"		/*自定义数据结构、函数头文件*/
        int yycolumn = 1;
        #define YY_USER_ACTION yylloc.first_line=yylloc.last_line=yylineno; yylloc.first_column=yycolumn; yylloc.last_column=yycolumn+yyleng-1; yycolumn+=yyleng;
        typedef union{
            int type_int;
            float type_float;
            char type_char;
            char type_id[32];
            struct node *ptr;
        }YYLVAL;
        #define YYSTYPE YYLVAL
    %}
    
    /*辅助定义*/
    id [A-Za-z][A-Za-z0-9]*
    int [0-9]+
    float ([0-9]*.[0-9]+)|([0-9]+.)
    
    
    /*规则部分:正规表达式+动作, 词法分析器识别出一个单词后,将该单词对应的字符串保存在 yytext中,其长度为yyleng*/
    /* 通过yylval.type_int=atoi(yytext);将整常数的值保存在yylval的成员type_int中,这里 yylval 是一个 Flex 和 Bison 共用的内部变量,类型为 YYLVAL,按这样的方式,在 Flex 中通过 yylval 的成员保存单词属性值,在 Bison 中就可以通过yylval 的成员取出属性值,实现了数据的传递*/
    %%
     /*注释处理 单行+多行*/
    //[^
    ]*  {;}	//匹配注释的正则表达式
    /*(s|.)*?*/ {;}//匹配注释的正则表达式
    {int} {yylval.type_int=atoi(yytext);return INT;}
    {float} {yylval.type_float=atof(yytext); return FLOAT;}
    "int" {strcpy(yylval.type_id,yytext); return TYPE;}
    "float" {strcpy(yylval.type_id,yytext); return TYPE;}
    "char" {strcpy(yylval.type_id,yytext); return TYPE;}
    "return" {return RETURN;}
    "if" {return IF;}
    "else" {return ELSE;}
    "while" {return WHILE;}
    "for" {return FOR;}
    {id} {strcpy(yylval.type_id,yytext); return ID;}
    
    ";" {return SEMI;}
    "," {return COMMA;}
    ">"|"<"|">="|"<="|"=="|"!=" {strcpy(yylval.type_id,yytext); return RELOP;}
    "=" {return ASSIGNOP;}
    "+" {return PLUS;}
    "-" {return MINUS;}
    "+=" {return COMADD;}
    "-=" {return COMSUB;}
    "++" {return AUTOADD;}
    "--" {return AUTOSUB;}
    "*" {return STAR;}
    "/" {return DIV;}
    "&&" {return AND;}
    "||" {return OR;}
    "!" {return NOT;}
    "(" {return LP;}
    ")" {return RP;}
    "[" {return LB;}
    "]" {return RB;}
    "{" {return LC;}
    "}" {return RC;}
    [
    ] {yycolumn=1;}
    [ 
    	] {;}
    .   {printf("Error type A: Mysterious character"%s" at line %d,column %d
    ",yytext,yylineno,yycolumn);}/*输出词法分析错误编号、异常符号串、错误行列号*/
    
    
    %%
    /* 复制到lex.yy.c中,冲突不能用了
    void main(int argc,char *argv[]){
        yylex();
        return;
    }
    */
    int yywrap(){
        return 1;
    }
    
  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/CSE-kun/p/13968622.html
Copyright © 2011-2022 走看看