flex & bison

说明

自动化词法语法分析的工具

工具一览表

这里主要学习使用Flex/Bison

Flex/Bison安装与下载

教程
百度云盘下载

hello world (傻瓜式教程)

环境 :windows10 + MinGW64 + g++ + flex + bison
首先按教程安装、配置flex、bison的相关东西
下载MinGW64,网上下载,或者拉开你的编译器,找到MinGW64

然后把路径 C:\Program Files (x86)\Dev-Cpp\MinGW64\bin添加到系统-环境变量-path中即可
这一步是为了在命令行里面用g++


/demo
+--- demo
   |
   +--- bison_code.cpp
   +--- flex_code.cpp
   +--- run.bat

run.bat

@echo off

copy bison_code.cpp bison_code.y >> nul

bison -d -obison.cpp bison_code.y

del bison_code.y  >> nul

flex -oflex.cpp flex_code.cpp

g++ -o demo bison.cpp flex.cpp -std=c++11

demo

flex_code.cpp

%option noyywrap yylineno
%{
	#include "bison.hpp"
	#include <string> 
	#include <iostream>
	void lexerror(std::string s)
	{
		std::cerr << "in lexerror :: " << s << std::endl;
	}
%}

%% 
"+" {
	return ADD;
}
"*" {
	return MUL;
}
[0-9]+		{
	yylval.result = atoi(yytext);
	return NUMBER;
	}
\n		{
	return EOL;
}

.		{
	lexerror(std::string("unknow character :: ") + 
	         std::string("in line: ") + 
			 std::to_string(yylineno));
}
%%

bison_code.cpp

%{
    #include <iostream>
	using namespace std;
	void yyerror(const char *s)
	  {
	  	cerr << "yyerror::" << s << endl;
	   } 
	int yylex();
%}
%union{
	int result;
}
%token NUMBER
%left ADD
%left MUL
%token EOL
%type <result> exp NUMBER

%%
calclist:
	| calclist exp EOL {cout << "ans = " << $2 << "\n";cout << "mzb> ";}
	| calclist EOL {cout << "mzb> ";}
	;
exp:
	  NUMBER	{$$ = $1;}
	| exp ADD exp {$$ = $1 + $3;}
	| exp MUL exp {$$ = $1 * $3;}
	;
%%
int main()
  {
  	cout << "mzb> ";
  	yyparse();
  	return 0;
  }

深入理解Flex

Flex的正则表达式是POSIX扩展正则表达式

配置行号

%option noyywrap yylineno
然后就可以在代码中使用yylineno
cout << " + " << yytext << " = " << yylineno << endl;

编译配置

flex -odemo.cpp flex_code.cpp  // 注意 -odemo.cpp 不是-o demo.cpp,并且对于输入文件的后缀没有要求
g++ demo.cpp 

输入输出配置

最简单粗暴有效的办法是直接对yyin、yyout两个FILE*变量赋值
输出用fprintf(yyout)即可

yylex

核心的函数,int yytext()
最简单的调用,while (yylex() != 0);
返回值标记token,同时有一个全局char*变量yytext指向当前token的内容

深入理解bison

编译配置

bison -d -odemo.cpp demo.y
因为flex需要bison生成的符号表(具体在flex_code.cpp里面需要include此头文件),所以这里需要-d参数,同时bison要求输入文件的后缀为.y
会生成demo.cpp(语法分析器) demo.hpp(符号表)

g++ -o demo bison_code.tab.cpp lex.yy.cpp AST.cpp -std=c++11

词法分析器是作为 .o 文件链接到语法分析器里面的

posted @ 2021-12-04 22:08  XDU18清欢  阅读(613)  评论(0)    收藏  举报