初探 1
什么是Flex和Bison?
Flex是一个词法分析器,是unix lex的gnu克隆,作用是把"词"抽象成符号,供程序识别%{
#include
using namespace std;
%}
%%
[0-9]+ { cout << "Number "; }
[a-zA-Z]+ { cout << "Word "; }
[ \t] ; //忽略空格
%%
flex -otest1ll.c test1ll.l
g++ test1ll.c -otest1 -lfl
./test1
%{
#include
using namespace std;
int yylex(); //只是一个声明
int yyerror(const char *); //必须要有
%}
%token Number
%token Word
%union {
int iv;
char *sv;
}
%%
main : main Number Word Word Number '\n' { cout << $2 + $5 << $3 << $4 << endl ; free($3) ; free($4) ; //因为我们使用strdup }
| //空
;
%%
int yyerror(const char *emseg)
{
cout << "Error: " << emseg << endl;
}
int main()
{
yyparse();
}
exp : exp + exp
| exp - exp
| int //一个数字
它的意思是,表达式exp有三种可能可以是两个exp表达式相加或者相减,也可能就是一个数字,是一个递归,这样,我们就很清晰地给 5 5+3 5+3-6+1 这样的算式提供了规则
上面,我们给两个数字夹两个单词的语法定义了规则,输出则是两个数字相加然后再连接两个单词
在bison,BNF范式的写法是
表达式 : 表达式1 表达式2 ... {当匹配后执行的代码}
| 表达式 .... { ... }
| .... { ... }
....
;
%{
#include
#include "test1yy.h" //由bison生成
extern int yyerror(const char *);
using namespace std;
%}
%%
[0-9]+ { yylval.iv = strtol(yytext,0,10); return Number; }
[a-zA-Z]+ { yylval.sv = strdup(yytext); return Word; }
[ \t] ; //忽略空格
\n { return *yytext; } //直接返回换行符作为符号给bison
%%
int yywrap()
{
return 1;
}
bison -d -otest1yy.c test1yy.y
flex -otest1ll.c test1ll.l
g++ test1*.c -otest1
./test1