声明:
该文章都是自己的一个记录,并不完全,推荐直接查看《flex与bison 中文版》,南京大学做的一个译本。
安装:
sudo apt-get install flex bison
Flex:
先看一个简单的例子:flex.l,该例子是一个简单的计算输入的单词字母数和行数:
/*definitions : alias re-string*/
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
letter [a-zA-Z]+
%%
{letter} {words ++; chars += yyleng; }
\n {chars++; lines ++;}
. {chars++;}
%%
/*user subroutines*/
int main(int argc, char** argv) {
if (argc > 1) {
/*这里是从外部拿文件数据,如果没有的话,在运行yylex()时会检测yyin是否为空,为空则赋值为stdin
然后使用yy_create_buffer创建一个缓存区,yy_switch_to_buffer将数据写入*/
if (!(yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return 1;
}
}
yylex();
/*flex的词法分析,如果action中没有return记号,会一直进行下去,如果有记号,词法分析会在下次调用yylex()之后继续。
记号会有一个number属性,可以在yylval中拿到该属性*/
printf("lines are %d words are %d chars are %d\n", lines, words, chars);
return 0;
}
/* 到达文件末尾的回调函数 */
int yywrap(void)
{
/* We reached the end of the input file... */
/* Should we continue with another file? */
/* If so:
* open the new file...
* return 0;
*/
/* to stop processing...
* return 1;
*/
return 1; /* Stop scanning at end of input file. */
}
格式由分隔符%%分为三个部分:
1.声明和选项设置
2.Pattern + action (正则表达式+匹配后的动作)
注意action是可以返回token记号的,记号有Number和value两个属性,number是自动从258开始的,也可以手动设置。
3.是会被拷贝到生成的词法分析器里面的C代码,通常是与action相关的。
运行起来比较简单:
flex flex.ll
gcc lex.yy.c -lfl -o scanner
./scanner 文件名
Start Conditions(启动条件):
%x为独占式启动条件,%s为非独占式启动条件。
独占和非独占条件的区别在于独占式条件会使得只有符合该条件的规则激活,而非独占条件并不影响其他规则是否激活,独占式条件相当于一个独立的子scanner,可以处理类似与注释等信息。
例如%x S,开启条件使用的是BEGIN(S),然后带有<s>前缀条件的规则会被激活。
参考: