flex

  1. 编写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;
}
  1. 第一步命令 flex a.lex得到lex.yy.c

  2. 第二步命令 gcc -o a lex.yy.c得到a.exe词法分析器

  3. 待分析文件b.c

1
2
3
4
5
asd asdf 23 q 
a1
b2
!#@
while
  1. 使用命令 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

  1. 首先使用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;}
%%
  1. 使用命令 flex token.l,得到lex.yy.c
  2. 输入上下文无关文法,文件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);
}
  1. 第二个命令 bison -d expr.y, 得到 expr.tab.cexpr.tab.h

  2. gcc lex.yy.c expr.tab.c -o expr 得到语法分析程序expr.exe

  3. 使用语法分析程序分析输入文件b.c expr <b.c> a.txt, 得到a.txt

  • 输入

    1
    55+(3*20)q
  • 输出

    1
    2
    Type something followed by Return. Type 'q' to end.
    expr=115