先上flex文件:
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "simple_compiler.tab.h"
#define YY_SKIP_YYWRAP
extern int yylval;
int yylex(void);
static int var_save(char* v) {
char* p = (char*)malloc(32);
sprintf(p, "%s", v);
return (int)p;
}
static int new_var(void) {
static int index = 0;
char* p = (char*)malloc(16);
sprintf(p, "r_%d", index++);
return (int)p;
}
static int function_paras(int para0, int para1) {
char* p = (char*)malloc(128);
sprintf(p, "%s, %s", (const char*)para0, (const char*)para1);
free((char*)para0);
free((char*)para1);
return (int)p;
}
static int function_call(int func) {
char* p = (char*)malloc(256);
sprintf(p, "%s()", (const char*)func);
free((char*)func);
return (int)p;
}
static int function_callp(int func, int paras) {
char* p = (char*)malloc(256);
sprintf(p, "%s(%s)", (const char*)func, (const char*)paras);
free((char*)func);
free((char*)paras);
return (int)p;
}
%}
num [0-9]+
hex "0x"[0-9a-fA-F]+
bin "0b"[01]+
_var [_a-zA-z]+[_a-zA-z0-9]*
_equal "="
_lp_s "("
_rp_s ")"
_split1 ","
_split2 ";"
_plus "+"
_minus "-"
_mul "*"
_divide "/"
_mod "%%"
_shift_r ">>"
_shift_l "<<"
_not "~"
_more ">"
_less "<"
_more_equal ">="
_less_equal "<="
_equal_equal "=="
_not_equal "!="
_next_line [\n]+
space [ \t]+
%%
{num} {
yylval = var_save(yytext);
return var;
}
{hex} {
yylval = var_save(yytext);
return var;
}
{bin} {
yylval = var_save(yytext);
return var;
}
{_var} {
yylval = var_save(yytext);
return var;
}
{_lp_s} {
return lp_s;
}
{_rp_s} {
return rp_s;
}
{_split1} {
return split1;
}
{_split2} {
return split2;
}
{_plus} {
return plus;
}
{_minus} {
return minus;
}
{_mul} {
return mul;
}
{_divide} {
return divide;
}
{_mod} {
return mod;
}
{_shift_r} {
return shift_r;
}
{_shift_l} {
return shift_l;
}
{_not} {
return not;
}
{_more} {
return more;
}
{_less} {
return less;
}
{_more_equal} {
return more_equal;
}
{_less_equal} {
return less_equal;
}
{_equal_equal} {
return equal_equal;
}
{_not_equal} {
return not_equal;
}
{_equal} {
return equal;
}
{_next_line} {
return next_line;
}
{space} {
}
. {
}
%%
再上yacc文件:
%{
#include <stdio.h>
#define YYSTYPE int
#include "lex.yy.c"
int yyparse(void);
void yyerror(char* s);
%}
%token dig var lp_s rp_s plus minus mul divide mod shift_r shift_l not more less more_equal less_equal equal_equal not_equal equal split1 split2 next_line
%%
code_lines: code_lines code_line next_line {}
| code_line next_line {}
;
code_line: code split2 {}
;
code: var_set {}
| var_level5 {}
;
var_set: var equal var_level5 {printf("%s = %s;\n", (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
;
var_level5: var_level5 more var_level4 {$$ = new_var(); printf("%s = %s > %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level5 less var_level4 {$$ = new_var(); printf("%s = %s < %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level5 more_equal var_level4 {$$ = new_var(); printf("%s = %s >= %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level5 less_equal var_level4 {$$ = new_var(); printf("%s = %s <= %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level5 equal_equal var_level4 {$$ = new_var(); printf("%s = %s == %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level5 not_equal var_level4 {$$ = new_var(); printf("%s = %s != %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level4 {$$ = $1;}
;
var_level4: var_level4 shift_r var_level3 {$$ = new_var(); printf("%s = %s >> %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level4 shift_l var_level3 {$$ = new_var(); printf("%s = %s << %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level3 {$$ = $1;}
;
var_level3: var_level3 plus var_level2 {$$ = new_var(); printf("%s = %s + %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level3 minus var_level2 {$$ = new_var(); printf("%s = %s - %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level2 {$$ = $1;}
;
var_level2: var_level2 mul var_level1 {$$ = new_var(); printf("%s = %s * %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level2 divide var_level1 {$$ = new_var(); printf("%s = %s / %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level2 mod var_level1 {$$ = new_var(); printf("%s = %s %% %s;\n", (char*)$$, (char*)$1, (char*)$3); free((char*)$1); free((char*)$3);}
| var_level1 {$$ = $1;}
;
var_level1: var {$$ = $1;}
| not var {$$ = new_var(); printf("%s = ~%s;\n", (char*)$$, (char*)$1); free((char*)$1);}
| func_call {$$ = $1;}
| not func_call {$$ = new_var(); printf("%s = ~%s;\n", (char*)$$, (char*)$1); free((char*)$1);}
| lp_s var_level5 rp_s {$$ = $2;}
;
func_call: var lp_s rp_s {$$ = new_var(); printf("%s = %s;\n", (char*)$$, (char*)function_call($1));}
| var lp_s func_para rp_s {$$ = new_var(); printf("%s = %s;\n", (char*)$$, (char*)function_callp($1, $3));}
;
func_para: var_level5 {$$ = $1;}
| func_para split1 var_level5 {$$ = function_paras($1, $3);}
;
%%
int main(int argc, char *argv[]) {
return yyparse();
}
int yywrap(void) {
return 1;
}
void yyerror(char* s) {
printf("error: %s\n", s);
}
转换成c文件
bison.exe -d simple_compiler.y
flex simple_compiler.l
编译成exe,测试:
输入文件:
输出文件:
离线