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);
}
纯 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); } //其他模式所没有匹配的内容
%%
计算器词法分析器
修改上一个词法分析器,它所返回的记号可以被语法分析器用来实现一个计算器。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 简单的计算器
规则的描述
计算器的 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);
}
计算器的词法分析器
修改 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