源码
编译前期最常实验的工具,分别是用来做 lexical analyse 和 semantic analyse 的,这两个工具的使用基本不需要很深的编译知识,只需要掌握正则表达式的书写(lexical analyse阶段使用)和上下文无关文法(semantic analyse 阶段使用)
https://gitee.com/gamebaby_admin/winflexbison.git
Flex
flex词法分析器
- 定义段,%{ … %}
- 规则段,%%段分割符, 是模式匹配的代码区域, 左边是正则表达式, 右边是匹配的 C 代码
- 用户程序段,%%段分割符
- yytext 代表匹配正则表达式的字符串
- flex 的匹配默认是从最长匹配开始, 如果有多个匹配的正则表达式, 从最早的那个开始匹配, 所以上面的模式匹配, 首先是按照单词 -> 行尾符 -> 剩余字符串的顺序进行匹配的, 不会产生重复统计的问题
- yylex 是调用 flex 的词法分析函数 yylex 进行计算,flex的入口函数,yyparser会调用
统计长度
%{int chars = 0;int words = 0;int lines = 0;
%}
letter [a-zA-Z]
%%
{letter}+ {words ++; chars += yyleng; }
\n {chars++; lines ++;}
. {chars++;}
%%
int main(int argc, char** argv) {if (argc > 1) {if (!(yyin = fopen(argv[1], "r"))) {perror(argv[1]);return 1;}}yylex();printf("lines are %d words are %d chars are %d\n", lines, words, chars);return 0;
}
demo如下test.l
%{
#include <stdio.h>
%}
%%
[a-zA-Z]+ { printf("get word: %s", yytext); }
[0-9]+ {printf("get number:%s", yytext); }
\n {printf("New line\n"); }
. { }
%%
flex test.l 生成c文件,c文件添加fl.lib依赖,可以直接生成exe,输入字符对应输出打印数据
win_flex --wincompat test.l
或者
win_flex --nounistd test.l
win_flex --header-file=lex.yy.h -nounistd test.l(输出带头文件lex.yy.h)
通过l文件生成c文件,flex是生成词法分析器的工具(c文件代码,词法分析器)
https://www.cnblogs.com/lyr2015/p/6099687.html
https://www.jianshu.com/p/bad193f67a09
Bison
bison语法分析器,格式和flex格式相同,分为定义段、规则段(BNF范式描述文法,每行代表一段规则)和用户端,%%分割段
- bison的入口函数是,yyparse
demo如下test.y,冒号左边$$,冒号右边依次是$1、$2…
calclist:/*空规则*/| calclist exp EOL { printf("=%d\n", $2); };exp: factor {$$ = $1}| exp ADD factor { $$ = $1 + $3; }| exp SUB factor { $$ = $1 - $3; };
win_bison -d test.y,输出test.tab.c和test.tab.h(带头文件)
win_bison test.y,输出test.tab.c
词法分析只保证词语的组合是正确的,还需要语义分析检测,bison不做语义分析,需要构建符号表进行语义分析。
参考:https://blog.csdn.net/qq_24421591/article/details/50085689,通过bison构建抽象语法树ast,通过符号表进行语义分析
BNF文法描述
BNF的基本语法:
- <符号> ::= <使用符号的表达式>
- 双引号(" ")中的字符串(“word”)代表这些字符本身,而double_quote代表双引号。
- 双引号外的字符串(有可能带下划线)代表语法部分。
- 尖括号(< >)中的内容为必选项。
- 方括号([ ])中的内容为可选项。
- 大括号({ })中的内容为可重复0至无限次的项。
- 竖线(|)表示其左右两侧任选一项,相当于 OR 的意思。
- ::= 符号表示 “被定义为”的意思。
整个c语言使用最短的行数描述语法规则,比自然语言简洁很多
https://blog.csdn.net/preyta/article/details/43675467
终止符:不能展开的内容
非终止符:定义项,内容可以展开
开发工具
vscode中添加以下工具
flex-bison 计算器
flex使用正则表达式匹配,bison建立语法规则
参考计算器的实现demo:https://gitee.com/sofu456/flex_bison_demo.git