www.pudn.com > Micro.rar > Syntax.cpp


#include "StdAfx.h" 
#include ".\syntax.h" 
 
 
#define  DEBUG  true 
 
Syntax::Syntax(void) 
{ 
} 
 
Syntax::~Syntax(void) 
{ 
} 
/////   Lex 
extern Word  g_token; 
extern token current_token; 
extern bool  matched; 
/////   Semantic 
extern Level  curLevel; 
 
//        ->  SCANEOF #finish 
void  system_goal		(void) { 
	program(); 
	match( SCANEOF ); 
	finish(); 
} 
//            -> #start   {,  } 
void  program			(void) { 
	if( DEBUG ) 
		fprintf(stderr, "program:\n"); 
	start(); 
	token tk = next_token(); 
	while( tk == FUNCTION ) { 
		function(); 
		tk = next_token(); 
	} 
} 
//           -> function   (  ) begin  end 
//           -> function   (              ) begin  end 
void		function		(void) { // new added 
	if( DEBUG ) 
		fprintf(stderr, "function:\n"); 
	expr_rec fun_name; 
	match( FUNCTION ); 
	curLevel = LOCAL;// 进入局部作用域 
	fname( & fun_name ); 
	match( LPAREN );	if( next_token() == ID ) { param_list(); }	match( RPAREN ); 
	match( BEGIN ); 
	statement_list(); 
	match( END ); 
	curLevel = GLOBAL;// 进入全局作用域 
} 
void  statement_list	() { 
	statement(); 
	while( true ) { 
		if( DEBUG ) 
			fprintf(stderr, "statement_list:\n"); 
		switch( next_token() ) { 
		case ID: 
		case READ: 
		case WRITE: 
			statement(); 
			break; 
		default: 
			return; 
		} 
	} 
} 
/* 
        ->  :=   #assign ; 
        -> read(  ); 
        -> write (  ); 
        ->  (  ) #process_func_call; 
        ->  (                 ) #process_func_call; 
*/ 
void  statement		(void) { 
	token tok = next_token(); 
	if( DEBUG )  fprintf(stderr, "statement: %d\n", tok); 
 
	expr_rec  left, right; 
	switch( tok ) { 
	case ID: 
		ident(&left); // match(ID); 
		if( next_token() == ASSIGNOP ) { 
			match(ASSIGNOP); expression(&right);   assign(left, right); // # 
		} else if ( next_token() == LPAREN ) { 
			match( LPAREN ); 
			if( next_token() == ID ) {	argument_list();	} 
			match( RPAREN ); 
			process_func_call();// # check and generate 
		} else { 
			syntax_error( next_token() ); 
		} 
		match(SEMICOLON); 
		break; 
	case READ: 
		match(READ); match(LPAREN); read_list(); match(RPAREN); match(SEMICOLON); 
		break; 
	case WRITE: 
		match(WRITE); match(LPAREN); write_list(); match(RPAREN); match(SEMICOLON); 
		break; 
	} 
} 
//         ->  #process_param {,  #process_param } 
void		param_list		(void) { // new added 
	expr_rec  id; 
	ident( & id); 
	process_param(  );// # 
	while( next_token() == COMMA ) { 
		match( COMMA ); 
		ident( & id ); 
		process_param(  );// # 
	} 
} 
//      ->  #process_argu {,  #process_argu } 
void		argument_list	(void) { // new added 
	expr_rec  id; 
	ident( & id ); 
	process_argu();// # 
	while( next_token() == COMMA ) { 
		ident( & id ); 
		process_argu();// # 
	} 
} 
void  read_list			(void) { // id_list 
	expr_rec t; 
	ident( &t );//    match(ID); 
	read_id(t); 
	while( next_token() == COMMA ) { 
		match(COMMA); 
		ident( &t );//   match(ID); 
		read_id(t); 
	} 
} 
void  write_list		(void) { // write_list 
	expr_rec  exp; 
	expression(&exp); 
	write_expr(exp);// # 
	while( next_token() == COMMA ) { 
		match( COMMA ); 
		expression(&exp); 
		write_expr(exp);// # 
	} 
} 
//         ->  {    #gen_infix  } 
void  expression		( expr_rec * result ) { 
	token t; 
	expr_rec  left, right; 
	op_rec    op; 
	if( DEBUG )	{	fprintf(stderr, "expression:\n");  } 
	mul_expr( &left );//primary( &left ); before change is primary 
	for( t = next_token(); t == PLUSOP || t == MINUSOP ; t = next_token() ) { 
		add_op( &op ); 
		mul_expr( &right );//primary( &right ); before change is primary 
		left = gen_infix(left, op, right);// # 
	} 
	*result = left; 
} 
//           ->  {   } 
void		mul_expr		(expr_rec * result) { // new added 
	token  t; 
	expr_rec left, right; 
	op_rec op; 
	if( DEBUG )  {  fprintf(stderr, "mul_expr:\n");  } 
	primary( &left ); 
	for( t = next_token(); t == MULOP || t == DIVOP ; t = next_token() ) { 
		mul_op( &op ); 
		primary( &right ); 
		left = gen_infix(left, op, right);// # 
	} 
	*result = left; 
} 
void  primary			(expr_rec * exp) { 
	token tok = next_token(); 
	if( DEBUG )  fprintf(stderr, "primary: %d\n", tok); 
	switch(tok) { 
	case LPAREN: 
		match(LPAREN);  expression(exp);  match(RPAREN); 
		break; 
	case ID: 
		ident( exp );// match(ID); # 
		break; 
	case INTLITERAL: 
		match(INTLITERAL); 
		*exp = process_literal();// # 
		break; 
	default: 
		syntax_error(tok); 
		break; 
	} 
} 
void  add_op			(op_rec * op) { 
	token t = next_token(); 
	if( DEBUG )  fprintf(stderr, "add_op: %d\n", t); 
	if( t == PLUSOP || t == MINUSOP ) { 
		match(t); 
		*op = process_op(); 
	} else { 
		syntax_error(t); 
	} 
} 
void  mul_op			(op_rec * op) { 
	token t = next_token(); 
	if( DEBUG )  fprintf(stderr, "mul_op: %d\n", t); 
	if( t == MULOP || t == DIVOP ) { 
		match(t); 
		*op = process_op(); 
	} else { 
		syntax_error(t); 
	} 
} 
void  ident			(expr_rec * exp) { 
	match(ID); 
	*exp = process_id();// # 
} 
void		fname			(expr_rec * exp) { // new added 
	match(ID); 
	gen_func_name( *exp ); 
} 
token next_token() { 
	if( matched ) { 
		current_token = scanner(); 
		matched = false; 
	} 
	return current_token; 
} 
void  match(token  tk) { 
	if( matched ) { 
		current_token = next_token(); 
	} 
	if( current_token != tk ) { 
		char  buf[50]; 
		if( tk == ID || INTLITERAL == tk ) 
			sprintf(buf, "[ Unmatch ] expect:%d  cur-tok:%d  text:%s", tk, current_token, g_token.buf); 
		else 
			sprintf(buf, "[ Unmatch ] expect:%d  cur-tok:%d", tk, current_token); 
		error(buf); 
		exit(3); 
	} 
	matched = true; 
	if( DEBUG ) { 
		if( ID == tk || INTLITERAL == tk ) { 
			fprintf(stderr, "match %d  %s %s\n", tk, getTokenText(tk), g_token.buf); 
		} 
		else 
			fprintf(stderr, "match %d  %s\n", tk, getTokenText(tk)); 
	} 
} 
 
void syntax_error(token t) { 
	char buf[100]; 
	fprintf(stderr, "[ Syntax Error ] - text:%s tok:%d", g_token.buf, t); 
	exit(4); 
}