flex
- 编写a.lex文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| %{ int wordCount=0; int numcount=0; %} chars [A-Za-z\_\'\.\"] numbers ([0-9])+ delim [" "\n\t] whitespace {delim}+ words {chars}+ %% while {printf("%s\n",yytext);} {words} { wordCount++; /* increase the word count by one*/ } {whitespace} { /* do nothing*/ } ([0-9])+ { numcount++; /* one may want to add some processing here*/ } %% void main() { printf("ok1\n"); yylex(); /* start the analysis*/ printf("ok2\n"); printf("No of words: %d\n number: %d\n", wordCount, numcount); return 0; } int yywrap() { return 1; }
|
第一步命令 flex a.lex得到lex.yy.c
第二步命令 gcc -o a lex.yy.c得到a.exe (词法分析器)
待分析文件b.c
1 2 3 4 5
| asd asdf 23 q a1 b2 !#@ while
|
- 使用命令
a.exe <b.c> a.txt , 分析结果保存在a.txt
1 2 3 4 5
| ok1 !#@while ok2 No of words: 5 number: 3
|
注意在cmd下运行,linux更优,不要在Powershell,会有<字符冲突
bison
- 首先使用flex工具输入构词规则序列 , 文件
token.l
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| %{ #include "expr.tab.h" %}
%% "q" return STOP; "(" return LP; ")" return RP; "\+" return PLUS; "\-" return MINUS; "\*" return MUL; "\/" return DIV;
[0-9]+ {yylval=atoi(yytext); return DIGIT;} %%
|
- 使用命令
flex token.l,得到lex.yy.c
- 输入上下文无关文法,文件
expr.y
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| %{ #include <stdio.h> %}
%token DIGIT STOP LP RP PLUS MINUS MUL DIV
%% start: expr STOP {printf("expr=%d\n", $1); exit(1);} ; expr: expr PLUS expr {$$=$1+$3;} |expr MINUS expr {$$=$1-$3;} |expr MUL expr {$$=$1*$3;} |expr DIV expr {$$=$1/$3;} |LP expr RP {$$=$2;} |DIGIT {$$=$1;} ; %%
main(){ printf("Type something followed by Return. Type 'q' to end.\n"); printf("\n"); return(yyparse()); /*Start the parser*/ }
yyerror(s) char *s; { printf("yacc error: %s\n",s); }
yywrap(){ return(0); }
|
第二个命令 bison -d expr.y, 得到 expr.tab.c及expr.tab.h
gcc lex.yy.c expr.tab.c -o expr 得到语法分析程序expr.exe
使用语法分析程序分析输入文件b.c expr <b.c> a.txt, 得到a.txt
输入
输出
1 2
| Type something followed by Return. Type 'q' to end. expr=115
|