先贴代码吧:
1,pre_compiler.l
%{
#include <stdio.h>
#include <string.h>
#include "pre_compiler.tab.h"
#define YY_SKIP_YYWRAP
extern int yylval;
int yylex(void);
typedef struct {
char name[128];
int init;
int value;
}var_store;
static var_store var_store_buf[8192];
static int var_store_cnt = 0;
static void exp_store_print(FILE* file, int index) {
fprintf(file, (const char*)"%s\n", (const char*)var_store_buf[index].name);
}
static int exp_store0(int num) {
sprintf((char*)var_store_buf[var_store_cnt].name, (const char*)"%d", num);
var_store_buf[var_store_cnt].init = 0;
var_store_buf[var_store_cnt++].value = 0;
return var_store_cnt - 1;
}
static int exp_store1(const char* str, int a) {
char* p_a;
if ((a < 0) || (a >= var_store_cnt)) {
return -1;
}
p_a = (char*)var_store_buf[a].name;
sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a);
var_store_buf[var_store_cnt].init = 0;
var_store_buf[var_store_cnt++].value = 0;
return var_store_cnt - 1;
}
static int exp_store2(const char* str, int a, int b) {
char* p_a;
char* p_b;
if ((a < 0) || (a >= var_store_cnt) || (b < 0) || (b >= var_store_cnt)) {
return -1;
}
p_a = (char*)var_store_buf[a].name;
p_b = (char*)var_store_buf[b].name;
sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a, p_b);
var_store_buf[var_store_cnt].init = 0;
var_store_buf[var_store_cnt++].value = 0;
return var_store_cnt - 1;
}
static int exp_store3(const char* str, int a, int b, int c) {
char* p_a;
char* p_b;
char* p_c;
if ((a < 0) || (a >= var_store_cnt) || (b < 0) || (b >= var_store_cnt) || (c < 0) || (c >= var_store_cnt)) {
return -1;
}
p_a = (char*)var_store_buf[a].name;
p_b = (char*)var_store_buf[b].name;
p_c = (char*)var_store_buf[c].name;
sprintf((char*)var_store_buf[var_store_cnt].name, str, p_a, p_b, p_c);
var_store_buf[var_store_cnt].init = 0;
var_store_buf[var_store_cnt++].value = 0;
return var_store_cnt - 1;
}
static void var_store_init(void) {
for (var_store_cnt = 4095; ; var_store_cnt--) {
strcpy((char*)var_store_buf[var_store_cnt].name, (const char*)"");
var_store_buf[var_store_cnt].value = 0;
var_store_buf[var_store_cnt].init = 0;
if (0 == var_store_cnt) {
break;
}
}
}
static int var_store_read(int index) {
if ((index >= 0) && (index < var_store_cnt) && var_store_buf[index].init) {
return var_store_buf[index].value;
}
return 0;
}
static void var_store_write(int index, int value) {
if ((index >= 0) && (index < var_store_cnt)) {
var_store_buf[index].value = value;
var_store_buf[index].init = -1;
}
}
static int var_store_find(const char* name) {
int i;
for (i = 0; i < var_store_cnt; i++) {
if (0 == strcmp((const char*)var_store_buf[i].name, name)) {
return i;
}
}
strcpy((char*)var_store_buf[var_store_cnt].name, name);
var_store_buf[var_store_cnt].init = 0;
var_store_buf[var_store_cnt++].value = 0;
return var_store_cnt - 1;
}
static int is_var_inited(int index) {
return var_store_buf[index].init;
}
static int bin2num(const char* bin) {
int num;
if ('0' != *bin++) {
return 0;
}
if ('b' != *bin++) {
return 0;
}
for (num = 0; *bin; bin++) {
num <<= 1;
if ('1' == *bin) {
num |= 1;
}
}
return num;
}
%}
subwf "subwf"
decf "decf"
addwf "addwf"
comf "comf"
incf "incf"
sublw "sublw"
addlw "addlw"
adcwf "adcwf"
sbcwf "sbcwf"
daa "daa"
das "das"
clrf "clrf"
clrw "clrw"
iorwf "iorwf"
andwf "andwf"
xorwf "xorwf"
rrf "rrf"
rlf "rlf"
swapf "swapf"
bcf "bcf"
bsf "bsf"
andlw "andlw"
xorlw "xorlw"
iorlw "iorlw"
decfsz "decfsz"
incfsz "incfsz"
btfsc "btfsc"
btfss "btfss"
goto "goto"
call "call"
return "return"
retfie "retfie"
retlw "retlw"
movwf "movwf"
movf "movf"
movlw "movlw"
nop "nop"
option "option"
tris "tris"
sleep "sleep"
clrwdt "clrwdt"
int "int"
equ "equ"
org "org"
end "end"
label ":"
split ","
note ";"[^\n]*
next_line [\n]
space [ \t]+
plus "+"
minus "-"
times "*"
divide "/"
lp "("
rp ")"
num [0-9]+
hex1 "0x"[0-9a-fA-F]+
hex2 [0-9]+[0-9a-fA-F]*[hH]
bin "0b"[01]+
var [_a-zA-z]+[_a-zA-z0-9]*
%%
{subwf} {
yylval = var_store_find(yytext);
return SUBWF;
}
{decf} {
yylval = var_store_find(yytext);
return DECF;
}
{addwf} {
yylval = var_store_find(yytext);
return ADDWF;
}
{comf} {
yylval = var_store_find(yytext);
return COMF;
}
{incf} {
yylval = var_store_find(yytext);
return INCF;
}
{sublw} {
yylval = var_store_find(yytext);
return SUBLW;
}
{addlw} {
yylval = var_store_find(yytext);
return ADDLW;
}
{adcwf} {
yylval = var_store_find(yytext);
return ADCWF;
}
{sbcwf} {
yylval = var_store_find(yytext);
return SBCWF;
}
{daa} {
yylval = var_store_find(yytext);
return DAA;
}
{das} {
yylval = var_store_find(yytext);
return DAS;
}
{clrf} {
yylval = var_store_find(yytext);
return CLRF;
}
{clrw} {
yylval = var_store_find(yytext);
return CLRW;
}
{iorwf} {
yylval = var_store_find(yytext);
return IORWF;
}
{andwf} {
yylval = var_store_find(yytext);
return ANDWF;
}
{xorwf} {
yylval = var_store_find(yytext);
return XORWF;
}
{rrf} {
yylval = var_store_find(yytext);
return RRF;
}
{rlf} {
yylval = var_store_find(yytext);
return RLF;
}
{swapf} {
yylval = var_store_find(yytext);
return SWAPF;
}
{bcf} {
yylval = var_store_find(yytext);
return BCF;
}
{bsf} {
yylval = var_store_find(yytext);
return BSF;
}
{andlw} {
yylval = var_store_find(yytext);
return ANDLW;
}
{xorlw} {
yylval = var_store_find(yytext);
return XORLW;
}
{iorlw} {
yylval = var_store_find(yytext);
return IORLW;
}
{decfsz} {
yylval = var_store_find(yytext);
return DECFSZ;
}
{incfsz} {
yylval = var_store_find(yytext);
return INCFSZ;
}
{btfsc} {
yylval = var_store_find(yytext);
return BTFSC;
}
{btfss} {
yylval = var_store_find(yytext);
return BTFSS;
}
{goto} {
yylval = var_store_find(yytext);
return GOTO;
}
{call} {
yylval = var_store_find(yytext);
return CALL;
}
{return} {
yylval = var_store_find(yytext);
return RETURN;
}
{retfie} {
yylval = var_store_find(yytext);
return RETFIE;
}
{retlw} {
yylval = var_store_find(yytext);
return RETLW;
}
{movwf} {
yylval = var_store_find(yytext);
return MOVWF;
}
{movf} {
yylval = var_store_find(yytext);
return MOVF;
}
{movlw} {
yylval = var_store_find(yytext);
return MOVLW;
}
{nop} {
yylval = var_store_find(yytext);
return NOP;
}
{option} {
yylval = var_store_find(yytext);
return OPTION;
}
{tris} {
yylval = var_store_find(yytext);
return TRIS;
}
{sleep} {
yylval = var_store_find(yytext);
return SLEEP;
}
{clrwdt} {
yylval = var_store_find(yytext);
return CLRWDT;
}
{int} {
yylval = var_store_find(yytext);
return INT;
}
{equ} {
yylval = var_store_find(yytext);
return EQU;
}
{org} {
yylval = var_store_find(yytext);
return ORG;
}
{end} {
yylval = var_store_find(yytext);
return END;
}
{label} {
return LABEL;
}
{split} {
return SPLIT;
}
{next_line} {
return NEXT_LINE;
}
{space} {
}
{note} {
}
{num} {
sscanf(yytext, "%d", &yylval);
return NUM;
}
{hex1} {
sscanf(yytext, "0x%x", &yylval);
return NUM;
}
{hex2} {
sscanf(yytext, "%x", &yylval);
return NUM;
}
{bin} {
yylval = bin2num(yytext);
return NUM;
}
{plus} {
return PLUS;
}
{minus} {
return MINUS;
}
{times} {
return TIMES;
}
{divide} {
return DIVIDE;
}
{lp} {
return LP;
}
{rp} {
return RP;
}
{var} {
yylval = var_store_find(yytext);
if (is_var_inited(yylval)) {
yylval = var_store_read(yylval);
return NUM;
}
else {
return VAR;
}
}
. {
}
%%
离线
2,pre_compiler.y
%{
#include <stdio.h>
#define YYSTYPE int
#include "lex.yy.c"
int yyparse(void);
void yyerror(char* s);
static FILE* file_temp = NULL;
static int code_addr = 0;
%}
%token VAR NUM PLUS MINUS TIMES DIVIDE LP RP SPLIT SUBWF DECF ADDWF COMF INCF SUBLW ADDLW ADCWF SBCWF DAA DAS CLRF CLRW IORWF ANDWF XORWF RRF RLF SWAPF BCF BSF ANDLW XORLW IORLW DECFSZ INCFSZ BTFSC BTFSS GOTO CALL RETURN RETFIE RETLW MOVWF MOVF MOVLW NOP OPTION TRIS SLEEP CLRWDT INT EQU ORG END LABEL NEXT_LINE
%%
file: file NEXT_LINE {}
| codes END {fprintf(file_temp, (const char*)"end\n");}
;
codes: codes code {}
| codes pre_code {}
| codes NEXT_LINE {}
| code {}
| pre_code {}
;
code: code2 exp_var SPLIT exp_var NEXT_LINE {$$ = exp_store3("%s %s, %s", $1, $2, $4); exp_store_print(file_temp, $$);}
| code1 exp_var NEXT_LINE {$$ = exp_store2("%s %s", $1, $2); exp_store_print(file_temp, $$);}
| code0 NEXT_LINE {$$ = $1; exp_store_print(file_temp, $$);}
;
pre_code: VAR EQU exp NEXT_LINE {var_store_write($1, $3);}
| ORG exp NEXT_LINE {code_addr = $2; fprintf(file_temp, (const char*)"org %d\n", $2);}
| VAR LABEL NEXT_LINE {var_store_write($1, code_addr);}
;
code0: DAA {$$ = $1;}
| DAS {$$ = $1;}
| CLRW {$$ = $1;}
| RETURN {$$ = $1;}
| RETFIE {$$ = $1;}
| NOP {$$ = $1;}
| OPTION {$$ = $1;}
| SLEEP {$$ = $1;}
| CLRWDT {$$ = $1;}
| INT {$$ = $1;}
;
code1: SUBLW {$$ = $1;}
| ADDLW {$$ = $1;}
| CLRF {$$ = $1;}
| ANDLW {$$ = $1;}
| XORLW {$$ = $1;}
| IORLW {$$ = $1;}
| GOTO {$$ = $1;}
| CALL {$$ = $1;}
| RETLW {$$ = $1;}
| MOVWF {$$ = $1;}
| MOVLW {$$ = $1;}
| TRIS {$$ = $1;}
;
code2: SUBWF {$$ = $1;}
| DECF {$$ = $1;}
| ADDWF {$$ = $1;}
| COMF {$$ = $1;}
| INCF {$$ = $1;}
| ADCWF {$$ = $1;}
| SBCWF {$$ = $1;}
| IORWF {$$ = $1;}
| ANDWF {$$ = $1;}
| XORWF {$$ = $1;}
| RRF {$$ = $1;}
| RLF {$$ = $1;}
| SWAPF {$$ = $1;}
| BCF {$$ = $1;}
| BSF {$$ = $1;}
| DECFSZ {$$ = $1;}
| INCFSZ {$$ = $1;}
| BTFSC {$$ = $1;}
| BTFSS {$$ = $1;}
| MOVF {$$ = $1;}
;
exp_var: exp_var PLUS term_var {$$ = exp_store2("%s + %s", $1, $3);}
| exp_var MINUS term_var {$$ = exp_store2("%s - %s", $1, $3);}
| term_var {$$ = $1;}
;
term_var: term_var TIMES factor_var {$$ = exp_store2("%s * %s", $1, $3);}
| term_var DIVIDE factor_var {$$ = exp_store2("%s / %s", $1, $3);}
| factor_var {$$ = $1;}
;
factor_var: VAR {$$ = $1;}
| LP exp_var RP {$$ = exp_store1("(%s)", $2);}
| exp {$$ = exp_store0($1);}
;
exp: exp PLUS term {$$ = $1 + $3;}
| exp MINUS term {$$ = $1 - $3;}
| term {$$ = $1;}
term: term TIMES factor {$$ = $1 * $3;}
| term DIVIDE factor {$$ = $1 / $3;}
| factor {$$ = $1;}
factor: NUM {$$ = $1;}
| LP exp RP {$$ = $2;}
;
%%
int main(int argc, char *argv[]) {
file_temp = fopen((const char*)"temp.asm", "w");
if (NULL == file_temp) {
return 0;
}
var_store_init();
yyparse();
fclose(file_temp);
yyin = fopen((const char*)"temp.asm", "r");
if (NULL == yyin) {
return 0;
}
file_temp = stdout;
return yyparse();
}
int yywrap(void) {
return 1;
}
void yyerror(char* s) {
printf("error: %s\n", s);
}
离线
3,将上述文件用flex&yacc工具生成c源码文件,codeblock编译成pre_compiler.exe,一个编译器就做好了
离线
flex&yacc转换出来的c文件:
将c文件编译成exe文件:
exe文件调用方法:
汇编例程源文件demo.asm:
pre_compiler.exe将汇编文件demo.asm编译,输出中间文件temp.asm:
输出最终文件out.asm:
离线
先上传flex&yacc源文件及转换工具
flex&yacc + pre_compiler
最近编辑记录 xxzouzhichao (2018-05-04 21:29:27)
离线
再上传codeblock工程文件以及测试汇编代码:
codeblock工程文件及测试demo
离线
请教大神,怎么使用?
详细使用教程已经发上来了
离线
请教一下,能不能用gcc, 把 lex.yy.c pre_compiler.tab.c pre_compiler.tab.h 生成 pre_compiler.exe ?
离线
请教一下,能不能用gcc, 把 lex.yy.c pre_compiler.tab.c pre_compiler.tab.h 生成 pre_compiler.exe ?
肯定能啊,我就是用的codeblock做的,它就是GCC啊
附个工程截图:
离线