Flex and Bison in vs2019
-
新建c++控制台项目
-
添加筛选器文件夹 "FlexBison"和"Generator Files"
-
在"FlexBison"下创建"lexer.l"和"parser.y"文件
-
右键"lexer.l"属性
命令行: win_flex --wincompat -o %(Filename).cc %(Identity)
输出: %(Filename).cc
附加依赖项: parser.y
- 右键"parser.y"属性
命令行: win_bison --no-line -o %(Filename).cc %(Identity)
输出: %(Filename).cc ; %(Filename).h
-
右键"lexer.l"编译,将生成"lexer.cc"文件
-
右键"parser.y"编译,将生成"parser.h"和"parser.cc"文件
-
将"lexer.cc","parser.h"和"parser.cc"添加现有项到"Generator Files"下
-
右键项目,生成
lexer.l:
%option noyywrap noline
%{
#pragma warning (disable: 4005)
#include <iostream>
#include <cmath>
using namespace std;
#include "parser.h"
%}
NUMB ([0-9]+)|([0-9]*\.[0-9]+)
%%
{NUMB} { yylval = atof(yytext); return NUM; }
[+*/()-] { return yytext[0]; }
[\n] { return '\n'; }
[ \t] { /* empty */ }
"quit" { yyterminate(); }
. /* nothing, eat up */
%%
parser.y:
%defines "parser.h"
%{
#include <cmath>
#include <cstdio>
#include <iostream>
#pragma warning (disable: 4005)
extern int yylex();
extern void yyerror(const char*);
using namespace std;
%}
%define api.value.type { double }
%token NUM
%left '-' '+'
%left '*' '/'
%%
input: %empty
| input line
;
line: '\n'
| exp '\n' { cout << " =>" << $1 << endl; }
;
exp: NUM { $$ = $1; }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '(' exp ')' { $$ = $2; }
;
%%
main.cpp
#include <iostream>
#include "parser.h"
using namespace std;
int main()
{
yyparse();
return 0;
}
void yyerror(const char* msg)
{
cout << "Error: " << msg << endl;
}