Article View: de.comp.gnu
Article #84Re: Wie binde ich ein Assemblerprg. in GNU-C ein?
From: alexander nagorny
Date: Tue, 15 Dec 1992 15:42
Date: Tue, 15 Dec 1992 15:42
315 lines
7770 bytes
7770 bytes
Hallo,
ich habe dieses einfache Lex-Programm gefunden.
Vieleicht hilft es dir bei der Konvertierung
von einfachen Assembler-Programmen weiter.
Gruss
Alexander Nagorny
email: nagorny@rbg.informatik.th-darmstadt.de
----------------- Begin of lex program ---------------------------------------
%{
/* cv68.l
*
* simple lex program for converting 68K motorola assembler syntax into GNU's
* GAS syntax. WARNING: It's only a lex program, hence no real syntax analysis
* of the input text is performed. For that a yacc script would be needed,
* which, i decided, is too slow, and it's not worth the effort, since most of
* the asm syntax is simple enough to analyse it with a simple finite state
* maschine.
*
* Be aware that all this is a quick but fairly well working hack!
*
* written in 10-12-89 by Kai-Uwe Bloem, I5110401@dbstu1.bitnet
*/
/*
* states of the FSM.
*/
#define START 0 /* awaiting a new source line */
#define LDECL 1 /* label or declaration parsed */
#define INSTR 2 /* instruction parsed */
#define OP1 3 /* 1st operand parsed */
#define OP2 4 /* 2nd operand parsed */
#define DIREC 10 /* assembler directive line */
#define COMM 11 /* comment line */
/* strongly simplified grammar:
*
* START -> LDECL -> INSTR -> OP1 -> OP2
* ^ | | | |
* +-- <- --+-- <- --+-- <- -+- <- -+
*/
/*
* forward declarations
*/
static void p_err();
/*
* global variables
*/
int state = START; /* current state */
int lineno = 1; /* current source line */
/* Opcodes which imply a word length operation (.w) */
char *opcodes[] = { "add", "clr", "cmp", "neg", "sub", "tst",
"asl", "asr", "lsl", "lsr", "rol", "ror",
"and", "eor", "not", "or" , "move", NULL };
/* Some codes are guaranteed to be missing here... */
%}
delim [;\n]
wspace [ \t]+
xnum "0x"[0-9a-fA-F]+
dnum "-"?[0-9]+
number {dnum}|{xnum}
prglabel [A-Za-z_][A-Za-z0-9_]*
value {number}|{prglabel}
expr {value}(("+"|"-"){value})?
dreg "d"[0-7]
areg ("a"[0-7])|"sp"|"usp"|"pc"
opreg {dreg}|{areg}|"sr"|"ccr"
opimmd "#"{expr}
opaddr {expr}
opreglst {opreg}("-"{opreg})?("/"{opreg}("-"{opreg})?)*
simploprs {opreg}|{opimmd}|{opaddr}|{opreglst}
opind ("-("{areg}")")|("("{areg}")+")|("("{areg}")")
opindoff {expr}"("{areg}(","{opreg}("."[wl])?)?")"
opcode [a-z]+("."[bwl])?
directive ("."[a-z0-9]+{wspace}[^!;\n]*)|("#"[a-zA-Z][^\n]*)
comment "!".*
decl ({prglabel}":")|({prglabel}{wspace}*"="{wspace}*{expr})
%%
{wspace}*{opcode} {
char *s = yytext;
char **t = opcodes;
if (state == START || state == LDECL)
{
while (*s == ',' || *s == ' ' || *s == '\t')
fputc(*s++,yyout);
while (*t != NULL)
{
if (!strcmp(*t,s))
{
fputs(s,yyout);
fputc('w',yyout);
*s = '\0'; /* bogous hack */
break;
}
t++;
}
while (*s)
{
if (*s != '.')
fputc(*s,yyout);
s++;
}
state = INSTR;
}
else if (state == INSTR || state == OP1)
{ /* must be a simple value operand... what a crock */
/* (but then, it's just a lex program...) */
fputs( yytext, yyout );
if (state == INSTR)
state = OP1;
else state = OP2;
}
else p_err( "unexpected opcode" );
}
((","{wspace}?)|{wspace}){simploprs} {
if (state == INSTR || state == OP1)
fputs( yytext, yyout );
else p_err( "misplaced operand" );
if (state == INSTR)
state = OP1;
else state = OP2;
}
((","{wspace}?)|{wspace}){opind} {
char *s = yytext;
int predecr = 0;
if (state == INSTR || state == OP1)
{
while (*s == ',' || *s == ' ' || *s == '\t')
fputc(*s++,yyout);
predecr = *s == '-';
if (predecr)
s += 2;
else s++; /* s now points to the address reg */
fputc(*s++,yyout); /* register qualifier */
fputc(*s++,yyout); /* register number */
fputc('@',yyout); /* indirect qualifier */
if (predecr) /* decrement/increment */
fputc('-',yyout);
else if (s[1] == '+')
fputc('+',yyout);
}
else p_err( "misplaced operand" );
if (state == INSTR)
state = OP1;
else state = OP2;
}
((","{wspace}?)|{wspace}){opindoff} {
char *s = yytext;
char *num;
if (state == INSTR || state == OP1)
{
while (*s == ',' || *s == ' ' || *s == '\t')
fputc(*s++,yyout);
num = s;
while (*s != '(') s++;
*s++ = '\0'; /* skip '(' */
fputc(*s++,yyout); /* register qualifier */
fputc(*s++,yyout); /* register number */
fputc('@',yyout); /* indirect qualifier */
fputc('(',yyout); /* offset qualifier */
fputs(num,yyout); /* offset value */
if (!strncmp(s-2,"pc",2)) { /* pc-rel is different */
fputs("-.-2",yyout); /* ... in ACK and GNU */
fprintf(stderr,
"cv68: line %d, pc-rel. may cause problems\n",
lineno);
}
if (*s++ == ',') /* distance register */
{
fputc(',',yyout);
fputc(*s++,yyout); /* distance qualifier */
fputc(*s++,yyout); /* distance number */
if (*s++ == '.') /* length qualifier */
{
fputc(':',yyout);
fputc(*s++,yyout);
}
}
fputc(')',yyout);
}
else p_err( "misplaced operand" );
if (state == INSTR)
state = OP1;
else state = OP2;
}
{directive} {
if (!strncmp(yytext,".define",7) || !strncmp(yytext,".extern",7))
{
fputs(".globl",yyout);
fputs(&yytext[7],yyout);
}
else if (!strncmp(yytext,".space",6))
{
fputs(".skip",yyout);
fputs(&yytext[6],yyout);
}
else if (!strncmp(yytext,".data",5))
{
if (yytext[5] == '2')
fputs(".word",yyout);
else if (yytext[5] == '4')
fputs(".long",yyout);
else if (yytext[5] == '1')
fputs(".byte",yyout);
fputs(&yytext[6],yyout);
}
else if (!strncmp(yytext,".sect",5))
{
char *s = &yytext[5];
while (*s == ' ' || *s == '\t') s++;
if (!strncmp(s,".text",5) || !strncmp(s,".data",5))
fputs(s,yyout);
else if (!strncmp(s,".bss",4))
{
fprintf(stderr,"cv68: line %d, no support for .bss\n",
lineno);
fputs(".data | really .bss, but not in gcc-as...",
yyout);
}
else
{
fputc('|',yyout);
fputs(yytext,yyout);
}
}
else fputs(yytext,yyout);
}
{comment} {
fputc('|',yyout);
fputs(&yytext[1],yyout);
}
{decl} {
char *s = yytext;
while(*s && *s != '=')
fputc(*s++,yyout);
if (*s && s[-1] != ' ' && s[-1] != '\t')
fputc(' ',yyout);
if (*s)
fputs(s,yyout);
state = LDECL;
}
{delim} {
state = START;
if (yytext[0] == '\n')
lineno++;
fputc('\n',yyout);
}
%%
void
p_err(s)
char *s;
{
fprintf( stderr, "cv68: line %d, %s\n", lineno, s );
exit(1);
}
main(argc,argv)
int argc;
char *argv[];
{
int i=0;
yyout = stdout;
while(++i < argc)
{
if (!strcmp(argv[i],"-v")) {
printf( "cv68 V1.0, written by KUB\n" );
continue;
}
if (!strcmp(argv[i],"-"))
yyin = stdin;
else if ((yyin = fopen(argv[i],"r")) == (FILE *)NULL)
continue;
while( yylex() > 0 )
;
if (yyin != stdin) fclose(yyin);
}
}
--------- end of lex program -------------------------------------------------
Technical Details
Message-ID:
<1992Dec15.164229@rbg.informatik.th-darmstadt.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!news.th-darmstadt.de!rbg.informatik.th-darmstadt.de!nagornyReferences:
<1992Dec5.224709.5788@rz.uni-karlsruhe.de> <1992Dec6.153136.1894@robkaos.GUN.de>Show Full Headers
Complete Article Headers
Newsgroups: de.comp.gnu,de.comp.sys.st Path: arc1-ca.pugleaf.net!sparky!uunet!spool.mu.edu!sol.ctr.columbia.edu!ira.uka.de!math.fu-berlin.de!news.th-darmstadt.de!rbg.informatik.th-darmstadt.de!nagorny From: nagorny@rbg.informatik.th-darmstadt.de (alexander nagorny) Subject: Re: Wie binde ich ein Assemblerprg. in GNU-C ein? Sender: news@news.th-darmstadt.de (The News System) Message-ID: <1992Dec15.164229@rbg.informatik.th-darmstadt.de> Date: Tue, 15 Dec 1992 15:42:29 GMT References: <1992Dec5.224709.5788@rz.uni-karlsruhe.de> <1992Dec6.153136.1894@robkaos.GUN.de> Nntp-Posting-Host: rbhp28.rbg.informatik.th-darmstadt.de Organization: TU Darmstadt Lines: 315