1. Lex파일 만들기 (calc.l)
%{
%}
%%
"quit" { exit(0); }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/" { return DIVIDE; }
"(" { return '('; }
")" { return ')'; }
[ \t] ;
"\n" { return '\n'; }
. ;
2. Yacc 파일 만들기 (calc.y)
%{
#include <stdio.h>
extern int yylex();
void yyerror(const char *s);
%}
%token NUMBER
%token PLUS MINUS TIMES DIVIDE
%left PLUS MINUS
%left TIMES DIVIDE
%%
stat_list:
| stat_list stat
;
stat: expr '\n' { printf("= %d\n", $1); }
;
expr: NUMBER { $$ = $1; }
| expr PLUS expr { $$ = $1 + $3; }
| expr MINUS expr { $$ = $1 - $3; }
| expr TIMES expr { $$ = $1 * $3; }
| expr DIVIDE expr {
if ($3 == 0) yyerror("Divide by zero");
else $$ = $1 / $3;
}
| MINUS expr %prec MINUS {$$ = -$2; }
| '(' expr ')' { $$ = $2; }
;
%%
#include "lex.yy.c"
void yyerror(const char *s){
fprintf(stderr, "Error: %s\n", s);
}
int main() {
printf("Chobocho'c Calc V0.1\n");
return yyparse();
}
3. Make파일 만들기
CC = gcc
LIBS = -lfl
LEX = flex
YACC = yacc
all: calc2
calc2: y.tab.c lex.yy.c
$(CC) -o calc2 y.tab.c $(LIBS)
y.tab.c: calc.y
$(YACC) -dv calc.y
lex.yy.c: calc.l
$(LEX) calc.l
clean:
rm y.tab.h
rm y.tab.c
rm y.tab.h.pch
rm lex.yy.c
rm calc2
4. 빌드 & 실행