Question: I write a address generater, which use micro code to generate address. For generating the micro codes easily, I create a some symbols and syntax to descrbie the micro code, things like assembly languange, as following:
/*
JDNZ Rx LABEL; {[0],[LABLE],[xx]} # x = 4~7, LABEL is 5 bits. If Rx equals 0, load Rx to initial value and
# execute next code by increase PC by 1. Otherwise, jump to LABEL to and
# run;
ADDR0 #; {[10],[######]} # add constant to R0. constant is 1~64.
SWAPR Rm Rn; {[1100],[mm],[nn]} # swap Rm and Rn, m and n are from 0 to 3
RST; {[11010],[xxx]} # reset all R to initial value
NU; {[11011],[xxx]} # addr is not usable, that means give the ack signal to data interface but
# the input data will not be saved to the internal ram.
ADD Rx; {[11100],[xxx]} # addr Rx to addr.
INCLD Rx; {[11101],[xxx]} # load Rx to addr, then increase Rx by 1
LD Rx; {[11110],[xxx]} # load Rx to addr
RSTR Rx; {[11111],[xxx]} # reset Rx to initial value
*/
// this is a comment line
// Define rbus index address and data address
INDEX = JCD_TBL_INDEX;
DATA = JCD_TBL_DATA;
init {
R0 = 0; //set the init value of Rx
R1 = 64;
R2 = 256;
R3 = 256;
R4 = 64;
R5 = 4;
R6 = 8;
R7 = 2;
}
program {
lbl0:
INCLD R0;
LD R2;
ADD R4;
INCLD R0;
INCLD R2;
ADD R4;
JDNZ R5 lbl0;
SWAPR R0 R1;
lbl1:
INCLD R0;
LD R2;
ADD R4;
INCLD R0;
INCLD R2;
ADD R4;
JDNZ R5 lbl1;
SWAPR R0 R1;
SWAPR R2 R3;
JDNZ R6 lbl0;
ADDR0 #64;
SWAPR R0 R1;
ADDR0 #64;
SWAPR R0 R1;
JDNZ R7 lbl0 ;
RST;
}
The init part inside "{" and "}" means how to initialize the R0~R7 registers. The program part inside "{" and "}" means micro code to generate the address. And INDEX is the configure register for index, DATA is the configure register for data.
Now, I need a compiler to convert the these "assembly" to appropriate micro code.
The expected output is like "RBUS[JCD_TBL_INDEX] = XXX;" or "RBUS[JCD_TBL_DATA] = XXX", which are use for C language.
Then I use flex to help me generate the pattern scanner and make the compiler works. The Flex file named compjcd.l is as following:
%{//=======================================// Compile the address generation code // into binary micro code. Please Refer// example, dec411.//=======================================#include <stdio.h>int bFindInit=0, bFindProg=0;int bFindLabel=0;int bErr = 0;int iPC=0;int iLabel=0;int aLabelPC[8];char sLabel[8][64] = {"\0", "\0", "\0", "\0"} ;char sBuff[64];char sIndex[32], sData[32];char PC[32];int iTmp, iTmp2;int i;int condition;%}%option yylineno%x COMMENT%s INIT PROGchars [A-Za-z\_]numbers ([0-9])+hex 0x([0-9])+alpha [0-9A-Za-z]words {chars}+({numbers}|{chars})*sp [\t ]%%"INDEX"{sp}*"="{sp}*({numbers}|{hex}|{words})+{sp}*";" { // find INDEX define //printf("%s\n", yytext); *(yytext+yyleng-1) = '\0'; i = 5; while(*(yytext+i) != '=') // search '=' i++; sscanf(yytext+i+1, "%s", sIndex); //printf("%s\n", sIndex); }"DATA"{sp}*"="{sp}*({numbers}|{hex}|{words})+{sp}*";" { // find DATA define //printf("%s\n", yytext); *(yytext+yyleng-1) = '\0'; i = 4; while(*(yytext+i) != '=') // search '=' i++; sscanf(yytext+i+1, "%s", sData); //printf("%s\n", sData); } "init"{sp}*"{" { //printf("[I]@%d: Find \"init\".\n", yylineno); printf("//Initialize R0~R7\n"); bFindInit=1; BEGIN( INIT ); }<INIT>"}" BEGIN( 0 );<INIT>"R"[0-7]{1}{sp}*"="{sp}*({numbers}|{hex}){sp}*";" { //printf("%s\n", yytext); *(yytext+yyleng-1) = '\0'; iTmp = atoi(yytext+1); //printf("%d\n", iTmp); i = 2; while(*(yytext+i) != '=') // search '=' i++; sscanf(yytext+i+1, "%d", &iTmp2); iTmp *= 2; iTmp += 32; printf("RBUS[%s]=0x%02X;\n", sIndex, iTmp); printf("RBUS[%s]=0x%02X;\n", sData, iTmp2&0xff); iTmp++; printf("RBUS[%s]=0x%02X;\n", sIndex, iTmp); printf("RBUS[%s]=0x%02X;\n", sData, (iTmp2>>8)&0xff); }"program"{sp}*"{" { //printf("[I]@%d: Find \"program\".\n", yylineno); printf("//Configure program\n"); printf("RBUS[%s]=0x00;\n", sIndex); iPC=0; bFindProg=1; BEGIN( PROG ); }<PROG>"}" BEGIN( 0 ); /* find label */<PROG>{chars}+{numbers}*":" { aLabelPC[iLabel]=iPC; *(yytext+yyleng-1)='\0'; //printf("[I]@%d: Find label: %s, number: %d\n", yylineno, yytext, iLabel); strcpy(sLabel[iLabel], yytext); iLabel++; } /* JDNZ */<PROG>"JDNZ"{sp}+"R"[0-7]{1}{sp}+{words}{sp}*";" { //printf("%s\n", yytext); *(yytext+yyleng-1) = ' '; i=4; while(*(yytext+i)!='R') { i++; } iTmp = atoi(yytext+i+1); //printf("%d\n", iTmp); if(iTmp < 4) { bErr = 1; printf("[E]@%d: JDNZ: Evaluated register must be one of R4 to R7.\n", yylineno, yytext); } else iTmp -= 4; sscanf((yytext+i+2), "%s", sBuff); //printf("%s\n", sBuff); for(i=0; i<4; i++) { //printf("%s\n", sLabel); if(strcmp(sBuff, sLabel)==0) { iTmp = iTmp+(aLabelPC<<2); bFindLabel = 1; } } if(bFindLabel) { printf("RBUS[%s]=0x%02X;", sData, iTmp); PC[iPC] = iTmp&0xFF; iPC++; } else { bErr = 1; printf("[E]@%d: JDNZ syntax error, jump label is not found.\n", yylineno); } }<PROG>"JDNZ"{sp}+. { bErr = 1; printf("[E]@%d: JDNZ syntax error.\n", yylineno); } /* ADDR0 */<PROG>"ADDR0"{sp}+"#"({numbers}|{hex}){sp}*";" { //printf("%s\n", yytext); *(yytext+yyleng-1) = '\0'; i = 5; while(*(yytext+i) != '#') i++; iTmp = atoi(yytext+i+1); //printf("%d\n", iTmp); if( (iTmp<1) || (iTmp>64) ) { bErr = 1; printf("[E]@%d: ADDR0 syntax error, constant must be value from 1 to 64.\n", yylineno); } else { PC[iPC] = ((0x02<<6)+iTmp-1)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x02<<6)+iTmp-1); iPC++; } }<PROG>"ADDR0"{sp}+. { bErr = 1; printf("[E]@%d: ADDR0 syntax error.\n", yylineno); } /* SWAPR */<PROG>"SWAPR"{sp}+"R"[0-3]{1}{sp}+"R"[0-3]{1}{sp}*";" { //printf("%s\n", yytext); *(yytext+yyleng-1) = '\0'; iTmp=0; for(i=5; i<yyleng; i++) { if(*(yytext+i)=='R') iTmp = (iTmp<<2) + atoi(yytext+i+1); } PC[iPC] = ((0x0C<<4)+iTmp)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x0C<<4)+iTmp); iPC++; }<PROG>"SWAPR"{sp}+. { bErr = 1; printf("[E]@%d: SWAPR syntax error.\n", yylineno); } /* RST */<PROG>"RST"{sp}*";" { //printf("%s\n", yytext); PC[iPC] = (0x1A<<3)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1A<<3)); iPC++; }<PROG>"RST"{sp}+. { bErr = 1; printf("[E]@%d: RST syntax error.\n", yylineno); } /* NG */<PROG>"NG"{sp}*";" { //printf("%s\n", yytext); PC[iPC] = (0x1B<<3)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1B<<3)); iPC++; }<PROG>"NG"{sp}+. { bErr = 1; printf("[E]@%d: NG syntax error.\n", yylineno); } /* ADD */<PROG>"ADD"{sp}+"R"[0-7]{1}{sp}*";" { //printf("%s\n", yytext); i=3; while(*(yytext+i) != 'R') i++; iTmp=atoi(yytext+i+1); PC[iPC] = ((0x1C<<3)+iTmp)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1C<<3)+iTmp); iPC++; }<PROG>"ADD"{sp}+. { bErr = 1; printf("[E]@%d: ADD syntax error.\n", yylineno); } /* INCLD */<PROG>"INCLD"{sp}+"R"[0-7]{1}{sp}*";" { //printf("%s\n", yytext); i=5; while(*(yytext+i) != 'R') i++; iTmp=atoi(yytext+i+1); PC[iPC] = ((0x1D<<3)+iTmp)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1D<<3)+iTmp); iPC++; }<PROG>"INCLD"{sp}+. { bErr = 1; printf("[E]@%d: INCLD syntax error.\n", yylineno); } /* LD */<PROG>"LD"{sp}+"R"[0-7]{1}{sp}*";" { //printf("%s\n", yytext); i=2; while(*(yytext+i) != 'R') i++; iTmp=atoi(yytext+i+1); PC[iPC] = ((0x1E<<3)+iTmp)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1E<<3)+iTmp); iPC++; }<PROG>"LD"{sp}+. { bErr = 1; printf("[E]@%d: LD syntax error.\n", yylineno); } /* RSTR */<PROG>"RSTR"{sp}+"R"[0-7]{1}{sp}*";" { //printf("%s\n", yytext); i=4; while(*(yytext+i) != 'R') i++; iTmp=atoi(yytext+i+1); PC[iPC] = ((0x1F<<3)+iTmp)&0xff; printf("RBUS[%s]=0x%02X;\n", sData, (0x1F<<2)+iTmp); iPC++; }<PROG>"RSTR"{sp}+. { bErr = 1; printf("[E]@%d: RSTR syntax error.\n", yylineno); } /* Line Comment */"//"[^\n]* /* Block Comment */"/*" BEGIN( COMMENT );<COMMENT>. /* output nothing when comment */<COMMENT>"*"+"/" BEGIN( 0 );{words}+{sp}*";" { bErr = 1; printf("[E]@%d: Unknown code: %s.\n", yylineno, yytext); }{words} { bErr = 1; printf("[E]@%d: %s is unknown. Maybe \";\" is missing at end of line.\n", yylineno, yytext); }. /* outout nothing when other alphas */<<EOF>> { if(bFindInit==0) { bErr = 1; printf("[E] 0: init part is not found!"); } if(bFindProg==0) { bErr = 1; printf("[E] 1: program part is not found!"); } return 0; }%%int main(argc, argv)int argc;char **argv;{ FILE* hFileOut; for(i=0; i<32; i++) { PC = 0; } yylex(); return 0;}int yywrap(){ return 1;}Then, generate the compiler:
$flex compjcd.l
文章评论(0条评论)
登录后参与讨论