Flex&Bison

Flex 与 Bison

《Flex 与 Bison》阅读笔记

Flex 和 Bison 简介

第一个 Flex 程序

字符统计 fbl-1.l

%{
    int chars = 0;
    int words = 0;
    int lines = 0;
%}

%%

[^ \t\n\r\f\v]+   { words++; chars += strlen(yytext); }
\n    { chars++; lines++; }
.    { chars++; }

%%

int main(int argc, char **argv)
{
    yylex();
    printf("%8d%8d%8d\n", lines, words, chars);
}

img

img

纯 Flex 的程序

英式英语到美式英语 fbl-2.l

/* 英式英语 -> 美式英语 */
%%
"colour" { printf("color"); }
"flavour" { printf("flavor"); }
"clever" { printf("smart"); }
"conservative" { printf("liberal"); }
. { printf("%s",yytext); }
%%

Flex 与 Bison 协同工作

同时使用 flex 和 bison 的程序。一个简单的 flex 词法分析器 fbl-3.l,识别出用于计算器的记号并把他们输出。

%%
"+"    { printf("PLUS\n"); }
"-"    { printf("MINUS\n"); }
"*"    { printf("TIMES\n"); }
"/"    { printf("DIVIDE\n"); }
"|"    { printf("ABS\n"); }
[0-9]+ { printf("NUMBER %s\n", yytext); }
\n     { printf("NEWLINE\n"); }
[\t]   { }
.      { printf("Mystery character %s\n", yytext); } //其他模式所没有匹配的内容
%%

img

img

计算器词法分析器

修改上一个词法分析器,它所返回的记号可以被语法分析器用来实现一个计算器。fbl-4.l。

%{
    enum yytokentype {
        NUMBER = 258,
        ADD = 259,
        SUB = 260,
        MUL = 261,
        DIV = 262,
        ABS = 263,
        EOL = 264
    };
    int yylval;
%}

%%

"+"         { return ADD; }
"-"         { return SUB; }
"*"         { return MUL; }
"/"         { return DIV; }
"|"         { return ABS; }
[0-9]+      { yylval = atoi(yytext); return NUMBER; }
\n          { return EOL; }
[\t]        { }
.           { printf("Mystery character %c\n", *yytext); }
%%

int main(int argc, char **argv)
{
    int tok;

    while (tok = yylex()) {
        printf("%d", tok);
        if (tok == NUMBER) printf(" = %d\n", yylval);
        else printf("\n");
    }
}

Bison 简单的计算器

规则的描述

img

计算器的 bison 代码,fbl-5.y

%{
    #include <stdio.h>
    int main();
    void yyerror();
    int yylex();
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%

calclist: /* 空规则 */
    | calclist exp EOL { printf("= %d\n", $2); }
    ;

exp : factor         { $$ = $1; }
    | exp ADD factor { $$ = $1 + $3; }
    | exp SUB factor { $$ = $1 - $3; }
    ;

factor : term            { $$ = $1; }
       | factor MUL term { $$ = $1 * $3; }
       | factor DIV term { $$ = $1 / $3; }
       ;
term : NUMBER   { $$ = $1; }
     | ABS term { $$ =  $2 > 0 ? $2 : -$2; }
     ;

%%

int main(int argc, char ** argv)
{
    yyparse();
}
void yyerror(char *s)
{
    fprintf(stderr, "error: %s\n", s);
}

img

img

计算器的词法分析器

修改 fbl-4.l 得到,计算器词法分析器 fb1-5.l,以便于让我们可以在语法分析器里面直接调用它。具体就是我们包含了 bison 为我们创建的头文件,而不是在第一部分里自己定义记号值。同时我们也删除了第三部分,因为语法分析器会调用词法分析器。

%{
    #include "fbl-5.tab.h"
%}

%%
"+"         { return ADD; }
"-"         { return SUB; }
"*"         { return MUL; }
"/"         { return DIV; }
"|"         { return ABS; }
[0-9]+      { yylval = atoi(yytext); return NUMBER; }
\n          { return EOL; }
[\t]        { }
.           { printf("Mystery character %c\n", *yytext); }

%%

makefile

fbl-5:fbl-5.l fbl-5.y
	bison -d fbl-5.y
	flex fbl-5.l
	cc -o $@ fbl-5.tab.c lex.yy.c -lfl

img

posted on 2024-01-13 18:11  LambdaQ  阅读(12)  评论(0编辑  收藏  举报