⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vas.y

📁 《编译方法》课程设计内容2.《编译方法》课程设计内容
💻 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 + -