commit
						22647d3898
					
				| @ -0,0 +1,10 @@ | ||||
| objs=parser.o lexer.o ast.o display.o | ||||
| CC=gcc | ||||
| 
 | ||||
| parser:$(objs) | ||||
| 	$(CC) -o parser ${objs} | ||||
| %.o:%.c | ||||
| 	$(CC) -c $< | ||||
| .PHONY: clean | ||||
| clean: | ||||
| 	rm parser $(objs) parser.c lexer.c parser.h -f | ||||
| @ -0,0 +1,716 @@ | ||||
| #include "ast.h" | ||||
| #include "parser.h"  //由bison根据parser.y生成 | ||||
| #define DEBUG 1 | ||||
| #define INTEGER_MINVALUE -2147483647 | ||||
| #define ARRAYCALL 123456789 | ||||
| int LEV=0; | ||||
| int main_flag = 0; | ||||
| int call_flag = 0; | ||||
| int main_call = 0; | ||||
| int current_offset = 0; | ||||
| char break_label[30]; | ||||
| char continue_label[30]; | ||||
| char case_temp[30]; | ||||
| char case_label[30]; | ||||
| char array_name[30]; | ||||
| char struct_name[33]; | ||||
| int struct_width = 0; | ||||
| int struct_flag = 0; | ||||
| int array_index = 0; | ||||
| int struct_var_flag = 0; | ||||
| int rtn, flag = 0; | ||||
| int rtn2, op; | ||||
| int return_flag = 0; | ||||
| struct ASTNode* left; | ||||
| struct ASTNode* right; | ||||
| char tokens[200][200]; //用来存储TAC语句信息
 | ||||
| const char spState[8][20] = { "FUNCTION", "GOTO", "CALL", "PARAM", "LABEL", "ARG", "RETURN","BLOCK" }; | ||||
| 
 | ||||
| int varlen = 0; //记录当前变量长度
 | ||||
| int lineNo = 0; //记录行号
 | ||||
| ASTNode *new_node(node_type type, ASTNode *left, ASTNode *mid, ASTNode *right, int int_val, float float_val, char *symbol, node_type d_type) { | ||||
|     ASTNode *n = (ASTNode *)malloc(sizeof(ASTNode)); | ||||
|     n->type = type; | ||||
|     n->left = left; | ||||
|     n->mid = mid; | ||||
|     n->right = right; | ||||
|     n->int_val = int_val; | ||||
|     n->float_val = float_val; | ||||
|     n->symbol = symbol; | ||||
|     n->d_type = d_type; | ||||
|     return n; | ||||
| } | ||||
| 
 | ||||
| int targetNum[1024]; | ||||
| int currentNum[1024]; | ||||
| int currentLayer = 0; | ||||
| int handle_next_display = 1; | ||||
| 
 | ||||
| int getBranchNum(ASTNode* T) | ||||
| { | ||||
| 	int count = 0; | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		count++; | ||||
| 	} | ||||
| 	if(T->right) | ||||
| 	{ | ||||
| 		count++; | ||||
| 	} | ||||
| 	if(T->mid) | ||||
| 	{ | ||||
| 		count++; | ||||
| 	} | ||||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| void printVarType(node_type type) | ||||
| { | ||||
| 	switch(type) | ||||
| 	{ | ||||
| 		case Int: | ||||
| 			printf("int"); | ||||
| 			break; | ||||
| 		case Float: | ||||
| 			printf("float"); | ||||
| 			break; | ||||
| 		case Void: | ||||
| 			printf("void"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			printf("unknown"); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void gapProcess() | ||||
| { | ||||
| 	for(int i=1;i<=currentLayer;i++) | ||||
| 	{ | ||||
| 		if(i < currentLayer) | ||||
| 		{ | ||||
| 			if(currentNum[i] <= targetNum[i]) | ||||
| 			{ | ||||
| 				printf("|  "); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				printf("   "); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if(currentNum[i] < targetNum[i]) | ||||
| 			{ | ||||
| 				printf("|--"); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				printf("`--"); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void gapManage(ASTNode* T, int reverse) | ||||
| { | ||||
| 	currentNum[currentLayer]++; | ||||
| 	currentLayer++; | ||||
| 	targetNum[currentLayer] = getBranchNum(T); | ||||
| 	currentNum[currentLayer] = 1; | ||||
| 	if(reverse) | ||||
| 	{ | ||||
| 		nextDisplayReverse(T); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		nextDisplay(T); | ||||
| 	} | ||||
| 	currentLayer--; | ||||
| } | ||||
| 
 | ||||
| void sameGapManage(ASTNode* T, int reverse) | ||||
| { | ||||
| 	currentNum[currentLayer]++; | ||||
| 	currentLayer++; | ||||
| 	targetNum[currentLayer] = getBranchNum(T) - 1; | ||||
| 	currentNum[currentLayer] = 1; | ||||
| 	if(T->right) | ||||
| 	{ | ||||
| 		display(T->right); | ||||
| 	} | ||||
| 	currentLayer--; | ||||
| 	display(T->left); | ||||
| } | ||||
| 
 | ||||
| void nextDisplay(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		display(T->left); | ||||
| 	} | ||||
| 	if(T->mid) | ||||
| 	{ | ||||
| 		display(T->mid); | ||||
| 	} | ||||
| 	if(T->right) | ||||
| 	{ | ||||
| 		display(T->right); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void nextDisplayReverse(ASTNode* T) | ||||
| { | ||||
| 	if(T->right) | ||||
| 	{ | ||||
| 		display(T->right); | ||||
| 	} | ||||
| 	if(T->mid) | ||||
| 	{ | ||||
| 		display(T->mid); | ||||
| 	} | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		display(T->left); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_root(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("CompUnit\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_comp_unit(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	handle_next_display = 0; | ||||
| 	switch(T->right->type) | ||||
| 	{ | ||||
| 	case ConstDecl: | ||||
| 		print_const_decl(T->right); | ||||
| 		break; | ||||
| 	case VarDecl: | ||||
| 		print_var_decl(T->right); | ||||
| 		break; | ||||
| 	case FuncDef: | ||||
| 		print_func_def(T->right); | ||||
| 		break; | ||||
| 	} | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentLayer++; | ||||
| 		targetNum[currentLayer] = getBranchNum(T) - 1; | ||||
| 		currentNum[currentLayer] = 1; | ||||
| 		currentLayer--; | ||||
| 		display(T->left); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_const_decl(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("ConstDecl "); | ||||
| 	printVarType(T->d_type); | ||||
| 	printf("\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_const_def(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("ConstDef %s\n", T->symbol); | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		sameGapManage(T, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		gapManage(T, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_const_exp_array(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("ConstExpArray\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_const_init_val(ASTNode* T) | ||||
| { | ||||
| 	if(T->right && T->right->type == ConstExp) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_const_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("ConstInitVal {}\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_const_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == 0) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_mul_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("ConstExp "); | ||||
| 	if(T->d_type == PLUS) | ||||
| 	{ | ||||
| 		printf("+\n"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf("-\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_var_decl(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("VarDecl "); | ||||
| 	printVarType(T->d_type); | ||||
| 	printf("\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_var_def(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("VarDef %s\n", T->symbol); | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		sameGapManage(T, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		gapManage(T, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_init_val(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == Exp) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_exp(T->right); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if(T->right) | ||||
| 		{ | ||||
| 			handle_next_display = 0; | ||||
| 			print_init_vals(T->right); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			gapProcess(); | ||||
| 			printf("Null Init Vals\n"); | ||||
| 			gapManage(T, 1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_init_vals(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("InitVals\n"); | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		sameGapManage(T, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		gapManage(T, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_func_def(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("FuncDef "); | ||||
| 	printVarType(T->d_type); | ||||
| 	printf(" %s\n", T->symbol); | ||||
| 	gapManage(T, 0); | ||||
| } | ||||
| 
 | ||||
| void print_func_f_param(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("FuncFParams "); | ||||
| 	printVarType(T->d_type); | ||||
| 	printf(" %s\n", T->symbol); | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		sameGapManage(T, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		gapManage(T, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_block(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("Block\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_block_item(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	handle_next_display = 0; | ||||
| 	switch(T->right->type) | ||||
| 	{ | ||||
| 	case ConstDecl: | ||||
| 		print_const_decl(T->right); | ||||
| 		break; | ||||
| 	case VarDecl: | ||||
| 		print_var_decl(T->right); | ||||
| 		break; | ||||
| 	case Stmt: | ||||
| 		print_stmt(T->right); | ||||
| 		break; | ||||
| 	} | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentLayer++; | ||||
| 		targetNum[currentLayer] = getBranchNum(T) - 1; | ||||
| 		currentNum[currentLayer] = 1; | ||||
| 		currentLayer--; | ||||
| 		display(T->left); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_stmt(ASTNode* T) | ||||
| { | ||||
| 	switch (T->int_val) | ||||
| 	{ | ||||
| 	case BlankStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Blank Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case ExpStmt: | ||||
| 		handle_next_display = 0; | ||||
| 		print_exp(T->right); | ||||
| 		break; | ||||
| 	case AssignStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Assign Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case Block: | ||||
| 		handle_next_display = 0; | ||||
| 		print_block(T->right); | ||||
| 		break; | ||||
| 	case IfStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("If Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case IfElseStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("If-Else Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case WhileStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("While Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case BreakStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Break Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case ContinueStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Continue Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case BlankReturnStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Blank Return Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	case ReturnStmt: | ||||
| 		gapProcess(); | ||||
| 		printf("Return Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	default: | ||||
| 		gapProcess(); | ||||
| 		printf("Unknown Statement\n"); | ||||
| 		gapManage(T, 0); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_exp(ASTNode* T) | ||||
| { | ||||
| 	handle_next_display = 0; | ||||
| 	print_add_exp(T->right); | ||||
| } | ||||
| 
 | ||||
| void print_add_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == MUL) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_mul_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("AddExp"); | ||||
| 	if(T->int_val == PLUS) | ||||
| 	{ | ||||
| 		printf(" +\n"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf(" -\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_mul_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == UnaryExp) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_unary_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("MulExp"); | ||||
| 	if(T->int_val == MUL) | ||||
| 	{ | ||||
| 		printf(" *\n"); | ||||
| 	} | ||||
| 	else if(T->int_val == DIV) | ||||
| 	{ | ||||
| 		printf(" /\n"); | ||||
| 	} | ||||
| 	else if(T->int_val == MOD) | ||||
| 	{ | ||||
| 		printf(" %%\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_unary_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == PrimaryExp) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_primary_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("UnaryExp "); | ||||
| 	switch (T->int_val) | ||||
| 	{ | ||||
| 	case FuncRParams: | ||||
| 		printf("%s()\n", T->symbol); | ||||
| 		break; | ||||
| 	case Plus: | ||||
| 		printf("+\n"); | ||||
| 		break; | ||||
| 	case Minus: | ||||
| 		printf("-\n"); | ||||
| 		break; | ||||
| 	case NOT: | ||||
| 		printf("NOT\n"); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_func_r_params(ASTNode* T) | ||||
| { | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		currentNum[currentLayer]--; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("FuncRParams\n"); | ||||
| 	if(T->left) | ||||
| 	{ | ||||
| 		sameGapManage(T, 1); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		gapManage(T, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void print_primary_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->d_type == NonType) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		if(T->int_val == Exp) | ||||
| 		{ | ||||
| 			print_exp(T->right); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			print_lv_al(T->right); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("PrimaryExp "); | ||||
| 	if(T->d_type == Int) | ||||
| 	{ | ||||
| 		printf("IntLiteral %d\n", T->int_val); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf("FloatLiteral %f\n", T->float_val); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_lv_al(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	//printVarType(T->d_type);
 | ||||
| 	printf("LVal %s\n", T->symbol); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_cond(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == 0 && T->right->type == Cond) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_cond(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("Cond"); | ||||
| 	if(T->int_val == OR) | ||||
| 	{ | ||||
| 		printf(" OR\n"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_l_and_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == 0) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_eq_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("LAndExp AND\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_eq_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == 0) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_rel_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("EqExp"); | ||||
| 	if(T->int_val == EQ) | ||||
| 	{ | ||||
| 		printf(" ==\n"); | ||||
| 	} | ||||
| 	else if(T->int_val == NE) | ||||
| 	{ | ||||
| 		printf(" !=\n"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_rel_exp(ASTNode* T) | ||||
| { | ||||
| 	if(T->int_val == 0) | ||||
| 	{ | ||||
| 		handle_next_display = 0; | ||||
| 		print_add_exp(T->right); | ||||
| 		return; | ||||
| 	} | ||||
| 	gapProcess(); | ||||
| 	printf("RelExp "); | ||||
| 	if(T->int_val == LT) | ||||
| 	{ | ||||
| 		printf("<\n"); | ||||
| 	} | ||||
| 	else if(T->int_val == GT) | ||||
| 	{ | ||||
| 		printf(">\n"); | ||||
| 	} | ||||
| 	else if(T->int_val == LE) | ||||
| 	{ | ||||
| 		printf("<=\n"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		printf(">=\n"); | ||||
| 	} | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_exp_array(ASTNode* T) | ||||
| { | ||||
| 	gapProcess(); | ||||
| 	printf("ExpArray []\n"); | ||||
| 	gapManage(T, 1); | ||||
| } | ||||
| 
 | ||||
| void print_unknown(ASTNode* T) | ||||
| { | ||||
| 	currentNum[currentLayer]++; | ||||
| 	gapProcess(); | ||||
| 	printf("Unknown\n"); | ||||
| } | ||||
| @ -0,0 +1,2 @@ | ||||
| bison -d parser.y -o parser.c | ||||
| flex -o lexer.c lexer.l  | ||||
| @ -0,0 +1,101 @@ | ||||
| #include "ast.h" | ||||
| extern int targetNum[1024]; | ||||
| extern int currentNum[1024]; | ||||
| extern int currentLayer; | ||||
| extern int handle_next_display; | ||||
| 
 | ||||
| void display(ASTNode* T) | ||||
| { | ||||
| 	handle_next_display = 1; | ||||
| 	switch (T->type) | ||||
| 	{ | ||||
| 	case Root: | ||||
| 		print_root(T); | ||||
| 		break; | ||||
| 	case CompUnit: | ||||
| 		print_comp_unit(T); | ||||
| 		break; | ||||
| 	case ConstDecl: | ||||
| 		print_const_decl(T); | ||||
| 		break; | ||||
| 	case ConstDef: | ||||
| 		print_const_def(T); | ||||
| 		break; | ||||
| 	case ConstExpArray: | ||||
| 		print_const_exp_array(T); | ||||
| 		break; | ||||
| 	case ConstInitVal: | ||||
| 		print_const_init_val(T); | ||||
| 		break; | ||||
| 	case ConstExp: | ||||
| 		print_const_exp(T); | ||||
| 		break; | ||||
| 	case VarDecl: | ||||
| 		print_var_decl(T); | ||||
| 		break; | ||||
| 	case VarDef: | ||||
| 		print_var_def(T); | ||||
| 		break; | ||||
| 	case InitVal: | ||||
| 		print_init_val(T); | ||||
| 		break; | ||||
| 	case InitVals: | ||||
| 		print_init_vals(T); | ||||
| 		break; | ||||
| 	case FuncDef: | ||||
| 		print_func_def(T); | ||||
| 		break; | ||||
| 	case FuncFParam: | ||||
| 		print_func_f_param(T); | ||||
| 		break; | ||||
| 	case Block: | ||||
| 		print_block(T); | ||||
| 		break; | ||||
| 	case BlockItem: | ||||
| 		print_block_item(T); | ||||
| 		break; | ||||
| 	case Stmt: | ||||
| 		print_stmt(T); | ||||
| 		break; | ||||
|    case Exp: | ||||
|         print_exp(T); | ||||
|         break; | ||||
|     case AddExp: | ||||
|         print_add_exp(T); | ||||
|         break; | ||||
|     case MulExp: | ||||
|         print_mul_exp(T); | ||||
|         break; | ||||
|     case UnaryExp: | ||||
|         print_unary_exp(T); | ||||
|         break; | ||||
|     case FuncRParams: | ||||
|         print_func_r_params(T); | ||||
|         break; | ||||
|     case PrimaryExp: | ||||
|         print_primary_exp(T); | ||||
|         break; | ||||
|     case LVal: | ||||
|         print_lv_al(T); | ||||
|         break; | ||||
| 	case Cond: | ||||
| 		print_cond(T); | ||||
| 		break; | ||||
| 	case LAndExp: | ||||
| 		print_l_and_exp(T); | ||||
| 		break; | ||||
| 	case EqExp: | ||||
| 		print_eq_exp(T); | ||||
| 		break; | ||||
|     case RelExp: | ||||
|         print_rel_exp(T); | ||||
|         break; | ||||
|     case ExpArray: | ||||
|         print_exp_array(T); | ||||
|         break; | ||||
| 	default: | ||||
| 		handle_next_display = 0; | ||||
| 		print_unknown(T); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -0,0 +1,94 @@ | ||||
| %option noyywrap | ||||
| %option yylineno | ||||
| 
 | ||||
| %{ | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| #include <ctype.h> | ||||
| 
 | ||||
| #include "ast.h" | ||||
| #include "parser.h" | ||||
| 
 | ||||
| int line_cnt = 1; | ||||
| %} | ||||
| 
 | ||||
| MultilineComment	    "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/" | ||||
| SingleLineComment	    "//"[^\n]+ | ||||
| Lex_err [1-9][0-9]*[a-zA-Z]+[0-9]*|0[0-7]*[8-9a-zA-Z_]+[0-9a-zA-Z_]*  | ||||
| 
 | ||||
| %% | ||||
| "//".* { } | ||||
| "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/" { | ||||
|     int len = strlen(yytext); | ||||
|     for (int i = 0; i < len; i++) | ||||
|         if(yytext[i] == '\n') | ||||
|             line_cnt++; | ||||
| } | ||||
| "\n" { line_cnt++; } | ||||
| [ \t] { } | ||||
| "int" { return INT; } | ||||
| "float" { return FLOAT; } | ||||
| "void" { return VOID; } | ||||
| "const" { return CONST; } | ||||
| "return" { return RETURN; } | ||||
| "if" { return IF; } | ||||
| "else" { return ELSE; } | ||||
| "while" { return WHILE; } | ||||
| "break" { return BREAK; } | ||||
| "continue" { return CONTINUE; } | ||||
| "(" { return LP; } | ||||
| ")" { return RP; } | ||||
| "[" { return LB; } | ||||
| "]" { return RB; } | ||||
| "{" { return LC; } | ||||
| "}" { return RC; } | ||||
| "," { return COMMA; } | ||||
| ";" { return SEMICOLON; } | ||||
| "+" { return PLUS; } | ||||
| "-" { return MINUS; } | ||||
| "!" { return NOT; } | ||||
| "=" { return ASSIGN; } | ||||
| "*" { return MUL; } | ||||
| "/" { return DIV; } | ||||
| "%" { return MOD; } | ||||
| "&&" { return AND; } | ||||
| "||" { return OR; } | ||||
| "==" { return EQ; } | ||||
| "!=" { return NE; } | ||||
| "<" { return LT; } | ||||
| "<=" { return LE; } | ||||
| ">" { return GT; } | ||||
| ">=" { return GE; } | ||||
| 0[xX][0-9a-fA-F]* { | ||||
|     int val = 0; | ||||
|     int len = strlen(yytext); | ||||
|     for (int i = 2; i < len; i++) { | ||||
|         val <<= 4; | ||||
|         if (isdigit(yytext[i])) | ||||
|             val += yytext[i] - '0'; | ||||
|         else | ||||
|             val += yytext[i] - 'a' + 10; | ||||
|     } | ||||
|     yylval.int_val = val; | ||||
|     return INT_LIT; | ||||
| } | ||||
| 
 | ||||
| [a-zA-Z_][a-zA-Z0-9_]* { | ||||
|     yylval.str_val = (char *)malloc(strlen(yytext) + 1); | ||||
|     strcpy(yylval.str_val, yytext); | ||||
|     yylval.str_val[strlen(yytext)] = '\0'; | ||||
|     return ID; | ||||
| } | ||||
| [0-9]*\.[0-9]+f?|[0-9]+e-?[0-9]+f? { yylval.float_val = atof(yytext); return FLOAT_LIT; } | ||||
| {Lex_err} { return LEX_ERR; } | ||||
| [1-9][0-9]*|0 { yylval.int_val = atoi(yytext); return INT_LIT; } | ||||
| 0[0-7]+ { | ||||
|     int val = 0; | ||||
|     int len = strlen(yytext); | ||||
|     for (int i = 1; i < len; i++) | ||||
|         val = (val << 3) + yytext[i] - '0'; | ||||
|     yylval.int_val = val; | ||||
|     return INT_LIT; | ||||
| } | ||||
| . { } | ||||
| %% | ||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -0,0 +1,139 @@ | ||||
| /* A Bison parser, made by GNU Bison 3.8.2.  */ | ||||
| 
 | ||||
| /* Bison interface for Yacc-like parsers in C
 | ||||
| 
 | ||||
|    Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, | ||||
|    Inc. | ||||
| 
 | ||||
|    This program is free software: you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation, either version 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|    GNU General Public License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| /* As a special exception, you may create a larger work that contains
 | ||||
|    part or all of the Bison parser skeleton and distribute that work | ||||
|    under terms of your choice, so long as that work isn't itself a | ||||
|    parser generator using the skeleton or a modified version thereof | ||||
|    as a parser skeleton.  Alternatively, if you modify or redistribute | ||||
|    the parser skeleton itself, you may (at your option) remove this | ||||
|    special exception, which will cause the skeleton and the resulting | ||||
|    Bison output files to be licensed under the GNU General Public | ||||
|    License without this special exception. | ||||
| 
 | ||||
|    This special exception was added by the Free Software Foundation in | ||||
|    version 2.2 of Bison.  */ | ||||
| 
 | ||||
| /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
 | ||||
|    especially those whose name start with YY_ or yy_.  They are | ||||
|    private implementation details that can be changed or removed.  */ | ||||
| 
 | ||||
| #ifndef YY_YY_PARSER_H_INCLUDED | ||||
| # define YY_YY_PARSER_H_INCLUDED | ||||
| /* Debug traces.  */ | ||||
| #ifndef YYDEBUG | ||||
| # define YYDEBUG 0 | ||||
| #endif | ||||
| #if YYDEBUG | ||||
| extern int yydebug; | ||||
| #endif | ||||
| 
 | ||||
| /* Token kinds.  */ | ||||
| #ifndef YYTOKENTYPE | ||||
| # define YYTOKENTYPE | ||||
|   enum yytokentype | ||||
|   { | ||||
|     YYEMPTY = -2, | ||||
|     YYEOF = 0,                     /* "end of file"  */ | ||||
|     YYerror = 256,                 /* error  */ | ||||
|     YYUNDEF = 257,                 /* "invalid token"  */ | ||||
|     ID = 258,                      /* ID  */ | ||||
|     INT_LIT = 259,                 /* INT_LIT  */ | ||||
|     FLOAT_LIT = 260,               /* FLOAT_LIT  */ | ||||
|     INT = 261,                     /* INT  */ | ||||
|     FLOAT = 262,                   /* FLOAT  */ | ||||
|     VOID = 263,                    /* VOID  */ | ||||
|     CONST = 264,                   /* CONST  */ | ||||
|     RETURN = 265,                  /* RETURN  */ | ||||
|     IF = 266,                      /* IF  */ | ||||
|     ELSE = 267,                    /* ELSE  */ | ||||
|     WHILE = 268,                   /* WHILE  */ | ||||
|     BREAK = 269,                   /* BREAK  */ | ||||
|     CONTINUE = 270,                /* CONTINUE  */ | ||||
|     LP = 271,                      /* LP  */ | ||||
|     RP = 272,                      /* RP  */ | ||||
|     LB = 273,                      /* LB  */ | ||||
|     RB = 274,                      /* RB  */ | ||||
|     LC = 275,                      /* LC  */ | ||||
|     RC = 276,                      /* RC  */ | ||||
|     COMMA = 277,                   /* COMMA  */ | ||||
|     SEMICOLON = 278,               /* SEMICOLON  */ | ||||
|     MINUS = 279,                   /* MINUS  */ | ||||
|     NOT = 280,                     /* NOT  */ | ||||
|     ASSIGN = 281,                  /* ASSIGN  */ | ||||
|     PLUS = 282,                    /* PLUS  */ | ||||
|     MUL = 283,                     /* MUL  */ | ||||
|     DIV = 284,                     /* DIV  */ | ||||
|     MOD = 285,                     /* MOD  */ | ||||
|     AND = 286,                     /* AND  */ | ||||
|     OR = 287,                      /* OR  */ | ||||
|     EQ = 288,                      /* EQ  */ | ||||
|     NE = 289,                      /* NE  */ | ||||
|     LT = 290,                      /* LT  */ | ||||
|     LE = 291,                      /* LE  */ | ||||
|     GT = 292,                      /* GT  */ | ||||
|     GE = 293,                      /* GE  */ | ||||
|     LEX_ERR = 294,                 /* LEX_ERR  */ | ||||
|     THEN = 295                     /* THEN  */ | ||||
|   }; | ||||
|   typedef enum yytokentype yytoken_kind_t; | ||||
| #endif | ||||
| 
 | ||||
| /* Value type.  */ | ||||
| #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | ||||
| union YYSTYPE | ||||
| { | ||||
| #line 25 "parser.y" | ||||
| 
 | ||||
|     int int_val; | ||||
|     float float_val; | ||||
|     char *str_val; | ||||
|     struct ASTNode *node_val; | ||||
| 
 | ||||
| #line 111 "parser.h" | ||||
| 
 | ||||
| }; | ||||
| typedef union YYSTYPE YYSTYPE; | ||||
| # define YYSTYPE_IS_TRIVIAL 1 | ||||
| # define YYSTYPE_IS_DECLARED 1 | ||||
| #endif | ||||
| 
 | ||||
| /* Location type.  */ | ||||
| #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED | ||||
| typedef struct YYLTYPE YYLTYPE; | ||||
| struct YYLTYPE | ||||
| { | ||||
|   int first_line; | ||||
|   int first_column; | ||||
|   int last_line; | ||||
|   int last_column; | ||||
| }; | ||||
| # define YYLTYPE_IS_DECLARED 1 | ||||
| # define YYLTYPE_IS_TRIVIAL 1 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| extern YYSTYPE yylval; | ||||
| extern YYLTYPE yylloc; | ||||
| 
 | ||||
| int yyparse (void); | ||||
| 
 | ||||
| 
 | ||||
| #endif /* !YY_YY_PARSER_H_INCLUDED  */ | ||||
											
												Binary file not shown.
											
										
									
								| @ -0,0 +1,201 @@ | ||||
| %define parse.error verbose | ||||
| %locations | ||||
| %{ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
| #include "ast.h" | ||||
| 
 | ||||
| ASTNode *root; | ||||
| 
 | ||||
| extern FILE *yyin; | ||||
| extern int line_cnt; | ||||
| extern int yylineno; | ||||
| extern char *yytext; | ||||
| extern int yylex(); | ||||
| extern int yyparse(); | ||||
| //extern void yyerror(char *msg); | ||||
| void yyerror(const char* fmt, ...); | ||||
| int syntax_error = 0; | ||||
| char filename[100]; | ||||
| %} | ||||
| 
 | ||||
| %union { | ||||
|     int int_val; | ||||
|     float float_val; | ||||
|     char *str_val; | ||||
|     struct ASTNode *node_val; | ||||
| } | ||||
| 
 | ||||
| %type <node_val> CompUnit ConstDecl VarDecl FuncDef ConstDef ConstInitVal VarDef InitVal FuncFParam ConstExpArray Block | ||||
| %type <node_val> Root BlockItem Stmt LVal PrimaryExp UnaryExp FuncRParams MulExp Exp RelExp EqExp LAndExp LNotExp Cond ConstExp | ||||
| %type <node_val> ExpArray AddExp LOrExp InitVals  | ||||
| //ForList | ||||
| 
 | ||||
| %token <str_val> ID | ||||
| %token <int_val> INT_LIT | ||||
| %token <float_val> FLOAT_LIT | ||||
| 
 | ||||
| %token <int_val> INT FLOAT VOID CONST RETURN IF ELSE WHILE BREAK CONTINUE LP RP LB RB LC RC COMMA SEMICOLON | ||||
| %token <int_val> MINUS NOT ASSIGN PLUS MUL DIV MOD AND OR EQ NE LT LE GT GE LEX_ERR  | ||||
| //FOR INC DEC THEN | ||||
| 
 | ||||
| %nonassoc THEN | ||||
| %nonassoc ELSE | ||||
| 
 | ||||
| %start Root | ||||
| 
 | ||||
| %% | ||||
| Root: CompUnit { root = new_node(Root, NULL, NULL, $1, 0, 0,  NULL, NonType); }; | ||||
| CompUnit: ConstDecl { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | VarDecl { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | FuncDef { $$ = new_node(CompUnit, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | ConstDecl CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | VarDecl CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | FuncDef CompUnit { $$ = new_node(CompUnit, $2, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| 
 | ||||
| ConstDecl: CONST INT ConstDef SEMICOLON { $$ = new_node(ConstDecl, NULL, NULL, $3, 0, 0, NULL, Int); } | ||||
|          | CONST FLOAT ConstDef SEMICOLON { $$ = new_node(ConstDecl, NULL, NULL, $3, 0, 0, NULL, Float); }; | ||||
| ConstDef: ID ConstExpArray ASSIGN ConstInitVal { $$ = new_node(ConstDef, NULL, $2, $4, 0, 0, $1, NonType); } | ||||
|         | ID ConstExpArray ASSIGN ConstInitVal COMMA ConstDef { $$ = new_node(ConstDef, $6, $2, $4, 0, 0, $1, NonType); }; | ||||
| ConstExpArray: { $$ = NULL; } | ||||
|              | LB ConstExp RB ConstExpArray { $$ = new_node(ConstExpArray, $4, NULL, $2, 0, 0, NULL, NonType); }; | ||||
| ConstInitVal: ConstExp { $$ = new_node(ConstInitVal, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|             | LC RC { $$ = new_node(ConstInitVal, NULL, NULL, NULL, 0, 0, NULL, NonType); } | ||||
|             | LC ConstInitVal RC { $$ = new_node(ConstInitVal, NULL, NULL, $2, 0, 0, NULL, NonType); } | ||||
|             | LC ConstInitVal COMMA ConstInitVal RC { $$ = new_node(ConstInitVal, $4, NULL, $2, 0, 0, NULL, NonType); }; | ||||
| ConstExp: MulExp { $$ = new_node(ConstExp, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | MulExp PLUS Exp { $$ = new_node(ConstExp, $3, NULL, $1, PLUS, 0, NULL, NonType); } | ||||
|         | MulExp MINUS Exp { $$ = new_node(ConstExp, $3, NULL, $1, MINUS, 0, NULL, NonType); }; | ||||
| 
 | ||||
| VarDecl: INT VarDef SEMICOLON { $$ = new_node(VarDecl, NULL, NULL, $2, 0, 0, NULL, Int); } | ||||
|        | FLOAT VarDef SEMICOLON { $$ = new_node(VarDecl, NULL, NULL, $2, 0, 0, NULL, Float); }; | ||||
| VarDef: ID ConstExpArray { $$ = new_node(VarDef, NULL, $2, NULL, 0, 0, $1, NonType); } | ||||
|       | ID ConstExpArray ASSIGN InitVal { $$ = new_node(VarDef, NULL, $2, $4, 0, 0, $1, NonType); } | ||||
|       | ID ConstExpArray COMMA VarDef { $$ = new_node(VarDef, $4, $2, NULL, 0, 0, $1, NonType); } | ||||
|       | ID ConstExpArray ASSIGN InitVal COMMA VarDef { $$ = new_node(VarDef, $6, $2, $4, 0, 0, $1, NonType); }; | ||||
| InitVal: Exp { $$ = new_node(InitVal, NULL, NULL, $1, Exp, 0, NULL, NonType); } | ||||
|        | LC RC { $$ = new_node(InitVal, NULL, NULL, NULL, InitVals, 0, NULL, NonType); } | ||||
|        | LC InitVals RC { $$ = new_node(InitVal, NULL, NULL, $2, InitVals, 0, NULL, NonType); }; | ||||
| InitVals: InitVal { $$ = new_node(InitVals, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|         | InitVal COMMA InitVals { $$ = new_node(InitVals, $3, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| 
 | ||||
| FuncDef: INT ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Int); } | ||||
|        | FLOAT ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Float); } | ||||
|        | VOID ID LP RP Block { $$ = new_node(FuncDef, NULL, NULL, $5, 0, 0, $2, Void); } | ||||
|        | INT ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Int); } | ||||
|        | FLOAT ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Float); } | ||||
|        | VOID ID LP FuncFParam RP Block { $$ = new_node(FuncDef, NULL, $4, $6, 0, 0, $2, Void); };; | ||||
| FuncFParam: INT ID { $$ = new_node(FuncFParam, NULL, NULL, NULL, 0, 0, $2, Int); } | ||||
|           | FLOAT ID { $$ = new_node(FuncFParam, NULL, NULL, NULL, 0, 0, $2, Float); } | ||||
|           | INT ID LB RB ExpArray { $$ = new_node(FuncFParam, NULL, NULL, $5, 0, 0, $2, Int); } | ||||
|           | FLOAT ID LB RB ExpArray { $$ = new_node(FuncFParam, NULL, NULL, $5, 0, 0, $2, Float); } | ||||
|           | INT ID COMMA FuncFParam { $$ = new_node(FuncFParam, $4, NULL, NULL, 0, 0, $2, Int); } | ||||
|           | FLOAT ID COMMA FuncFParam { $$ = new_node(FuncFParam, $4, NULL, NULL, 0, 0, $2, Float); } | ||||
|           | INT ID LB RB ExpArray COMMA FuncFParam { $$ = new_node(FuncFParam, $7, NULL, $5, 0, 0, $2, Int); } | ||||
|           | FLOAT ID LB RB ExpArray COMMA FuncFParam { $$ = new_node(FuncFParam, $7, NULL, $5, 0, 0, $2, Float); }; | ||||
| 
 | ||||
| Block: LC BlockItem RC { $$ = new_node(Block, NULL, NULL, $2, 0, 0, NULL, NonType); }; | ||||
| BlockItem: { $$ = NULL; } | ||||
|          | ConstDecl BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); } | ||||
|          | VarDecl BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); } | ||||
|          | Stmt BlockItem { $$ = new_node(BlockItem, $2, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| 
 | ||||
| // 以下是你需要完成的语法规则和语义计算规则 | ||||
| //Stmt → LVal '=' Exp ';' | [Exp] ';' | Block | ||||
| //| 'if' '(' Cond ')' Stmt [ 'else' Stmt ] | ||||
| //| 'while' '(' Cond ')' Stmt | ||||
| //| 'break' ';' | 'continue' ';' | ||||
| //| 'return' [Exp] ';' | ||||
| Stmt:  LVal ASSIGN Exp SEMICOLON{$$ = new_node(Stmt,$1,NULL,$3,0,0,NULL,NonType);} | ||||
| | Exp SEMICOLON {$$ = new_node(Stmt,NULL,NULL,$1,0,0,NULL,NonType);} | ||||
| | SEMICOLON {$$ = NULL;} | ||||
| | Block{$$ = new_node(Stmt,NULL,NULL,$1,0,0,NULL,NonType);} | ||||
| | IF LP Cond RP Stmt {$$ = new_node(Stmt,$3,NULL,$5,0,0,NULL,NonType);} | ||||
| | IF LP Cond RP Stmt ELSE Stmt {$$ = new_node(Stmt,$3,$7,$5,0,0,NULL,NonType);} | ||||
| | WHILE LP Cond RP Stmt {$$ = new_node(Stmt,$3,NULL,$5,0,0,NULL,NonType);} | ||||
| | BREAK SEMICOLON {$$ = NULL;} | ||||
| | CONTINUE SEMICOLON {$$ = NULL;} | ||||
| | RETURN SEMICOLON {$$ = NULL;} | ||||
| | RETURN Exp SEMICOLON {$$ = new_node(Stmt,NULL,NULL,$2,0,0,NULL,NonType);} | ||||
| ; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Exp: AddExp { $$ = new_node(Exp, NULL, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| AddExp: MulExp { $$ = new_node(AddExp, NULL, NULL, $1, MUL, 0, NULL, NonType); } | ||||
|       | MulExp PLUS AddExp { $$ = new_node(AddExp, $3, NULL, $1, PLUS, 0, NULL, NonType); } | ||||
|       | MulExp MINUS AddExp { $$ = new_node(AddExp, $3, NULL, $1, MINUS, 0, NULL, NonType); }; | ||||
| MulExp: UnaryExp { $$ = new_node(MulExp, NULL, NULL, $1, UnaryExp, 0, NULL, NonType); } | ||||
|       | UnaryExp MUL MulExp { $$ = new_node(MulExp, $3, NULL, $1, MUL, 0, NULL, NonType); } | ||||
|       | UnaryExp DIV MulExp { $$ = new_node(MulExp, $3, NULL, $1, DIV, 0, NULL, NonType); } | ||||
|       | UnaryExp MOD MulExp { $$ = new_node(MulExp, $3, NULL, $1, MOD, 0, NULL, NonType); }; | ||||
| UnaryExp: PrimaryExp { $$ = new_node(UnaryExp, NULL, NULL, $1, PrimaryExp, 0, NULL, NonType); } | ||||
|         | ID LP RP { $$ = new_node(UnaryExp, NULL, NULL, NULL, FuncRParams, 0, $1, NonType); } | ||||
|         | ID LP FuncRParams RP { $$ = new_node(UnaryExp, NULL, NULL, $3, FuncRParams, 0, $1, NonType); } | ||||
|         | PLUS UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, Plus, 0, NULL, NonType); } | ||||
|         | MINUS UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, Minus, 0, NULL, NonType); } | ||||
|         | NOT UnaryExp { $$ = new_node(UnaryExp, NULL, NULL, $2, NOT, 0, NULL, NonType); }; | ||||
| FuncRParams: Exp { $$ = new_node(FuncRParams, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|            | Exp COMMA FuncRParams { $$ = new_node(FuncRParams, $3, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| PrimaryExp: LP Exp RP { $$ = new_node(PrimaryExp, NULL, NULL, $2, Exp, 0, NULL, NonType); } | ||||
|           | LVal { $$ = new_node(PrimaryExp, NULL, NULL, $1, LVal, 0, NULL, NonType); } | ||||
|           | INT_LIT { $$ = new_node(PrimaryExp, NULL, NULL, NULL, $1, 0, NULL, Int); } | ||||
|           | FLOAT_LIT { $$ = new_node(PrimaryExp, NULL, NULL, NULL, 0, $1, NULL, Float); }; | ||||
| LVal: ID ExpArray { $$ = new_node(LVal, NULL, NULL, $2, 0, 0, $1, NonType); }; | ||||
| 
 | ||||
| Cond: LOrExp { $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| LOrExp: LAndExp { $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|       | LAndExp OR LOrExp { $$ = new_node(Cond, $3, NULL, $1, OR, 0, 0, NonType); } | ||||
|       | LNotExp{ $$ = new_node(Cond, NULL, NULL, $1, 0, 0, NULL, NonType); }; | ||||
| 
 | ||||
| LAndExp: EqExp { $$ = new_node(LAndExp, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|        | EqExp AND LAndExp { $$ = new_node(LAndExp, $3, NULL, $1, AND, 0, NULL, NonType); }; | ||||
| 
 | ||||
| LNotExp: NOT LP EqExp RP { $$ = new_node(LNotExp, NULL, NULL, $3, 0, 0, NULL, NonType);}; | ||||
| 
 | ||||
| EqExp: RelExp { $$ = new_node(EqExp, NULL, NULL, $1, 0, 0, NULL, NonType);} | ||||
|      | RelExp EQ EqExp { $$ = new_node(EqExp, $3, NULL, $1, EQ, 0, NULL, NonType); } | ||||
|      | RelExp NE EqExp { $$ = new_node(EqExp, $3, NULL, $1, NE, 0, NULL, NonType); }; | ||||
| 
 | ||||
| RelExp: AddExp { $$ = new_node(RelExp, NULL, NULL, $1, 0, 0, NULL, NonType); } | ||||
|       | AddExp LT RelExp { $$ = new_node(RelExp, $3, NULL, $1, LT, 0, NULL, NonType); } | ||||
|       | AddExp GT RelExp { $$ = new_node(RelExp, $3, NULL, $1, GT, 0, NULL, NonType);} | ||||
|       | AddExp LE RelExp { $$ = new_node(RelExp, $3, NULL, $1, LE, 0, NULL, NonType); } | ||||
|       | AddExp GE RelExp { $$ = new_node(RelExp, $3, NULL, $1, GE, 0, NULL, NonType); }; | ||||
| 
 | ||||
| ExpArray: { $$ = NULL; } | ||||
|         | LB Exp RB ExpArray { $$ = new_node(ExpArray, $4, NULL, $2, 0, 0, NULL, NonType); }; | ||||
| %% | ||||
| 
 | ||||
| int main(int argc, char *argv[]) { | ||||
|     int index = strlen(argv[1]) - 1; | ||||
|     while(index > 0 && argv[1][index - 1] != '/') | ||||
|         index--; | ||||
|     strcpy(filename, argv[1] + index); | ||||
|     freopen(argv[1], "r", stdin); | ||||
|     yyparse(); | ||||
|     if (syntax_error == 0)  | ||||
|         display(root); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| void yyerror(char *msg) { | ||||
|     printf("%s:%d\n", name, yylineno); | ||||
|     printf("error text: %s\n", yytext); | ||||
|     exit(-1); | ||||
| } | ||||
| */ | ||||
| #include<stdarg.h> | ||||
| void yyerror(const char* fmt, ...) | ||||
| { | ||||
|     syntax_error = 1;     | ||||
|     va_list ap; | ||||
|     va_start(ap, fmt); | ||||
|     fprintf(stderr, "%s:%d ", filename, yylineno); | ||||
|     vfprintf(stderr, fmt, ap); | ||||
|     fprintf(stderr, ".\n"); | ||||
| }	 | ||||
					Loading…
					
					
				
		Reference in new issue