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

📄 c--.y

📁 c—语言的句法分析器。读入一个C--语言程序
💻 Y
📖 第 1 页 / 共 3 页
字号:
%{
#include 	<ctype.h>
#include 	<string.h>
#include 	<stdio.h>
#include 	<stdlib.h>
#include <assert.h>

#define HASHSIZE 128
//s
typedef struct aa
{  int type;
	struct aa *next;
} fun_type;
typedef struct {
char *name; /* symbol name */
int scope; /* scope level */
int type;
int value;
int funargc;
fun_type *functype;
int isdeclar;
int offset; /* for functions: size of local variables */
} symbol ;

struct sym_entry {
symbol sym; /* this symbol */
struct sym_entry *next; /* next entry on hash chain */
};

struct table {
int level; /* scope level for this table */
struct table *previous; /* table at lower scope */
struct sym_entry *buckets[HASHSIZE]; /* hash buckets */
};

typedef struct
{
    char op;
    symbol *x, *y, *z;
} Quadruple;


typedef struct
{
    char *translation;
    int variable;
} myattribute;



struct string_data {
  int index;
  char * value;
};
int n_const_strings = 0;
struct string_data const_strings[100];

struct table * table_stack[100]; 
struct table * global_table; 
int table_len = 0;
int offset_stack[100];
int offset_len = 0;
int level = 0;
int verbose = 0;
int argccount=0;
int isfunction=0;
int isdeclartion=0;
fun_type *funtype=0;
void trace(char *s) { if (verbose) fprintf(stderr, s); }
//0
symbol *lookup(char *name, struct table *tp) {
struct sym_entry *p;
unsigned h = ((unsigned)name)&(HASHSIZE-1); /*not素数 */
//	printf("look up %s  level  %d       tp.level  %d       table_len-1 %d\n",name,level,tp->level,table_len-1);

do
for (p = tp->buckets[h]; p; p = p->next)
if (name == p->sym.name) {return &p->sym;}
while (tp = tp->previous);
return 0;
}
symbol *lookupred(char *name, struct table *tp) {
struct sym_entry *p;
unsigned h = ((unsigned)name)&(HASHSIZE-1); /*not素数 */

for (p = tp->buckets[h]; p; p = p->next)
if (name == p->sym.name){//printf("find the symobl %s\n",p->sym.name); 
         return &p->sym;}

return 0;
}

struct table * mktable(struct table *previous, int level) {
	int i;
	struct table *new = (struct table *)malloc(sizeof *new);
	new->previous = previous; new->level = level;
	for (i = 0; i < HASHSIZE; i++) new->buckets[i] = 0;
	return new;
}
//i
symbol *insert(char *name, struct table *tpp) {
unsigned h = ((unsigned)name)&(HASHSIZE-1);
struct table *tp = tpp;
struct sym_entry *p = (struct entry *)malloc(sizeof *p);
//printf("&&&&&&&&&tp->level =%d level=%d  inserting %s\n", tp->level,level,name);
if (tp->level < level) { // 当前scope level
	tp = mktable(tp, level);
//	printf("make new table\n");
	table_stack[table_len] = tp; 
	table_len ++;
	offset_stack[offset_len] = 0;
	offset_len ++;
}
p->sym.name = name; p->sym.scope = level;
if(isfunction) { p->sym.type = 1; }
	else p->sym.type = 0; /*假设是常数, 常数的类型为0*/
p->next = tp->buckets[h];
p->sym.funargc=0;
tp->buckets[h] = p; /* 新名字在表头 */
//printf("Inset  %s  level  %d       tp.level  %d       table_len-1 %d\n",name,level,tp->level,table_len-1);

return &p->sym;
}

typedef struct {
  int is_const;
  int value;
  int type;
  symbol * place;
  symbol * offset; /* for array */
  char * code;
} expr;

char * insert_id(char *name);

symbol * newtemp()
{
    static int index = 1;
    char tmpname[20];
    char * p;
    symbol * s;
    sprintf(tmpname, "__t%d", index);
    index++;
    s = insert(insert_id(tmpname), table_stack[table_len-1]);
    s->offset = offset_stack[offset_len-1];
    offset_stack[offset_len-1] += 4;
    return s;
}
%}

%token 	ID  NUM  INT  VOID  CHAR  IF  ELSE WHILE  RETURN  
	CDECL  STDCALL  EQ  NE  LT  GT  LE  GE   AND  OR  
        ADDOP CHARATER STRING
%start 	program

%right 	'='
%left  	ADDOP	
%left  	'*'     '/' 

%union{       char * _ident;
              char _op;
              char _relop[3];
              int value;
              symbol *_sym; 
              expr _expr;
};

%token <_ident> NUM
%token <_ident> ID
%token <_op> CHARATER
%token <_ident> STRING
%token <_op> ADDOP
%type <value> type_spec
%type <_sym> var
%type <_sym> fun_declar
%type <_sym> fun_tag
%type <value> params
%type <value> param
%type <value> param_list
%type <value> args
%type <value> arg_list
%type <_expr> factor
%type <_expr> unary_expr 
%type <_expr> term
%type <_expr> add_expr
%type <_expr> simple_expr
%type <_expr> logicand_expr
%type <_expr> logic_expr
%type <_expr> expr
%type <_op> mulop
%type <_op> unaryop 
%type <_relop> relop
//%token <_op> unaryop 
/* 为了简单起见,把所有能产生代码的非终极符也说明为_expr类型,其实应该用别的,但是也有code属性*/
%type <_expr> comp_stmt
%type <_expr> if_stmt
%type <_expr> while_stmt
%type <_expr> stmt_list
%type <_expr> stmt
%type <_expr> expr_stmt 
%type <_expr> return_stmt
%type <_expr> call

%%
program  :    M declar_list
	{  fprintf(yyout, "	.data\n");
       { int i;
        struct sym_entry *p;
         
        for (i = 0; i< n_const_strings; i++) {
 	   	fprintf(yyout, "s@%d	label	byte", const_strings[i].index);
		fprintf(yyout, "	db	\"%s,0\"",const_strings[i].value); /* \n可能需要变成 10 */
        }
       /* 生成全局变量 */
        for (i = 0; i< HASHSIZE; i++) {
			p = global_table->buckets[i]; /* hash buckets */
			while (p) {
				if (p->sym.type == INT) fprintf(yyout, "_%s	DD	?\n", p->sym.name); else
				if (p->sym.type == CHAR) fprintf(yyout, "_%s	DB	?\n", p->sym.name);
				p = p->next;
			}
	    }
	   fprintf(yyout, "	public	_main\n");
	
	   fprintf(yyout, "	end\n");
     }}
      ;
M : {   
	fprintf(yyout, "	.386p\n");
	fprintf(yyout, "	model flat\n");
	fprintf(yyout, "	.code\n");
	     
	global_table = mktable(NULL, 0); 
	table_stack[table_len] = global_table; 
	table_len ++;
	offset_stack[offset_len] = 0;
	offset_len ++;
}
     ;
declar_list  :    declar_list declar 
	{  trace("declar_list => declar_list declar\n");  }
      |   declar
      ;
declar  :    var_declar 
      |   fun_declar
      ;
var_declar  :    type_spec   ID   ';' 
	{  
		//1
	struct table * tp = table_stack[table_len-1];
	if(lookupred($2,tp)==0){
	symbol * p = insert($2, tp);
  int width = 0;
	p->type = $1;
	p->offset = offset_stack[offset_len-1];
    if ($1 == INT) width = 4; else if ($1 == CHAR) width = 1;
        offset_stack[offset_len-1] += width;
    }else   printf("line %d: error: %s :redefinition\n", nline, $2);
    	  
	  trace("var_declar => type_spec ID  ;\n"); 
	    } //12
      |   type_spec   ID  '['  NUM  ']'     ';'
	{  struct table * tp = table_stack[table_len-1];
	   trace("var_declar => type_spec ID [ NUM ] ;\n");  
	   if(lookupred($2,tp)==0){	 
	    symbol * p = insert($2, tp); 
        int width = 0;
        int widthall=width;
	      p->type = $1;
	      p->offset = offset_stack[offset_len-1];
        if ($1 == INT) width = 4; else if ($1 == CHAR) width = 1;
        offset_stack[offset_len-1] += widthall;
    }else   printf("line %3d error: %s :redefinition\n", nline, $2);    
	}  //13
      |   type_spec   '*'  ID   ';' 
	{ struct table * tp = table_stack[table_len-1]; 
		trace(" var_declar =>  type_spec * ID ;\n");
		if(lookupred($3,tp)==0){	 
	    symbol * p = insert($3, tp); 
        int width = 0;
        int widthall=width;
	      p->type = $1;
	      p->offset = offset_stack[offset_len-1];
        if ($1 == INT) width = 4; else if ($1 == CHAR) width = 1;
        offset_stack[offset_len-1] += widthall;
	   }else   printf("line %3d error: %s :redefinition\n", nline, $3);	  
  }
      |   type_spec   '*'  ID  '['  NUM  ']'     ';'
	{ 
		 struct table * tp = table_stack[table_len-1]; 
		 trace("var_declar =>  type_spec * ID [ NUM ] ;\n"); 
		 if(lookupred($3,tp)==0){	 
	    symbol * p = insert($3, tp); 
        int width = 0;
        int widthall=width;
	      p->type = $1;
	      p->offset = offset_stack[offset_len-1];
        if ($1 == INT) width = 4; else if ($1 == CHAR) width = 1;
        offset_stack[offset_len-1] += widthall;
		   }else   printf("line %3d error: %s :redefinition\n", nline, $3);	
		 }
		  |  error  '\n'
		
      ;
type_spec  :    INT
	{  $$ = INT;  //printf("type_spec   %d\n",$$); 
		}
      |   VOID 
	{  $$ = VOID;  //printf("type_spec   %d\n",$$); 
		}
      |   CHAR
	{  $$ = CHAR;  //printf("type_spec   %d\n",$$);
		}
      | error {fprintf(stderr, "line %d :type name expected\n",nline); yyerrok; } 
      ;
//3
fun_declar  :    type_spec  fun_tag   '(' LL params   ')'  comp_stmt
	{  fprintf(yyout, "_%s	proc	near\n", $2->name);  
	   fprintf(yyout, "	push      ebp\n");
	   fprintf(yyout, "	mov       ebp,esp\n");
           $2->offset = offset_stack[offset_len-1];
           $2->type=$1;
        //   printf("function type is %d\n",$2->type);
	   fprintf(yyout, "	sub	  esp, %d\n", $2->offset);
	   fprintf(yyout, "%s\n", $7.code);
	   fprintf(yyout, "	.....\n");
	   fprintf(yyout, "	ret\n");
	   fprintf(yyout, "_%s	endp\n\n", $2->name);  
	   
	    printf("_%s	:\n", $2->name); 	
	      if($2->isdeclar==1) {
	      	 	fun_type *p1=$2->functype,*p2=funtype;int i;

⌨️ 快捷键说明

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