📄 vas.y
字号:
%{
/******************************************************************************
*******************************************************************************
文件名:vas.y 源程序
本程序将VAM的汇编程序翻译为二进制目标文件.
编译方法
1. "byacc vas.y" 生成 y_tab.c.
2. "ren y_tab.c vas.c"
3. 用tc编译vas.c生成执行文件vas.exe
运行方法:
vas VAM汇编文件
程序将输出一个扩展名是.o的VAM二进制文件
文件修改时间
============
2005年5月6日
*******************************************************************************
******************************************************************************/
#include <stdio.h>
void pword(long);
#define YYSTYPE long
#define MAXLAB 0x1000 /* Number of labels */
/* The instruction set */
#define I_HALT 0 /* End of program */
#define I_NOP 1 /* Do nothing */
#define I_TRAP 2 /* Output a character */
#define I_ADD 3 /* ADD Rx,Ry */
#define I_SUB 4
#define I_MUL 5
#define I_DIV 6
#define I_STI 7 /* STI Rx,offset(Ry) */
#define I_LDI 8 /* LDI offset(Rx),Ry */
#define I_LDA 9 /* LDA offset(Rx),Ry */
#define I_LDR 10 /* LDR Rx,Ry */
#define I_BZE 11 /* BZE offset */
#define I_BNZ 12
#define I_BRA 13
#define I_BAL 14 /* BAL Rx,Ry */
#define I_MAX 15
/* Global variables */
FILE *in, *out;
int pass ; /* Which pass */
int pc ; /* Program counter */
long labtab[MAXLAB] ; /* Offsets for labels */
%}
%%
program : statement
| program statement
;
statement : comment return
| label ':' comment return
{
labtab[$1] = pc ;
}
| label ':' ws instruction comment return
{
labtab[$1] = pc ;
}
| ws instruction comment return
;
label : 'L' number { $$ = $2 ; }
;
number : number1
| '-' number1 {$$ = -$2;}
number1 : number1 digit
{
$$ = $1 * 10 + $2 ;
}
| digit
;
digit : '0' { $$ = 0x0 ; }
| '1' { $$ = 0x1 ; }
| '2' { $$ = 0x2 ; }
| '3' { $$ = 0x3 ; }
| '4' { $$ = 0x4 ; }
| '5' { $$ = 0x5 ; }
| '6' { $$ = 0x6 ; }
| '7' { $$ = 0x7 ; }
| '8' { $$ = 0x8 ; }
| '9' { $$ = 0x9 ; }
ws : separator
| ws separator
;
separator : ' '
| '\t'
;
instruction : halt_instr
| nop_instr
| trap_instr
| add_instr
| sub_instr
| mul_instr
| div_instr
| sti_instr
| ldi_instr
| lda_instr
| ldr_instr
| bze_instr
| bnz_instr
| bra_instr
| bal_instr
| db_instr
;
halt_instr : halt_op { pbyte( I_HALT ) ; }
;
nop_instr : nop_op { pbyte( I_NOP ) ; }
;
trap_instr : trap_op { pbyte( I_TRAP ) ; }
;
add_instr : add_op ws reg ',' reg
{
pbyte( I_ADD ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
sub_instr : sub_op ws reg ',' reg
{
pbyte( I_SUB ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
mul_instr : mul_op ws reg ',' reg
{
pbyte( I_MUL ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
div_instr : div_op ws reg ',' reg
{
pbyte( I_DIV ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
sti_instr : sti_op ws reg ',' offset '(' reg ')'
{
pbyte( I_STI ) ;
pbyte( ($3 << 4) | $7 ) ;
pword( $5 ) ;
}
| sti_op ws reg ',' label
{
pbyte( I_STI ) ;
pbyte( $3 << 4 ) ;
pword( labtab[$5] ) ;
}
;
ldi_instr : ldi_op ws offset '(' reg ')' ',' reg
{
pbyte( I_LDI ) ;
pbyte( ($5 << 4) | $8 ) ;
pword( $3 ) ;
}
| ldi_op ws label ',' reg
{
pbyte( I_LDI ) ;
pbyte( $5 ) ;
pword( labtab[$3] ) ;
}
;
lda_instr : lda_op ws offset '(' reg ')' ',' reg
{
pbyte( I_LDA ) ;
pbyte( ($5 << 4) | $8 ) ;
pword( $3 ) ;
}
| lda_op ws label ',' reg
{
pbyte( I_LDA ) ;
pbyte( $5 ) ;
pword( labtab[$3] ) ;
}
;
ldr_instr : ldr_op ws reg ',' reg
{
pbyte( I_LDR ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
bze_instr : bze_op ws offset
{
pbyte( I_BZE ) ;
pword( $3 ) ;
}
| bze_op ws label
{
pbyte( I_BZE ) ;
pword( labtab[$3] - pc + 1 ) ;
}
;
bnz_instr : bnz_op ws offset
{
pbyte( I_BNZ ) ;
pword( $3 ) ;
}
| bnz_op ws label
{
pbyte( I_BNZ ) ;
pword( labtab[$3] - pc + 1 ) ;
}
;
bra_instr : bra_op ws offset
{
pbyte( I_BRA ) ;
pword( $3 ) ;
}
| bra_op ws label
{
pbyte( I_BRA ) ;
pword( labtab[$3] - pc + 1 ) ;
}
;
bal_instr : bal_op ws reg ',' reg
{
pbyte( I_BAL ) ;
pbyte( ($3 << 4) | $5 ) ;
}
;
db_instr : db_op ws number
{
pbyte( $3 ) ;
}
;
halt_op : 'H' 'A' 'L' 'T'
;
nop_op : 'N' 'O' 'P'
;
trap_op : 'T' 'R' 'A' 'P'
;
add_op : 'A' 'D' 'D'
;
sub_op : 'S' 'U' 'B'
;
mul_op : 'M' 'U' 'L'
;
div_op : 'D' 'I' 'V'
;
sti_op : 'S' 'T' 'I'
;
ldi_op : 'L' 'D' 'I'
;
lda_op : 'L' 'D' 'A'
;
ldr_op : 'L' 'D' 'R'
;
bze_op : 'B' 'Z' 'E'
;
bnz_op : 'B' 'N' 'Z'
;
bra_op : 'B' 'R' 'A'
;
bal_op : 'B' 'A' 'L'
;
db_op : 'D' 'B'
;
reg : 'R' number { $$ = $2 ; }
;
offset : number
;
comment : text_comment
| ws text_comment
|
;
text_comment : text_comment char
| '\\'
;
char : separator
| 'a'
| 'b'
| 'c'
| 'd'
| 'e'
| 'f'
| 'g'
| 'h'
| 'i'
| 'j'
| 'k'
| 'l'
| 'm'
| 'n'
| 'o'
| 'p'
| 'q'
| 'r'
| 's'
| 't'
| 'u'
| 'v'
| 'w'
| 'x'
| 'y'
| 'z'
| 'A'
| 'B'
| 'C'
| 'D'
| 'E'
| 'F'
| 'G'
| 'H'
| 'I'
| 'J'
| 'K'
| 'L'
| 'M'
| 'N'
| 'O'
| 'P'
| 'Q'
| 'R'
| 'S'
| 'T'
| 'U'
| 'V'
| 'W'
| 'X'
| 'Y'
| 'Z'
| '0'
| '1'
| '2'
| '3'
| '4'
| '5'
| '6'
| '7'
| '8'
| '9'
| '!'
| '\"'
| '#'
| '$'
| '%'
| '&'
| '\''
| '('
| ')'
| '='
| '-'
| '~'
| '^'
| '\\'
| '|'
| '@'
| '{'
| '['
| '`'
| '_'
| '+'
| ';'
| ':'
| '*'
| '}'
| ']'
| '<'
| ','
| '>'
| '.'
| '?'
| '/'
;
return : '\n'
;
%%
void main( argc, argv )
int argc ;
char **argv ;
{
char *fin, fout[80] = "", *pos;
int loc;
if( argc < 2 ) /* Must have at least a first arg */
{
printf( "vas: Too few args\n" ) ;
exit( 10 ) ;
}
fin = argv[1];
in = fopen (fin, "r");
if (in == NULL) {
printf("error: can't open file %s!\n", fin);
exit(10);
}
pos = strchr(fin, '.');
if (pos == NULL)
loc = strlen(fin);
else
loc = pos - fin;
strncpy(fout, fin, loc);
strcat(fout, ".o");
printf( "the VAM object file is : %s.\n", fout);
out = fopen (fout, "wb");
if (out == NULL) {
printf("error: can't open output file %s!\n", fin);
exit(10);
}
/* First pass sets up labels */
pass = 1 ;
yyparse() ;
/* Second pass generates code */
rewind( in) ;
pc = 0 ;
pass = 2 ;
yyparse() ;
fclose(in);
fclose(out);
} /* void main( void ) */
int yylex( void )
{
return fgetc(in) ;
} /* int yylex( void ) */
void yyerror( char *s )
{
fprintf( stderr, "yyerror: %s\n", s ) ;
} /* void yyerror( char *s ) */
void pbyte( int n )
/* Put out the single byte n (on pass 2), advancing pc */
{
if( pass == 2 )
fputc( n , out) ;
pc++ ;
} /* void pbyte( int n ) */
void pword( long n )
/* Put out the word n (on pass 2), advancing pc */
{
if( pass == 2 )
{
fputc( n >>24, out ) ;
fputc( n >>16 , out) ;
fputc( n >> 8 , out) ;
fputc( n , out ) ;
}
pc += 4;
} /* void pword( int n ) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -