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

📄 as.y

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 Y
字号:
%{
    #include "as.h"
    #include "lexyacc.h"
    #include "asytab.h"
    
    typedef uint_16         YYACTIONBASETYPE;
    typedef uint_16         YYACTIONTYPE;
    typedef uint_16         YYBITBASETYPE;
    typedef uint_8          YYBITTYPE;
    typedef uint_8          YYPLENTYPE;
    typedef uint_16         YYPLHSTYPE;
    
    typedef unsigned        YYTOKENTYPE;
    
#pragma disable_message( 118 );	// no more unreferenced label warning
#pragma warning 17 5	// shut off the unreferenced goto warning
#pragma warning 389 5	// shut off the integral truncated warning
#pragma warning 373 5	// get rid of defined but not referenced warning

    instruction		    *AsCurrIns;
    directive_t		    *AsCurrDir;
%}

%union {
    char	    *str;
    void	    *null;
    int_32	    val;
    double	    fval;
    sym_handle	    sym;
    reg		    reg;
    expr_tree	    *tree;	/* node in an expression tree */
    instruction	    *ins;
    ins_operand	    *op;
    asm_reloc_type  rtype;
    directive_t	    *dir;
:segment _STANDALONE_
    fileinfo	    *file;
:endsegment
}

%token	<null>	T_ERROR
:segment _STANDALONE_
%token	<file>	T_FILE_SWITCH	/* indicating a #line; info in <file> */
:endsegment

%token	<sym>	T_DIRECTIVE
%token	<str>	T_DIRECTIVE_OPERAND
%token	<sym>	T_OPCODE
%token	<sym>	T_IDENTIFIER

/* registers */
%token	<reg>	T_REGISTER

/* manifest constants */

%token	<val>	T_INTEGER_CONST
%token	<str>	T_STRING_CONST
%token	<fval>	T_FLOAT_CONST
:segment AS_PPC
%token	<val>	T_BI_OFFSET
:endsegment

/* punctuation and special symbols */

:segment _STANDALONE_
%token		T_NEWLINE
:endsegment
%token		T_COMMA
%token		T_COLON
%token		T_SEMICOLON
%token		T_LEFT_PAREN
%token		T_RIGHT_PAREN
%token	<rtype>	T_RELOC_MODIFIER
%token	<val>	T_NUMERIC_LABEL
%token	<val>	T_NUMLABEL_REF

/* arithmetic stuff */

%left  	<tree>	T_OR
%left	<tree>	T_XOR
%left	<tree>	T_AND
%left	<tree>	T_SHIFT_LEFT T_SHIFT_RIGHT
%left 	<tree>	T_PLUS T_MINUS
%left	<tree>	T_TIMES T_DIVIDE T_MOD
%nonassoc <tree> T_UNARY_MINUS T_NOT T_UNARY_PLUS

:segment _STANDALONE_
%type	<null>	asm_file
:endsegment
%type	<null>	asm_line
%type	<sym>	label
%type	<null>	statement
%type	<null>	directive
%type	<dir>	dir_name
%type	<null>	dir_operands
%type	<null>	dir_op_tail
%type	<null>	dir_op
%type	<null>	dir_ident
%type	<tree>	plus_minus_num_expr
%type	<tree>	num_expr_plus
%type	<null>	dir_ident
%type	<tree>	num_expr
%type	<ins>	instruction
%type	<null>	operand_list
%type	<null>	operand_tail
%type	<op>	operand
%type	<tree>	expression
%type	<reg>	reg_indirect
%type	<op>	mem_reference
:segment AS_PPC
%type	<op>	field_BI
%type	<val>	bi_crf
:endsegment
%type	<ins>	opcode
%type	<op>	ins_operand
%type	<sym>	identifier

%%

:segment _STANDALONE_
asm_file	: asm_line					{ }
		| asm_file asm_line				{ }
		;

asm_line	: label statement more_stmts T_NEWLINE		{ CurrLineno++; }
		| error T_NEWLINE				{ CurrLineno++; yyerrok; }
		| T_FILE_SWITCH					{   /* #line directive */
								    CurrLineno = $1->line;
								    MemFree( CurrFilename );
								    CurrFilename = AsStrdup( $1->name );
								    MemFree( $1 );
								}
:elsesegment
asm_line	: label statement more_stmts			{ }
:endsegment
		;

label		: /* nothing */					{ }
		| T_IDENTIFIER T_COLON label			{ ObjEmitLabel( $1 ); }
		| T_NUMERIC_LABEL label				{ ObjEmitNumericLabel( $1 ); }
		;

statement	: /* nothing */					{ }
		| directive					{ }
		| instruction					{ }
		;
		
more_stmts	: /* nothing */					{ }
		| T_SEMICOLON label statement more_stmts	{ }
		;

directive	: dir_name dir_operands				{
								    bool okay;
								    
								    okay = DirParse( $1 );
								    DirDestroy( $1 );
								    AsCurrDir = NULL;
								    if( !okay ) YYABORT;
								}
		;
 
dir_name	: T_DIRECTIVE					{ $$ = DirCreate( $1 ); AsCurrDir = $$; }
		;
		
dir_operands	: /* nothing */					{ }
		| dir_op dir_op_tail				{ }
		;

dir_op_tail	: /* nothing */					{ }
		| T_COMMA dir_op dir_op_tail			{ }
		;

num_expr_plus	: /* nothing */					{ $$ = ETConst( 0 ); }
		| num_expr T_PLUS				{ $$ = $1; }
		;

plus_minus_num_expr : /* nothing */				{ $$ = ETConst( 0 ); }
		| T_PLUS num_expr				{ $$ = $2; }
		| T_MINUS num_expr				{ $$ = ETUnary( ET_UNARY_MINUS, $2 ); }
		;

dir_ident	: num_expr_plus identifier plus_minus_num_expr	{ DirAddOperand( AsCurrDir, DirOpIdentifier( ASM_RELOC_UNSPECIFIED, $2, ETBinary( ET_PLUS, $1, $3 ), 1 ) ); }
		| num_expr_plus T_RELOC_MODIFIER identifier plus_minus_num_expr
								{ DirAddOperand( AsCurrDir, DirOpIdentifier( $2, $3, ETBinary( ET_PLUS, $1, $4 ), 1 ) ); }
		| num_expr_plus T_NUMLABEL_REF plus_minus_num_expr
								{ DirAddOperand( AsCurrDir, DirOpNumLabelRef( ASM_RELOC_UNSPECIFIED, $2, ETBinary( ET_PLUS, $1, $3 ), 1 ) ); }
		| num_expr_plus T_RELOC_MODIFIER T_NUMLABEL_REF plus_minus_num_expr
								{ DirAddOperand( AsCurrDir, DirOpNumLabelRef( $2, $3, ETBinary( ET_PLUS, $1, $4 ), 1 ) ); }
		;

dir_op		: num_expr					{ DirAddOperand( AsCurrDir, DirOpNumber( $1 ) ); }
		| T_DIRECTIVE_OPERAND				{ DirAddOperand( AsCurrDir, DirOpLine( $1 ) ); }
		| dir_ident					{ }
		| T_STRING_CONST				{ DirAddOperand( AsCurrDir, DirOpString( $1 ) ); }
		| num_expr T_COLON num_expr			{ DirAddOperand( AsCurrDir, DirOpRepeat( $1, $3 ) ); }
		;

num_expr	: num_expr T_TIMES num_expr			{ $$ = ETBinary( ET_TIMES, $1, $3 ); }
		| num_expr T_DIVIDE num_expr			{ $$ = ETBinary( ET_DIVIDE, $1, $3 ); }
		| num_expr T_MOD num_expr			{ $$ = ETBinary( ET_MOD, $1, $3 ); }
		| num_expr T_PLUS num_expr			{ $$ = ETBinary( ET_PLUS, $1, $3 ); }
		| num_expr T_MINUS num_expr			{ $$ = ETBinary( ET_MINUS, $1, $3 ); }
		| num_expr T_SHIFT_LEFT num_expr		{ $$ = ETBinary( ET_SHIFT_L, $1, $3 ); }
		| num_expr T_SHIFT_RIGHT num_expr		{ $$ = ETBinary( ET_SHIFT_R, $1, $3 ); }
		| num_expr T_AND num_expr			{ $$ = ETBinary( ET_AND, $1, $3 ); }
		| num_expr T_OR num_expr			{ $$ = ETBinary( ET_OR, $1, $3 ); }
		| num_expr T_XOR num_expr			{ $$ = ETBinary( ET_XOR, $1, $3 ); }
		| num_expr error				{ /* Pass this on so that DirOpXXX will free the memory */ }
		| T_MINUS %prec T_UNARY_MINUS num_expr		{ $$ = ETUnary( ET_UNARY_MINUS, $2 ); }
		| T_PLUS %prec T_UNARY_PLUS num_expr		{ $$ = $2; }
		| T_NOT num_expr				{ $$ = ETUnary( ET_NOT, $2 ); }
		| T_LEFT_PAREN num_expr T_RIGHT_PAREN		{ $$ = ETUnary( ET_PARENS, $2 ); }
		| T_INTEGER_CONST				{ $$ = ETConst( $1 ); }
		| T_FLOAT_CONST 				{ $$ = ETFPConst( $1 ); }
		;

instruction	: opcode operand_list				{ InsEmit( $1 ); InsDestroy( $1 ); AsCurrIns = NULL; }
		;
		
opcode		: T_OPCODE					{
								    $$ = InsCreate( $1 );
								    if( AsCurrIns ) InsDestroy( AsCurrIns );
								    AsCurrIns = $$;
								}
		;

operand_list	: /* nothing */					{ }
		| ins_operand operand_tail			{ }
		;
		
operand_tail	: /* nothing */					{ }
		| T_COMMA ins_operand operand_tail		{ }
		;
		
ins_operand	: operand					{ InsAddOperand( AsCurrIns, $1 ); }
		;
		
operand		: expression					{ $$ = OpImmed( $1 ); }
		| T_REGISTER					{ $$ = OpRegister( $1 ); }
		| mem_reference					{ $$ = $1; }
:segment AS_PPC
		| field_BI					{ $$ = $1; }
:endsegment
		;

mem_reference	: expression reg_indirect			{ $$ = OpRegIndirect( $2, $1 ); }
		| reg_indirect					{ $$ = OpRegIndirect( $1, NULL ); }
		;

:segment AS_PPC
field_BI	: bi_crf T_PLUS T_BI_OFFSET			{ $$ = OpBI( $1, $3 ); }
		| T_BI_OFFSET					{ $$ = OpBI( 0, $1 ); }
		;

bi_crf		: T_REGISTER					{ $$ = RegCrfToBI( $1 ); }
		;
:endsegment

reg_indirect	: T_LEFT_PAREN T_REGISTER T_RIGHT_PAREN		{ $$ = $2; }
		;
		
expression	: expression T_TIMES expression			{ $$ = ETBinary( ET_TIMES, $1, $3 ); }
		| expression T_DIVIDE expression		{ $$ = ETBinary( ET_DIVIDE, $1, $3 ); }
		| expression T_MOD expression			{ $$ = ETBinary( ET_MOD, $1, $3 ); }
		| expression T_PLUS expression			{ $$ = ETBinary( ET_PLUS, $1, $3 ); }
		| expression T_MINUS expression			{ $$ = ETBinary( ET_MINUS, $1, $3 ); }
		| expression T_SHIFT_LEFT expression		{ $$ = ETBinary( ET_SHIFT_L, $1, $3 ); }
		| expression T_SHIFT_RIGHT expression		{ $$ = ETBinary( ET_SHIFT_R, $1, $3 ); }
		| expression T_AND expression			{ $$ = ETBinary( ET_AND, $1, $3 ); }
		| expression T_OR expression			{ $$ = ETBinary( ET_OR, $1, $3 ); }
		| expression T_XOR expression			{ $$ = ETBinary( ET_XOR, $1, $3 ); }
		| expression error				{ /* Pass this on so that OpXXX will free the memory */ }
		| T_MINUS %prec T_UNARY_MINUS expression	{ $$ = ETUnary( ET_UNARY_MINUS, $2 ); }
		| T_PLUS %prec T_UNARY_PLUS expression		{ $$ = $2; }
		| T_NOT expression				{ $$ = ETUnary( ET_NOT, $2 ); }
		| T_LEFT_PAREN expression T_RIGHT_PAREN		{ $$ = ETUnary( ET_PARENS, $2 ); }
		| T_INTEGER_CONST				{ $$ = ETConst( $1 ); }
		| T_RELOC_MODIFIER identifier			{ $$ = ETReloc( $1, $2 ); }
		| identifier					{ $$ = ETReloc( ASM_RELOC_UNSPECIFIED, $1 ); }
		| T_RELOC_MODIFIER T_NUMLABEL_REF		{ $$ = ETNumLabelReloc( $1, $2 ); };
		| T_NUMLABEL_REF				{ $$ = ETNumLabelReloc( ASM_RELOC_UNSPECIFIED, $1 ); };
		;
		
identifier	: T_IDENTIFIER					{ $$ = $1; }
:segment _STANDALONE_
		| T_DIRECTIVE					{   if( !SymIsSectionSymbol( $1 ) ) {
									Error( INVALID_RELOC_SYM, SymName( $1 ) );
									YYERROR;
								    }
								    // otherwise
								    $$ = $1;
								}
:endsegment
		;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -