Flex and Bison in vs2019

  1. 新建c++控制台项目

  2. 添加筛选器文件夹 "FlexBison"和"Generator Files"

  3. 在"FlexBison"下创建"lexer.l"和"parser.y"文件

  4. 右键"lexer.l"属性

命令行: win_flex --wincompat -o %(Filename).cc %(Identity)
输出: %(Filename).cc
附加依赖项: parser.y

  1. 右键"parser.y"属性

命令行: win_bison --no-line -o %(Filename).cc %(Identity)
输出: %(Filename).cc ; %(Filename).h

  1. 右键"lexer.l"编译,将生成"lexer.cc"文件

  2. 右键"parser.y"编译,将生成"parser.h"和"parser.cc"文件

  3. 将"lexer.cc","parser.h"和"parser.cc"添加现有项到"Generator Files"下

  4. 右键项目,生成

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;
}

posted @ 2021-05-17 15:52  Ajanuw  阅读(261)  评论(0编辑  收藏  举报