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