分享
 
 
 

编译原理课程设计_C--编译器_语法分析&代码生成

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

%{

#include "ctype.h"

#include "string.h"

#include "stdio.h"

#include "stdlib.h"

#define HASHSIZE 256

#define GLOBAL 0

typedef int Type;

typedef struct symbol *Symbol;

typedef struct table *Table;

Table types;

Table currentTable;

int currentLevel;

int params;//堆栈已分配的单元个数;

int paramcount;//参数和临时变量总数记录

int realParam;//参数的个数记录

int calltype=0;//函数调用方式__stdcall&__cdecl

char funBuffer[1024];//函数声明缓冲区

char localValBuffer[1024]; //局部变量缓冲区

char varBuffer[1024];//全局变量缓冲区

//char stringBuffer[1024];//字符串常量缓冲区

int msgIndex = 0;//字符串索引

int bufferLen;//缓冲区长度

int callparam;//调用时记录参数数目

int label=0;//自动生成标号

struct symbol {

char *name;//串名

int scope;//层次

int sclass;//符号表内类型

Symbol up;//上一个被插入的符号的指针

int ty;//类型

float ref;//引用地址

int value;//符号表中符号的值

int calltype;//如果是函数,记录调用方式

int isLocal;//记录是全局变量还是局部变量

};

/*

void 1 int 2 char 3

void* 11 int* 12 char* 13

void[] 21 int[] 22 char[] 23

void*[] 31 int*[] 32 char*[] 33

*/

struct entry {

struct symbol sym;

struct entry *link;

};

struct table {

int level;

Table previous;

struct entry *buckets[HASHSIZE];

Symbol all;

};

Table table( Table tp, int level);

Symbol install(char *name, Table *tpp, int level, int sclass);

Symbol lookup(char *name, Table tp);

void enterscope();

void exitscope();

Table table( Table tp, int level)

{

int i;

Table newTemp = (Table) malloc( sizeof( struct table ) );

newTemp->previous = tp;

newTemp->level = level;

for( i = 0; i < HASHSIZE; i++ )

{

newTemp->buckets[i] = NULL;

}

if (tp)

newTemp->all = tp->all;

return newTemp;

}

Symbol install(char *name, Table *tpp, int level, int sclass)

{

Table tp = *tpp;

struct entry *p;

int len;

unsigned h = name[0] & (HASHSIZE - 1);

if (level > 0 && tp->level < level)

tp = *tpp = table(tp, level);

currentTable = tp;

p = (struct entry *) malloc( sizeof( struct entry ) );

len = strlen( name );

p->sym.name = (char *) malloc( len * sizeof( char ) );

strcpy( p->sym.name, name );

p->sym.scope = level;

p->sym.up = tp->all;

p->sym.sclass = sclass;

tp->all = &p->sym;

p->link = tp->buckets[h];

tp->buckets[h] = p;

return &p->sym;

}

Symbol lookup(char *name, Table tp) {

struct entry *p;

unsigned h = name[0] & (HASHSIZE-1);

if( tp == NULL ) return NULL;

do

for (p = tp->buckets[h]; p; p = p->link )

{

if ( p != NULL && strcmp(name, p->sym.name) == 0 )

return &p->sym;

}

while ((tp = tp->previous) != NULL);

return NULL;

}

void enterscope() {

currentLevel++;

}

void exitscope() {

if (currentTable->level == currentLevel) {

Table tt = currentTable;

currentTable = currentTable->previous;

free( tt );

}

--currentLevel;

}

Symbol makeSym( char *text )

{

int len;

Symbol temp = (Symbol) malloc( sizeof( struct symbol ) );

len = strlen( text );

temp->name = (char *) malloc( len * sizeof( char ) );

strcpy( temp->name, text );

temp->scope = currentLevel;

return temp;

}

typedef struct {//表达式的类型

int is_const;

int value;

char *code;

char *name;

char *temp;

} expr;

%}

%token ID NUM CHARACTER STRING INT VOID CHAR IF ELSE

WHILE RETURN __CDECL __STDCALL LE LT GT GE EQ

NE OR AND INT VOID CHAR FUNCTION ARRAY POINTER NEG

%start program

%union{ int* value;

Symbol symType;

expr* exprType;

char* op;

};

%token <symType> ID

%token <symType> NUM

%token <symType> STRING

%token <symType> CHARACTER

%type <exprType> param

%type <exprType> program

%type <exprType> startstmt

%type <exprType> declaration_list

%type <exprType> declaration

%type <value> type_specifer

%type <exprType> params

%type <exprType> compound_stmt

%type <exprType> param_list

%type <exprType> local_declarations

%type <exprType> var_declaration

%type <exprType> fun_declaration

%type <exprType> statement_list

%type <exprType> statement

%type <exprType> expression_stmt

%type <exprType> if_stmt

%type <exprType> while_stmt

%type <exprType> return_stmt

%type <exprType> expression

%type <exprType> simple_expression

%type <exprType> additive_expression

%type <exprType> var

%type <exprType> relop

%type <exprType> term

%type <op> mulop

%type <exprType> unary_expression

%type <op> unaryop

%type <exprType> factor

%type <exprType> call

%type <exprType> args

%type <exprType> arg_list

%type <value> calling_convention

%type <exprType> loc_declaration

%type <op> addop

%right '='

%left '+' '-'

%left '*' '/' '%'

%%

program : declaration_list

{

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $1->code ) + 100 );

sprintf( $$->code, "%sEND main\n", $1->code );

fprintf( yyout, ".386\n.MODEL flat, stdcall\n.Stack 4096\n" );

fprintf( yyout, "\n%s", funBuffer );

fprintf( yyout, "\n.data\n%s", varBuffer );

fprintf( yyout, "\n.code\n%s", $$->code );

}

;

declaration_list : declaration_list declaration

{

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $1->code ) + strlen( $2->code ) + 1 );

sprintf( $$->code, "%s%s", $1->code, $2->code );

}

| declaration

{

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $1->code ) + 1 );

sprintf( $$->code, "%s", $1->code );

}

;

declaration : var_declaration

{

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $1->code ) + 1 );

sprintf( $$->code, "");

sprintf( varBuffer, "%s%s", varBuffer, $1->code );

}

| fun_declaration

{

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $1->code ) + 10 );

sprintf( $$->code, "%s", $1->code );

}

;

var_declaration : type_specifer ID ';'

{

if( lookup( $2->name, currentTable ) == NULL )

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 0;

}

else

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $2->name );

yyerror( msg );

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + 13 );

switch( *$1 )

{

case 1:

$2->ty = 1;

yyerror( "Type Error: " );

break;

case 2:

$2->ty = 2;

sprintf( $$->code, " %s DWORD 0\n", $2->name );

break;

case 3:

$2->ty = 3;

sprintf( $$->code, " %s BYTE 0\n", $2->name );

break;

}

}

| type_specifer ID '[' NUM ']' ';'

{

if( lookup( $2->name, currentTable ) == NULL )

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 0;

}

else

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $2->name );

yyerror( msg );

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + strlen( $4->name ) + 13 );

switch( *$1 )

{

case 1:

$2->ty = 21;

yyerror( "Type Error: " );

break;

case 2:

$2->ty = 22;

sprintf( $$->code, " %s DWORD %s DUP(0)\n", $2->name, $4->name );

break;

case 3:

$2->ty = 23;

sprintf( $$->code, " %s BYTE %s DUP(0)\n", $2->name, $4->name );

break;

}

}

| type_specifer '*' ID ';'

{

if( lookup( $3->name, currentTable ) == NULL )

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 0;

}

else

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $3->name );

yyerror( msg );

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->name ) + 13 );

switch( *$1 )

{

case 1:

$3->ty = 11;

yyerror( "Type Error: " );

break;

case 2:

$3->ty = 12;

sprintf( $$->code, " %s PTR DWORD 0\n", $3->name );

break;

case 3:

$3->ty = 13;

sprintf( $$->code, " %s PTR BYTE 0\n", $3->name );

break;

}

}

| type_specifer '*' ID '[' NUM ']' ';'

{

if( lookup( $3->name, currentTable ) == NULL )

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 0;

}

else

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $3->name );

yyerror( msg );

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->name ) + strlen( $5->name ) + 13 );

switch( *$1 )

{

case 1:

$3->ty = 31;

yyerror( "Type Error: " );

break;

case 2:

$3->ty = 32;

sprintf( $$->code, " %s PTR DWORD %s DUP(0)\n", $3->name, $5->name );

break;

case 3:

$3->ty = 33;

sprintf( $$->code, " %s PTR BYTE %s DUP(0)\n", $3->name, $5->name );

break;

}

}

;

loc_declaration : type_specifer ID ';'

{

Symbol temp;

if( (temp = lookup( $2->name, currentTable )) == NULL )

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 1;

}

else

{

if( temp->scope == currentLevel )

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $2->name );

yyerror( msg );

}

else

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 1;

}

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + 13 );

switch( *$1 )

{

case 1:

$2->ty = 1;

yyerror( "Type Error: " );

break;

case 2:

$2->ty = 2;

sprintf( localValBuffer, "%s\tlocal %s:DWORD\n", localValBuffer, $2->name );

break;

case 3:

$2->ty = 3;

sprintf( localValBuffer, "%s\tlocal %s:DWORD\n", localValBuffer, $2->name );

break;

}

sprintf( $$->code, "" );

paramcount++;

realParam++;

}

| type_specifer ID '[' NUM ']' ';'

{

Symbol temp;

if( (temp = lookup( $2->name, currentTable )) == NULL )

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 1;

}

else

{

if( temp->scope == currentLevel )

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $2->name );

yyerror( msg );

}

else

{

$2 = install($2->name, &currentTable, currentLevel, ID);

$2->isLocal = 1;

}

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + strlen( $4->name ) + 13 );

switch( *$1 )

{

case 1:

$2->ty = 21;

yyerror( "Type Error: " );

break;

case 2:

$2->ty = 22;

sprintf( localValBuffer, "%s\tlocal %s[%s]:DWORD\n", localValBuffer, $2->name, $4->name );

break;

case 3:

$2->ty = 23;

sprintf( localValBuffer, "%s\tlocal %s[%s]:DWORD\n", localValBuffer, $2->name, $4->name );

break;

}

sprintf( $$->code, "" );

paramcount++;

realParam++;

}

| type_specifer '*' ID ';'

{

Symbol temp;

if( (temp = lookup( $3->name, currentTable )) == NULL )

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 1;

}

else

{

if( temp->scope == currentLevel )

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $3->name );

yyerror( msg );

}

else

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 1;

}

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->name ) + 13 );

switch( *$1 )

{

case 1:

$3->ty = 11;

yyerror( "Type Error: " );

break;

case 2:

$3->ty = 12;

sprintf( localValBuffer, "\tlocal %s:PTR WORD\n", $3->name );

break;

case 3:

$3->ty = 13;

sprintf( localValBuffer, "\tlocal %s:PTR BYTE\n", $3->name );

break;

}

sprintf( $$->code, "" );

paramcount++;

realParam++;

}

| type_specifer '*' ID '[' NUM ']' ';'

{

Symbol temp;

if( (temp = lookup( $3->name, currentTable )) == NULL )

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 1;

}

else

{

if( temp->scope == currentLevel )

{

char msg[100];

sprintf( msg, "Variable %s redefinition: ", $3->name );

yyerror( msg );

}

else

{

$3 = install($3->name, &currentTable, currentLevel, ID);

$3->isLocal = 1;

}

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->name ) + strlen( $5->name ) + 13 );

switch( *$1 )

{

case 1:

$3->ty = 31;

yyerror( "Type Error: " );

break;

case 2:

$3->ty = 32;

sprintf( localValBuffer, "\tlocal %s[%s]:DWORD\n", $3->name, $5->name );

break;

case 3:

$3->ty = 33;

sprintf( localValBuffer, "\tlocal %s[%s]:DWORD\n", $3->name, $5->name );

break;

}

sprintf( $$->code, "" );

paramcount++;

realParam++;

}

;

type_specifer : INT

{

$$ = (int*)malloc( sizeof( int ) );

*$$ = 2;

}

| VOID

{

$$ = (int*)malloc( sizeof( int ) );

*$$ = 1;

}

| CHAR

{

$$ = (int*)malloc( sizeof( int ) );

*$$ = 3;

}

;

fun_declaration : type_specifer calling_convention ID '(' params ')' compound_stmt

{

// if( lookup( $3->name, currentTable ) == NULL )

// {

// $3 = install($3->name, &currentTable, currentLevel, ID);

// }

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $3->name )*2 + strlen( $5->code ) + strlen( $7->code ) + strlen( localValBuffer ) + 12 );

if( *$2== 0 && params > 0 )

{

// $3->calltype = 0;

sprintf( $$->code, "%s PROC%s\n%s\tsub esp, %d\n%s\tret %d\n%s ENDP\n", $3->name, $5->code, $7->code, localValBuffer, (paramcount-realParam)*4, 4*params, $3->name );

}

else

{

// $3->calltype = 1;

sprintf( $$->code, "%s PROC%s\n%s\tsub esp, %d\n%s\tret\n%s ENDP\n", $3->name, $5->code, $7->code, localValBuffer, (paramcount-realParam)*4, $3->name );

}

params = 0;

paramcount = 0;

realParam = 0;

sprintf( localValBuffer, "" );

}

| type_specifer calling_convention ID '(' params ')' ';'

{

if( lookup( $3->name, currentTable ) == NULL )

{

$3 = install($3->name, &currentTable, currentLevel, ID);

}

else

{

char msg[100];

sprintf( msg, "The Function %s redefinition: ", $3->name );

yyerror( msg );

}

if( *$2== 0 && params > 0 )

{

$3->calltype = 0;

}

else

{

$3->calltype = 1;

}

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = "";

sprintf( funBuffer, "%s PROTO%s\n", $3->name, $5->code );

}

| type_specifer ID '(' params ')' compound_stmt

{

// if( lookup( $2->name, currentTable ) == NULL )

// {

// $2 = install($2->name, &currentTable, currentLevel, ID);

// }

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = ( char * ) malloc( strlen( $2->name ) * 2 + strlen( $4->code ) + strlen( $6->code ) + strlen( localValBuffer ) + 20 );

// $2->calltype = 0;

if( params > 0 )

{

sprintf( $$->code, "%s PROC%s\n%s\tsub esp, %d\n%s\tret %d\n%s ENDP\n", $2->name, $4->code, localValBuffer, (paramcount-realParam)*4, $6->code, 4*params, $2->name );

}

else

{

sprintf( $$->code, "%s PROC%s\n%s\tsub esp, %d\n%s\tret\n%s ENDP\n", $2->name, $4->code, localValBuffer, (paramcount-realParam)*4, $6->code, $2->name );

}

params = 0;

paramcount = 0;

realParam = 0;

sprintf( localValBuffer, "" );

}

| type_specifer ID '(' params ')' ';'

{

if( lookup( $2->name, currentTable ) == NULL )

{

$2 = install($2->name, &currentTable, currentLevel, ID);

}

else

{

char msg[100];

sprintf( msg, "The Function %s redefinition: ", $2->name );

yyerror( msg );

}

$2->calltype = 0;

$$ = ( expr * ) malloc( sizeof( expr ) );

$$->code = "";

sprintf( funBuffer, "%s%s PROTO%s\n", funBuffer, $2->name, $4->code );

}

;

params : param_list

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = $1->code;

}

| VOID

{

params = 0;

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = "";

}

;

param_list : param_list ',' param

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + strlen( $3->code ) + 1 );

sprintf( $$->code, "%s%s", $1->code, $3->code );

params++;

}

| param

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = $1->code;

params = 1;

}

;

param : type_specifer ID

{

Symbol temp = install($2->name, &currentTable, currentLevel+1, ID);

$$->code = (char *) malloc( 100 );

switch( *$1 )

{

case 1:

temp->ty = 1;

yyerror( "Parameters Type Error: " );

break;

case 2:

temp->ty = 2;

sprintf( $$->code, ", %s:DWORD", $2->name );

break;

case 3:

temp->ty = 3;

sprintf( $$->code, ", %s:DWORD", $2->name );

break;

default:

break;

}

}

| type_specifer '*' ID

{

Symbol temp = install($3->name, &currentTable, currentLevel+1, ID);

$$->code = (char *) malloc( 100 );

switch( *$1 )

{

case 1:

temp->ty=11;

sprintf( $$->code, ", %s:PTR DWORD", $3->name );

break;

case 2:

temp->ty=12;

sprintf( $$->code, ", %s:PTR WORD", $3->name );

break;

case 3:

temp->ty=13;

sprintf( $$->code, ", %s:PTR BYTE", $3->name );

break;

}

}

| type_specifer ID '[' ']'

{

Symbol temp = install($2->name, &currentTable, currentLevel+1, ID);

$$->code = (char *) malloc( 100 );

switch( *$1 )

{

case 1:

temp->ty = 21;

yyerror( "Parameters Type Error: " );

break;

case 2:

temp->ty = 22;

sprintf( $$->code, ", %s:PTR WORD", $2->name );

break;

case 3:

temp->ty = 23;

sprintf( $$->code, ", %s:PTR BYTE", $2->name );

break;

}

}

| type_specifer '*' ID '[' ']'

{

Symbol temp = install($3->name, &currentTable, currentLevel+1, ID);

$$->code = (char *) malloc( 100 );

switch( *$1 )

{

case 1:

temp->ty = 31;

sprintf( $$->code, ", %s:DWORD", $3->name );

break;

case 2:

temp->ty = 32;

sprintf( $$->code, ", %s:DWORD", $3->name );

break;

case 3:

temp->ty = 33;

sprintf( $$->code, ", %s:DWORD", $3->name );

break;

}

}

;

compound_stmt : '{' local_declarations statement_list '}'

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->code ) + strlen( $3->code ) + 12 );

sprintf( $$->code, "%s%s", $2->code, $3->code );

}

;

local_declarations : /*空值*/

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = "";

}

| local_declarations loc_declaration

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + strlen( $2->code ) + 1 );

sprintf( $$->code, "%s%s", $1->code, $2->code );

}

;

statement_list : /*空值*/

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 2 );

$$->code = "";

}

| statement_list statement

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + strlen( $2->code ) + 1 );

sprintf( $$->code, "%s%s", $1->code, $2->code );

}

;

statement : expression_stmt

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code )+20 );

sprintf( $$->code, "%s\n", $1->code );

}

| compound_stmt

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = $1->code;

}

| if_stmt

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = $1->code;

}

| while_stmt

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = $1->code;

}

| return_stmt

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = $1->code;

}

;

expression_stmt : expression ';'

{

$$ = (expr*) malloc( sizeof( expr ) );

//$$->code = (char *) malloc( strlen( $1->code )+20 );

$$->code= $1->code;

}

| ';'

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 2 );

sprintf( $$->code, "" );

}

;

if_stmt : IF '(' expression ')' statement

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->code ) + strlen( $5->code ) + strlen( $3->temp ) + 30 );

sprintf( $$->code, "%s\t.IF %s\n%s\t.ENDIF\n", $3->temp, $3->code, $5->code );

}

| IF '(' expression ')' statement ELSE statement

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->code ) + strlen( $5->code ) + strlen( $3->temp ) + strlen( $7->code ) + 10 );

sprintf( $$->code, "%s\t.IF %s\n%s\t.ELSE\n%s\t.ENDIF\n", $3->temp, $3->code, $5->code, $7->code );

}

;

while_stmt : WHILE '(' expression ')' statement

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->temp ) + strlen( $3->code ) + strlen( $5->code ) + strlen($3->temp) + 10 );

sprintf( $$->code, "_label%d:\n%s\t.IF !( %s ) \n\tjmp _label%d\n\t.ENDIF\n%s\tjmp _label%d\n_label%d:\n", label, $3->temp, $3->code,label+1, $5->code, label, label + 1 );

label += 2;

}

;

return_stmt : RETURN ';'

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 15 );

sprintf( $$->code, "\tmov eax, 0\n\tret\n" );

}

| RETURN expression ';'

{

$$ = (expr*) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + strlen( $2->code ) + 15 );

sprintf( $$->code, "%s\tmov eax, %s\n\tret\n", $2->code, $2->name );

}

;

expression : var '=' expression

{

if( $1->value == 0 )

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + strlen( $3->code )+ strlen( $3->name ) + 10 );

sprintf( $$->code, "%s\tmov eax, %s\n\tmov %s, eax\n", $3->code, $3->name, $1->code );

$$->name = (char *)malloc( sizeof( $1->name ) );

sprintf( $$->name, "%s", $1->name );

$$->temp = $$->code;

}

else

{

char *s = (char *) malloc( strlen( $1->name ) + strlen( $1->code ) + strlen( $3->code )+ strlen( $3->name ) + 100 );

$$ = (expr *) malloc( sizeof( expr ) );//sprintf( $$->code, "%s\tmov eax, %s\n%s\tmov %s, eax\n", $3->code, $3->name, $1->code, $1->name );

sprintf( s, "%s\tmov eax, ", $3->code );

sprintf( s, "%s%s\n", s, $3->name );

sprintf( s, "%s%s\tmov ", s, $1->code );

sprintf( s, "%s%s, eax\n", s, $1->name );

$$->code = (char *) malloc( strlen( $1->name ) + strlen( $1->code ) + strlen( $3->code )+ strlen( $3->name ) + 100 );

$$->code = s;

$$->name = (char *)malloc( sizeof( $1->code ) );

sprintf( $$->name, "%s", $1->code );

$$->temp = $$->code;

}

}

| simple_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + 1 );

$$->name = $1->name;

sprintf( $$->code, "%s", $1->code );

$$->temp = $1->temp;

}

;

var : ID

{

if( lookup( $1->name, currentTable ) == NULL )

{

char msg[100];

sprintf( msg, "Variable %s haven't been defined: ", $1->name );

yyerror( msg );

}

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->name ) + 1 );

sprintf( $$->code, "%s", $1->name );

$$->is_const = 1;

$$->name = $1->name;

$$->value = 0;

}

| ID '[' expression ']'

{

Symbol temp;

if( temp = lookup( $1->name, currentTable ) == NULL )

{

char msg[100];

sprintf( msg, "Variable %s haven't been defined: ", $1->name );

yyerror( msg );

}

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->code ) + strlen( $3->name ) + 10 );

sprintf( $$->code, "%s\tmov edi, %s\n", $3->code, $3->name );

$$->name = (char *)malloc( sizeof( $1->name ) );

sprintf( $$->name, "DWORD ptr %s[edi]", $1->name );

$$->temp = $$->code;

$$->value = 1;

}

| '*' ID

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->name ) + 10 );

sprintf( $$->code, "\tmov esi, %s\n", $2->name );

$$->name = (char *)malloc( sizeof( 6 ) );

sprintf( $$->name, "DWORD PTR [esi]" );

$$->value = 1;

}

;

simple_expression : additive_expression relop additive_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $3->name ) + strlen( $2->code ) + 5 );

sprintf( $$->code, "edx %s %s", $2->code, $3->name );

$$->temp = (char *) malloc( strlen( $1->code ) +strlen( $1->code ) + strlen( $3->code ) + 20 );

sprintf( $$->temp, "%s%s\tmov edx, %s\n", $3->code, $1->code, $1->name );

}

| additive_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->value = $1->value;

$$->code = $1->code;

$$->name = $1->name;

}

;

relop : LE

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 3 );

sprintf( $$->code, "<=" );

}

| LT

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 2 );

sprintf( $$->code, "<" );

}

| GT

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 2 );

sprintf( $$->code, ">" );

}

| GE

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 3 );

sprintf( $$->code, ">=" );

}

| EQ

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 3 );

sprintf( $$->code, "==" );

}

| NE

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 3 );

sprintf( $$->code, "!=" );

}

;

additive_expression : additive_expression addop term

{

$$ = (expr *) malloc( sizeof( expr ) );

switch( *$2 )

{

case '+':

$$->code = (char *) malloc( strlen($1->code) + strlen($1->name) + strlen($3->name) + strlen($3->code) + 1024 );

sprintf( $$->code, "%s%s\tmov eax, %s\n\tadd eax, %s\n", $1->code, $3->code, $1->name, $3->name );

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "[ebp-%d]", 4*(paramcount+1) );

paramcount++;

sprintf( $$->code, "%s\tmov %s, eax\n", $$->code, $$->name );

break;

case '-':

$$->code = (char *) malloc( strlen($1->code) + strlen($1->name) + strlen($3->name) + 1024 );

sprintf( $$->code, "%s%s\tmov eax, %s\n\tsub eax, %s\n", $3->code, $1->code, $1->name, $3->name );

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "[ebp-%d]", 4*(paramcount+1) );

paramcount++;

sprintf( $$->code, "%s\tmov %s, eax\n", $$->code, $$->name );

break;

break;

case OR:

break;

}

$$->value = 0;

}

| term

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + 1 );

if( $1->is_const == 1 )

{

strcpy( $$->code, "" );

}

else

{

strcpy( $$->code, $1->code );

}

$$->name = $1->name;

$$->value = 1;

}

;

addop : '+'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = '+';

}

| '-'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = '-';

}

;

term : term mulop unary_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

switch( *$2 )

{

case '*':

$$->code = (char *) malloc( strlen($1->code) + strlen($1->name) + strlen($3->name) + 1024 );

sprintf( $$->code, "%s\tmov eax, %s\n\tmov ebx, %s\n\timul ebx\n", $1->code, $1->name, $3->name );

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "[ebp-%d]", 4*(paramcount+1) );

paramcount++;

sprintf( $$->code, "%s\tmov %s, eax\n", $$->code, $$->name );

break;

case '/':

$$->code = (char *) malloc( strlen($1->code) + strlen($1->name) + strlen($3->name) + 1024 );

sprintf( $$->code, "%s\tmov eax, %s\n\tcdq\n\tmov ebx, %s\n\tidiv ebx\n", $1->code, $1->name, $3->name );

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "[ebp-%d]", 4*(paramcount+1) );

paramcount++;

sprintf( $$->code, "%s\tmov %s, eax\n", $$->code, $$->name );

break;

case '%':

$$->code = (char *) malloc( strlen($1->code) + strlen($1->name) + strlen($3->name) + 1024 );

sprintf( $$->code, "%s\tmov eax, %s\n\tcdq\n\tmov ebx, %s\n\tidiv ebx\n", $1->code, $1->name, $3->name );

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "[ebp-%d]", 4*(paramcount+1) );

paramcount++;

sprintf( $$->code, "%s\tmov %s, edx\n", $$->code, $$->name );

break;

}

$$->is_const = 0;

}

| unary_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + 1 );

if( $1->is_const == 1 )

{

strcpy( $$->code, "" );

}

else

{

strcpy( $$->code, $1->code );

}

$$->name = $1->name;

$$->is_const = $1->is_const;

}

;

mulop : '*'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = '*';

}

| '/'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = '/';

}

| '%'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = '%';

}

;

unary_expression : unaryop unary_expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->code ) + 10 );

sprintf( $$->code, "%s\tmov ebx, %s\n\tneg ebx\n", $2->code, $2->name );

$$->name = (char *) malloc( 6 );

sprintf( $$->name, "ebx" );

$$->is_const = 0;

}

| factor

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = $1->code;

$$->name = $1->name;

$$->is_const = $1->is_const;

}

;

unaryop : '-'

{

$$ = (char *) malloc( sizeof( char ) );

*$$ = NEG;//用数NEG表示负号;

}

;

factor : '(' expression ')'

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $2->code ) + 1 );

sprintf( $$->code, "%s", $2->code );

$$->name = $2->name;

$$->is_const = 0;

}

| var

{

$$ = (expr *) malloc( sizeof( expr ) );

if( $1->value == 0 )

{

$$->code = (char *) malloc( strlen( $1->code ) + 1 );

sprintf( $$->code, "%s", $1->code );

$$->name = $1->name;

$$->is_const = 1;

}

else if( $1->value == 1 )

{

$$->code = (char *) malloc( strlen( $1->name ) + 1 );

sprintf( $$->code, "%s", $1->name );

$$->name = $1->code;

$$->is_const = 1;

}

}

| call

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->code ) + 1 );

sprintf( $$->code, $1->code );

$$->name = ( char * )malloc(4);

sprintf( $$->name, "eax" );

$$->code = $1->code;

$$->is_const = 0;

}

| NUM

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->name ) + 1 );

sprintf( $$->code, "" );

$$->is_const = 1;

$$->value = atoi( $1->name );

$$->name = $1->name;

}

| STRING

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->name ) + 1 );

sprintf( $$->code, "" );

$$->is_const = 1;

$$->name = (char *) malloc( 20 );

sprintf( $$->name, "_msg%d", msgIndex );

sprintf( varBuffer, "%s\t%s BYTE %s, 0\n", varBuffer, $$->name, $1->name );

sprintf( $$->name, "offset _msg%d", msgIndex );

msgIndex++;

}

;

call : ID '(' args ')'

{

if( lookup( $1->name, currentTable ) == NULL )

{

char msg[100];

sprintf( msg, "The Function %s must be declared: ", $1->name );

yyerror( msg );

}

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->name ) + strlen( $3->code) + 50 );

sprintf( $$->code, "%s\tcall %s\n", $3->code, $1->name );

}

;

args : /*空值*/

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( 1 );

sprintf( $$->code, "" );

}

| arg_list

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen($1->code) + strlen( $1->temp ) + 1 );

sprintf( $$->code, "%s%s", $1->temp, $1->code );

}

;

arg_list : arg_list ',' expression

{

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen($1->code) + strlen($3->code) + 10 );

sprintf( $$->code, "\tpush %s\n%s", $3->name, $1->code );

$$->temp = (char *) malloc( strlen( $1->temp ) + strlen( $3->code ) + 1 );

sprintf( $$->temp, "%s%s", $1->temp, $3->code );

callparam++;

}

| expression

{

callparam = 1;

$$ = (expr *) malloc( sizeof( expr ) );

$$->code = (char *) malloc( strlen( $1->name ) + 10 );

sprintf( $$->code, "\tpush %s\n", $1->name );

$$->temp = (char *) malloc( strlen( $1->code ) + 10 );

sprintf( $$->temp, "%s", $1->code );

}

;

calling_convention : __CDECL

{

$$ = (expr *) malloc( sizeof( expr ) );

*$$ = 1;

}

| __STDCALL

{

$$ = (expr *) malloc( sizeof( expr ) );

*$$ = 0;

}

;

%%

#include "Lex.yy.c"

int yyparse();

void yyerror();

int main( int argc, char **argv )

{

FILE *fp ;

currentTable = table( NULL, 0 );

currentLevel = 0;

++argv;

--argc;

if(argc > 0)

yyin = fopen(argv[0],"r");

else

yyin = stdin;

++argv;

--argc;

if(argc > 0)

yyout = fopen(argv[0],"w");

else

yyout = stdout;

// fp = fopen( "a.txt", "r" );

// yyin = fp;

// fp = fopen( "c.asm", "w" );

// yyout = fp;

return(yyparse());

}

void yyerror( char *temp )

{

printf( "\nline %d: %s %s %d\n", lineno, temp, yytext, currentLevel );

exit(1);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有