save

#include <stdio.h>
#include "lily.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
extern int get_token();

char test[100][100]
={	"begin",	
	"int",	  "char",  "void" ,   "pint",  "pchar",  
	"pvoid",   "if",    "else",    "for",  "while",         
	"return", "ID",	   "NUM",     "14",    "15",
	"16",     "17",    "18",      "19",    "20",        
	"=",      "+",     "-",       "*",     "/",                 
	"(",      ")",     "[",       "]",     "{",      	 
	"}",      ",",	   ":",       ";",     "'",		   
	"\"",	  "<=",	   "<",       ">=",	   ">",             
	"==",     "!=",    "&",		  "|",	   "!",           
	"&&",     "||" };

extern int save_line;
int current_line;

int main(int argc, char *argv[])
{
	int a= -999;
	freopen( "./lexTest/2.txt", "r", stdin );
	//  test
/*	while( (a = get_token() ) != FINISH  )
	{
		if( save_line == current_line )
			printf( "%s\t", test[a] );
		else
		{
			current_line = save_line;
			printf( "\n%s\t", test[a] );
		}
	}*/
	//printf( "\n\n" );
	program();
	
	return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lily.h"

#define MAX_WORD_LEN 20
#define MAX_INPUT_LEN 1000 
#define RESEVER_WORD_NUM 11

char * resever_word[] = 
{
 "int",   "char", "void", "pint", "pchar", 
 "pvoid", "if",   "else", "for",  "while", 
 "return"
};		


char save_word[100];
int save_num;
int save_line;


static char input_line[105];
static int input_len;
static int pos;


static int is_resever_word()
{
	int i;
	for( i = 0; i < RESEVER_WORD_NUM; i++ )
	{
		if( !strcmp( resever_word[i], save_word ) )
				return i+1;
	}
	return -1; 
}

static int get_next_word() 
{
	if( pos >= input_len )
	{
		if( fgets( input_line, MAX_INPUT_LEN, stdin ) )
		{	
			pos = 0;
			save_line++;
			input_len = strlen( input_line );
			if( input_len > MAX_INPUT_LEN )
			{
				fprintf( stderr, "input_line out of max range\n" );
				exit( 0 ); 
			}
			return input_line[pos++];
		}
		else
		{
			return FINISH;
		}
	}
	else
		return input_line[pos++];
}


int get_token()
{
	int c, len, i, max_word_len, state, token, flag, pause_line, pause_block;
	
	state = START;
	pause_line = 0;
	pause_block = 0; 
	
	while( state != OVER  )
	{
		if( state == PAUSE )
		{
			if( pause_line )
			{
				pause_line = 0;
				pos = input_len;
				state = START;
			}
			if( pause_block )
			{
				while( (c = get_next_word()) != FINISH )
				{
					if( c == '*' && input_line[pos] == '/' )
					{
						input_line[pos++];
						break;
					}
				}
				if( c == FINISH )
					return FINISH; 
				pause_block = 0;
				state = START;
			}
		}
		c = get_next_word();
		if( c == FINISH )
			return FINISH;
		if( c == ' ' || c == '\t' || c == '\n' )
			continue;
		if( isalpha( c ) || c == '_' )
		{
			i = 0;
			max_word_len = 0;
			do
			{
				save_word[i++] = c;
				c = input_line[pos++];
				max_word_len++;
			}while( isdigit( c ) || c == '_' || isalpha( c ) );
			pos--;
			if( max_word_len >= 20 )
			{
				fprintf( stderr, "word's max len is 20"); // 以后要写一个错误处理函数
				exit( 0 ); 
			}
			save_word[i] = '\0';
			token = TOK_ID;
			state = OVER;
		}
		else if( isdigit( c ) )
		{
			i = 0;
			if( flag == '-' )
				save_word[i++] = '-';
			while( isdigit( c ) )	
			{
				save_word[i++] = c;
				c = input_line[pos++];
			}
			pos--;
			save_word[i] = '\0';
			save_num = atoi( save_word );
			token = TOK_NUM;
			state = OVER;
			flag = 0;
		}
		else
		{
			state = OVER;
			switch( c ) 
			{	
				case '+':
					token = TOK_PLUS;
					break;
				case '-':
					token = TOK_MINUS;
					break;
				case '*':
					token = TOK_MUL;
					break;
				case '/':
					if( input_line[pos] == '/' )
					{
						input_line[pos++];
						state = PAUSE;
						pause_line = 1;
					}
					else if( input_line[pos] == '*' )
					{
						input_line[pos++];
						state = PAUSE;
						pause_block = 1;
					}
					else
					{
						token = TOK_DIV;
					}
					break;
				case '=':
					if( input_line[pos] == '=' )
					{
						input_line[pos++];
						token = TOK_EQ;
					}
					else
						token = TOK_ASSIGN;
					break;
				case '>':
					if( input_line[pos] == '=' ) 
					{
						input_line[pos++];
						token = TOK_GE;
					}
					else
						token = TOK_GT;
					break;
				case '<':
					if( input_line[pos] == '=' )
					{
						input_line[pos++];
						token = TOK_LE;
					}
					else
						token = TOK_LT;
					break;
				case '!':
					if( input_line[pos] == '=' )
					{
						input_line[pos++];
						token = TOK_NE;
					}
					else
						token = TOK_NOT;
					break;
				case '&':
					if( input_line[pos] == '&' )
					{
						input_line[pos++];
						token = TOK_ANDAND;
					}
					else
						token = TOK_AND;
					break;
				case '|':
					if( input_line[pos] == '|' )
					{
						input_line[pos++];
						token = TOK_OROR;
					}
					else
						token = TOK_OR;
					break;
				case ',':	
					token = TOK_COMMA;
					break;
				case ':'://no gonna use 'condition ?  true : false'
					token = TOK_COLON;
					break;
				case ';':
					token = TOK_SEMI;
					break;
				case 39:	//  '
					token = TOK_SQUTOA;
					break;
				case 34:	//  "
					token = TOK_DQUTOA;
					break;
				case '(':
					token = TOK_LPAREN;               
					break;
				case ')':
					token = TOK_RPAREN;
					break;
				case '[':
					token = TOK_LSQUARE;
					break;
				case ']':
					token = TOK_RSQUARE;
					break;
				case '{':
					token = TOK_LBRACKET; 
					break;
				case '}':
					token = TOK_RBRACKET;
					break;
			}
		}
	}
	if( token == TOK_ID )
	{
		int t;
		if( (t = is_resever_word()) != -1 )
			token = t; 		
	}
	return token;
}

#ifndef LILY_H
#define LILY_H
 
#define TOK_INT            1	    
#define TOK_CHAR           2
#define TOK_VOID           3
#define TOK_PINT           4
#define TOK_PCHAR          5		
#define TOK_PVOID		   6		    
#define TOK_IF             7
#define TOK_ELSE           8        
#define TOK_FOR            9        
#define TOK_WHILE          10   
#define TOK_RETURN         11

#define TOK_ID			   12
#define TOK_NUM            13		

#define TOK_ASSIGN         21	
#define TOK_PLUS           22			
#define TOK_MINUS      	   23			
#define TOK_MUL            24           
#define TOK_DIV            25          
#define TOK_LPAREN         26        
#define TOK_RPAREN         27        
#define TOK_LSQUARE        28    
#define TOK_RSQUARE        29    
#define TOK_LBRACKET       30		 
#define TOK_RBRACKET       31     
#define TOK_COMMA	       32			
#define TOK_COLON          33 			
#define TOK_SEMI      	   34
#define TOK_SQUTOA		   35
#define TOK_DQUTOA		   36	          	
#define TOK_LE	           37			
#define TOK_LT             38  			
#define TOK_GE			   39
#define TOK_GT             40
#define TOK_EQ             41           
#define TOK_NE             42 

#define TOK_AND			   43
#define TOK_OR			   44
#define TOK_NOT            45

#define TOK_ANDAND         46
#define TOK_OROR		   47


#define START  -1
#define PAUSE  -2
#define OVER   -3
#define FINISH -4

#define true 1
#define false 0
#define TRUE 1
#define FALSE 0 

#endif

#include <stdio.h>
#include <string.h>
#include "lily.h"

extern void program();

static void declaration(int type);
static void var_declaration(int type, char id[]);
static void fun_declaration(int type, char id[]);

static void params();
static void param_list();
static void param();

static void compound_stmt();
static void statement();
static void statement_list();

static void expression_stmt();
static void selection_stmt();
static void iteration_stmt();
static void return_stmt();
static void elseif_stmt();

static void expression();
static void var();
static void simple_expression();
static int relop();
static void additive_expression();
static int addop();
static void term();
static void factor();
static void call();

static void args();
static void arg_list();

int token;

extern char save_word[100];
extern int get_token();
extern int save_line;

extern char test[][100];

static void match(int type)
{
	if(token == type)
	{
		token = get_token();
  	}
  	else
  	{
      	fprintf(stderr, "line %d: expected token %s\n", save_line, test[type]);
  	}
}


void program()
{
	int entry_flag  = 0;
	token = get_token();
	while(token == TOK_INT || token == TOK_VOID || token == TOK_CHAR)
	{
		entry_flag = 1;
		declaration(token);
	}
	if(entry_flag)
		printf("succeed!!\texit()");
	else
		fprintf(stderr, "line %d: %s does not name a type", save_line, save_word );
}

static void declaration(int type)
{
	
	int temp;
	char id[30];
	
	type = token;
	
	match(type);
	match(TOK_ID);
	strcpy( id, save_word );
	
	if(token == TOK_LPAREN) 
	{
	    fun_declaration(type, id);
	}
	else if(token == TOK_SEMI || token == TOK_LSQUARE)
	{
		var_declaration(type, id);
	}
	else
	{
		fprintf(stderr, "line %d: unexpected token %s\n", save_line, save_word);
	}
	
}

static void fun_declaration(int type, char * id)
{
	/* match ( */
	match(TOK_LPAREN);
	
	params();
	
	/*match ) */
	match(TOK_RPAREN);
	
	compound_stmt();
}

static void var_declaration(int type, char *id)
{
	/* var */
	if(token == TOK_SEMI) 
	{
		match(TOK_SEMI);
	}
	/* array */
	else if(token == TOK_LSQUARE)
	{
		/* match [ */ 
		match(TOK_LSQUARE);
		match(TOK_NUM);
    	match(TOK_RSQUARE);
    	match(TOK_SEMI);
	}
	else
		fprintf(stderr, "line %d: param does not a type\n", save_line);
	
}

static void params()
{
	if(token == TOK_VOID)
	{
		match(TOK_VOID);
	}
	else if(token == TOK_INT)
	{
		param_list();
	}
	else if(token == TOK_CHAR)
	{
		param_list();
	}
	else
	{
		if(token != TOK_RPAREN)
			fprintf(stderr, "line %d: function params error\n", save_line);
			
		//else  is empty
	}
}

static void param_list()
{
	
	param();
	
	while(token == TOK_COMMA)
	{
		match(TOK_COMMA);
		param();
	}
	
}

static void param( )
{
	
	if(token == TOK_INT
	 ||token == TOK_CHAR
	 ||token == TOK_PINT
	 ||token == TOK_PCHAR
	 ||token == TOK_VOID
	 ||token == TOK_PVOID)
	{
		match(token);
	}
		
	match(TOK_ID);
	
	if(token==TOK_LSQUARE)
	{
		match(TOK_LSQUARE);
		match(TOK_RSQUARE);
	}	
		
}


static void compound_stmt()
{
	/* match { */
	match( TOK_LBRACKET );
	
	while(token == TOK_INT 
	   || token == TOK_CHAR 
	   || token == TOK_PINT
	   || token == TOK_PCHAR)
	{
		match(token);
		match(TOK_ID);
		var_declaration(0,"");
	}
	
	statement_list();
	
	/* match } */
	match( TOK_RBRACKET );	
	
}

static void statement_list()
{
	
	while(token == TOK_IF 
		||token == TOK_LBRACKET
        ||token == TOK_ID  //  a  
        ||token == TOK_MUL //  *a 
        ||token == TOK_AND //  &a
		||token == TOK_WHILE
        ||token == TOK_RETURN
		||token == TOK_SEMI
		||token == TOK_FOR	)
	{
    	statement();
  	}
  	
}

static void statement( )
{
	if(token == TOK_IF)
	{
		selection_stmt();
	}
	else if(token == TOK_LBRACKET)
	{
		compound_stmt();
	}
	else if(token == TOK_ID||token == TOK_MUL||token == TOK_AND)
	{
		expression_stmt();
	}
	else if(token == TOK_WHILE||token == TOK_FOR)
	{
		iteration_stmt();
	}
	else if(token == TOK_RETURN)
	{
		return_stmt();
	}
	else if(token == TOK_SEMI)
	{
		match(TOK_SEMI); 
	}
	else
		fprintf( stderr, "line %d: error statements", save_line );
		
}

static void expression_stmt()
{
	expression();
	match(TOK_SEMI);
}

static void selection_stmt()
{
	match(TOK_IF);
	match(TOK_LPAREN);
	expression();
	match(TOK_RPAREN);
	
	statement();
	
	if(token == TOK_ELSE)
	{
		match(TOK_ELSE);
		statement();
	}
}



static void iteration_stmt()
{
	if(token == TOK_WHILE)
	{
		match(TOK_WHILE);
		match(TOK_LPAREN); /* ( */
		expression();
		match(TOK_RPAREN); /* ) */
		statement();	
	}
	else		
	{
		match(TOK_FOR);
		match(TOK_LPAREN);/* ( */
		
		expression();
		match(TOK_SEMI);
		
		expression();
		match(TOK_SEMI);
		
		expression();
		match(TOK_RPAREN);/* ) */
	}
	
}


static void return_stmt()
{
	match(TOK_RETURN);
	
	if(token == TOK_SEMI)
	{
		match(TOK_SEMI);
	}
	else
	{
		expression();
		match(TOK_SEMI);
	}
	
}



static void expression( )
{
	
	simple_expression();
	if(token == TOK_ASSIGN)
	{	
		match(TOK_ASSIGN);
		expression();
	}
	
} 

static void var()
{
	
	if(token == TOK_MUL || token == TOK_AND)
	{
		/* if is * or & */
		match(token);
	}
	match(TOK_ID);
	if(token == TOK_LSQUARE)
	{
		match(TOK_LSQUARE);
		expression();
		match(TOK_RSQUARE);
	}
		
}

static void simple_expression( )
{
	additive_expression();
	
	if(token == TOK_LE
	 ||token == TOK_LT
	 ||token == TOK_GT
	 ||token == TOK_GE
	 ||token == TOK_EQ
	 ||token == TOK_NE )
	 {
	 	relop();
	 	additive_expression();
	 }
	
}

static int relop()
{
	switch(token)
	{
		case TOK_LE:
			match(TOK_LE);
			break;
		case TOK_LT:
			match(TOK_LT);
			break;
		case TOK_GT:
			match(TOK_GT);
			break;
		case TOK_GE:
			match(TOK_GE);
			break;
		case TOK_EQ:
			match(TOK_EQ);
			break;
		case TOK_NE:
			match(TOK_NE);
			break;
	}
	return token;
}

static void additive_expression()
{
	term();
	while(token == TOK_PLUS || token == TOK_MINUS)
	{
		/* match PLUS or MINUS */
		match(token);
		term();
	}
	
}

static void term()
{
	
	factor();
	while(token == TOK_MUL || token == TOK_DIV)
	{
		/* match MUL or DIV */
		match(token);
		factor();
	}
	
}

static void factor()
{
	if(token == TOK_LPAREN)
	{
		match(TOK_LPAREN);
		expression();
		match(TOK_RPAREN);
	}
	else if(token == TOK_ID
		  ||token == TOK_MUL
		  ||token == TOK_AND)
	{
		var();
		if(token == TOK_LPAREN)
		{
			call();
		}
	}
	else if(token == TOK_NUM)
	{
		match(TOK_NUM);
	}
	else if(token == TOK_PLUS
		  ||token == TOK_MINUS )
	{
		/*  0 + a ->  +a
		    0 - a ->  -a
		*/
		//first element is zero
	}
	else
		fprintf(stderr, "line %d: unexpected factor\n", save_line, save_word);
}

static void call()
{
	match(TOK_LPAREN);
	args();
	match(TOK_RPAREN);
}

void args()
{
	if(token == TOK_ID)
	{
		expression();
		while(token == TOK_COMMA)
		{
			match(TOK_COMMA);
			expression();
		}
	}	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值