# flex와 bison 사용방법
# flex & bison 설치
# MS-Windows
# MAC OS
# for intel chip
% brew install bison
1
# for apple silicon arm64
% arch -arm64 brew install bison
1
# Linux (Ubuntu)
% sudo apt-get update
% sudo apt install flex
% sudo apt install bison
1
2
3
2
3
# flex를 이용해서 스캐너 만들기
# 코드 작성 (calc.l)
%option noyywrap
%option never-interactive
%{
#include <stdio.h>
#define T_FLOAT 1
#define T_INT 2
#define T_PLUS 3
#define T_MINUS 4
#define T_MULTIPLY 5
#define T_DIVIDE 6
#define T_LEFT 7
#define T_RIGHT 8
double fval;
int ival;
%}
%%
[ \t] ; // ignore all whitespace
[0-9]+\.[0-9]+ {fval = atof(yytext); return T_FLOAT;}
[0-9]+ {ival = atoi(yytext); return T_INT;}
"+" {return T_PLUS;}
"-" {return T_MINUS;}
"*" {return T_MULTIPLY;}
"/" {return T_DIVIDE;}
"(" {return T_LEFT;}
")" {return T_RIGHT;}
%%
int main(int argc, char** argv) {
yy_scan_string("314 * (1.23 + 2)");
int result = yylex();
while (result) {
switch(result) {
case T_FLOAT: printf(" - T_FLOAT: %g \n", fval); break;
case T_INT: printf(" - T_INT: %d \n", ival); break;
case T_PLUS: printf(" - T_PLUS: %s \n", yytext); break;
case T_MINUS: printf(" - T_MINUS: %s \n", yytext); break;
case T_MULTIPLY: printf(" - T_MULTIPLY: %s \n", yytext); break;
case T_DIVIDE: printf(" - T_DIVIDE: %s \n", yytext); break;
case T_LEFT: printf(" - T_LEFT: %s \n", yytext); break;
case T_RIGHT: printf(" - T_RIGHT: %s \n", yytext); break;
}
result = yylex();
}
}
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 컴파일 및 실행
% flex calc.l
% gcc lex.yy.c -o calc
% ./calc
- T_INT: 314
- T_MULTIPLY: *
- T_LEFT: (
- T_FLOAT: 1.23
- T_PLUS: +
- T_INT: 2
- T_RIGHT: )
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 사칙연산 계산기 만들기
# flex 코드 (calc.l)
%option noyywrap
%option never-interactive
%{
#include <stdio.h>
#include "calc.tab.c"
%}
%%
[ \t] ; // ignore all whitespace
[0-9]+\.[0-9]+ {yylval.fval = atof(yytext); return T_FLOAT;}
[0-9]+ {yylval.fval = atof(yytext); return T_FLOAT;}
"+" {return T_PLUS;}
"-" {return T_MINUS;}
"*" {return T_MULTIPLY;}
"/" {return T_DIVIDE;}
"(" {return T_LEFT;}
")" {return T_RIGHT;}
%%
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# bison 코드 (calc.y)
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
extern int yyparse();
void yyerror(const char* s);
%}
%union {
float fval;
}
%token<fval> T_FLOAT
%token T_PLUS T_MINUS T_MULTIPLY T_DIVIDE T_LEFT T_RIGHT
%left T_PLUS T_MINUS
%left T_MULTIPLY T_DIVIDE
%type<fval> expression
%%
calculation:
expression { printf("\tResult: %f\n", $1);}
;
expression:
T_FLOAT { $$ = $1; }
| expression T_PLUS expression { $$ = $1 + $3; }
| expression T_MINUS expression { $$ = $1 - $3; }
| expression T_MULTIPLY expression { $$ = $1 * $3; }
| expression T_DIVIDE expression { $$ = $1 / $3; }
| T_LEFT expression T_RIGHT { $$ = $2; }
;
%%
int main() {
return yyparse();
}
void yyerror(const char* s) {
fprintf(stderr, "Parse error: %s\n", s);
exit(1);
}
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
33
34
35
36
37
38
39
40
41
42
43
44
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
33
34
35
36
37
38
39
40
41
42
43
44
# 컴파일 및 실행
% flex calc.l
% bison calc.y
% gcc lex.yy.c -o calc
% ./calc
2 * (3 + 4)
[ctrl + D]
Result: 14.000000
1
2
3
4
5
6
7
2
3
4
5
6
7