Welcome, guest! Login / Register - Why register?
Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)

Paste

Pasted as C by 123 ( 6 years ago )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define Maxlen 10000

typedef enum{ UNKNOW, OP, MULTIV, DOUBLE, ASSIGN, NUM, ID, LPAREN, RPAREN, END } tokenType;

typedef struct node{
	struct node *left, *right;
	tokenType type;
	char* data;
	int val; //NUM的值 
	int R; //暫存的register 
	int memory; //ID存的位置 
} Node;
typedef struct id{
	char* name;
	int value;
}Id;

char strNow[Maxlen];
tokenType preType = UNKNOW;
Id* ID_table[100];
int tableSize = 3;
int M = 2;
int Double = 0; //判斷有沒有出現過 ++ or -- 
int assign_right = 0; //判斷有沒有出現過 =  
//int id2 = 0; //判斷等號前有沒有2個ID  
int r[1000] = {0};

void getToken();
Node* expr();
Node* term();
Node* factor();
Node* makeNode();
void error();
void Print(Node* root);
void Free(Node* root);
void evaluate(Node* root);

//statement  :=  ENDFILE | END | expr END
//expr       :=  term expr_tail
//expr_tail  :=  ADDSUB_LOGICAL term expr_tail | NiL
//term       :=  factor term_tail
//term_tail  :=  MULDIV factor term_tail | NiL
//factor     :=  INT | ADDSUB INT | ID  | ADDSUB ID  |  INCDEC ID | ID ASSIGN expr | LPAREN expr RPAREN | ADDSUB LPAREN expr RPAREN
//
//Integers
//Operators (+, -, *, /, =, &, |, ^, ++, --)
//Three built-in variables x, y, z (exist in the beginning)
//Some new local variables
//
//The initial value of x, y, and z are stored in memory [0], [4], and [8] respectively. 
//If the expression is legal, remember to print "EXIT 0" on the last line.
//If the expression is illegal, your final output should be "EXIT 1".
//
//x = 100+10*y
//y = z+100*10/50*10
//z = 10*x/100
//xx = x
//yy = y
//zz = z
//x = xx ^x
//y=yy|y
//z = zz&z

int main(void){
	int i;
	for(i=0;i<3;i++){
		Id* newID = (Id*)malloc(sizeof(Id)); 
		ID_table[i] = newID;
		char* s = (char*)malloc(sizeof(char)*50);
		newID->name = s;
	}
	ID_table[0]->name[0] = 'x';
	ID_table[0]->name[1] = '\0';
	ID_table[1]->name[0] = 'y';
	ID_table[1]->name[1] = '\0';
	ID_table[2]->name[0] = 'z';
	ID_table[2]->name[1] = '\0';
	
	while(1){
		assign_right = Double = 0;
		preType = UNKNOW;
		Node* root = expr();
		if(assign_right)evaluate(root);
//		Print(root);
//		printf("\n");
		Free(root);
	}
	
	return 0;
}

void getToken(){
	char c;
	tokenType tmpType = preType;
//	if(tmpType==NUM) printf("YES\n");
	if((c = getchar())==EOF){
		printf("MOV r0 [0]\n");
		printf("MOV r1 [4]\n");
		printf("MOV r2 [8]\n");
		printf("EXIT 0\n");
		exit(0);
	}
	//c = getchar();
	strNow[0] = c;
	strNow[1] = '\0';
//	printf("get %s\n", strNow);
	if(c==' ' || c=='\t'){
		getToken();
	}
	else if(c=='\n'){ //newline
		preType = END;
	}
	else if(c=='('){
		if(preType!=OP && preType!=ASSIGN && preType!=MULTIV && preType!=LPAREN) error();
		preType = LPAREN;
	}
	else if(c==')'){
		if(preType!=NUM && preType!=ID && preType!=RPAREN) error();
		preType = RPAREN;
	}
	else if(c=='+'){
		c = getchar();
		if(c=='+'){ //++
			if(preType==ID || preType==NUM || Double) error();
			strNow[1] = c;
			strNow[2] = '\0';
			preType = DOUBLE;
		}
		else{
			ungetc(c, stdin);
			preType = OP;
		}
	}
	else if(c=='-'){
		c = getchar();
		if(c=='-'){ //--
			if(preType==ID || preType==NUM || Double) error();
			strNow[1] = c;
			strNow[2] = '\0';
			preType = DOUBLE;
		}
		else{
			ungetc(c, stdin);
			preType = OP;
		} 
	}
	else if(c=='*'){
		preType = MULTIV;
	}
	else if(c=='/'){
		preType = MULTIV;
	}
	else if(c=='='){
		if(preType!=ID || assign_right || Double) error();
		assign_right = 1; //在assign右邊 
		preType = ASSIGN;
	}
	else if(c=='&'){
		preType = OP;
	}
	else if(c=='|'){
		preType = OP;
	}
	else if(c=='^'){
		preType = OP;
	}
	else if(isdigit(c)){
		if(preType==ID || preType==NUM || preType==RPAREN) error();
		int i = 1;
		while(isdigit(c = getchar())){
		strNow[i] = c;
		i++;
		}
		ungetc(c, stdin);
		strNow[i] = '\0';
		preType = NUM;
	}
	else if(isalpha(c)){
		if(preType==ID || preType==NUM || preType==RPAREN) error();
//		if(assign_right==0 && id2==1) error();
//		if(id2==0) id2=1;
		int i = 1;
		c = getchar();
		
		while(isalpha(c)){
			strNow[i] = c;
			c = getchar();
			i++;
		}
		ungetc(c, stdin);
		strNow[i] = '\0';
		preType = ID;
	}
	
	if(preType==OP || preType==MULTIV){
		if(tmpType!=NUM && tmpType!=ID && tmpType!=RPAREN){
			error();
		}
	}
}
Node* expr(){
//	printf("expr\n");
	Node* leftNode = term();	
	Node* rtNode = leftNode;
	while(preType==OP){
		rtNode = makeNode(); //return_Node
		rtNode->left = leftNode;
		rtNode->right = term();
		if(rtNode->right == NULL) error();
		leftNode = rtNode;
	}
	return rtNode;
}
Node* term(){
//	printf("TERM\n");
	Node* leftNode = factor();
	Node* rtNode = leftNode;
	while(preType==MULTIV){
		rtNode = makeNode(); //return_Node
		rtNode->left = leftNode;
		rtNode->right = factor();
		if(rtNode->right == NULL) error();
		leftNode = rtNode;
	}
	return rtNode;
}
Node* factor(){
	Node* rtNode = NULL;
//	printf("Factor\n");
	getToken();
	
	if(preType==ID){
		Node* leftNode = makeNode();
		rtNode = leftNode;
		getToken();
		if(preType==ASSIGN){
			rtNode = makeNode();
			rtNode->left = leftNode;
			rtNode->right = expr();
		}
	}
	else if(preType==NUM){
		rtNode = makeNode();
		getToken();
	}
	else if(preType==LPAREN){
		rtNode = expr(); 
		if(preType==RPAREN) {
		getToken();	
		}
		else error();
	}
	else if(preType==END){
	}
	else if(preType==DOUBLE){
		getToken();
		if(preType==ID){
			ID_table[checkTable()]->value++;
			preType = NUM;
			sprintf(strNow, "%d", ID_table[checkTable()]->value);
			rtNode = makeNode();
			getToken();
		}
		else error();
	}
	else error();
	return rtNode;
}
Node* makeNode(){
	Node* newNode = (Node*)malloc(sizeof(Node));
	char* str = (char*)malloc(sizeof(char)*127);
	newNode->data = str;
	newNode->left = newNode->right = NULL;
	strcpy(newNode->data, strNow);
	newNode->type = preType;
	if(newNode->type==NUM){
		newNode->val = atoi(newNode->data);
	}
	else if(preType==ID){
		int tmp = checkTable();
		newNode->val = ID_table[tmp]->value;
		newNode->memory = 4*tmp;
	}
	return newNode;
}
int checkTable(){
	int i = 0;
	for(i=0; i<tableSize; i++){
		if(strcmp(strNow, ID_table[i]->name)==0)
			return i;
	}
	if(assign_right){ //undefined ID 
		printf("EXIT 1\n");
		exit(1);
	}
	else{
		Id* newID = (Id*)malloc(sizeof(Id)); 
		ID_table[tableSize] = newID;
		char* s = (char*)malloc(sizeof(char)*50);
		newID->name = s;
		strcpy(newID->name, strNow);
		newID->value = 0;
		M++;
		tableSize++;
		return tableSize-1;
	}
}
void error(){
	printf("EXIT 1\n");
	exit(0);
}
void evaluate(Node* root){
//	printf("eva\n");
	if(root==NULL) return;
	tokenType T = root->type;
	if(T==ID){
		int i = 0;
		int tmp = root->memory;
		while(r[i]!=0) i++;
		r[i] = 1;
		printf("MOV r%d [%d]\n", i, tmp);
		root->R = i;
		return;
	}
	if(T==NUM){
		int i = 0;
		int tmp = root->val;
		while(r[i]!=0) i++;
		r[i] = 1;
		printf("MOV r%d %d\n", i, tmp);
		root->R = i;
		return;
	}
	else if(T==ASSIGN){
		evaluate(root->right);
		int tmp = root->left->memory;
		printf("MOV [%d] r%d\n", tmp, root->right->R);
		r[root->right->R] = 0;
		strcpy(strNow, root->left->data);
		int idx = checkTable();
		ID_table[idx]->value = root->right->val;
	}
	else if(T==OP || T==MULTIV){
		char c = root->data[0];
		evaluate(root->left);
		evaluate(root->right);
		if(c=='+'){
			root->val = root->left->val + root->right->val;
			int tmp = root->left->R;
			printf("ADD r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
		else if(c=='-'){
			root->val = root->left->val - root->right->val;
			int tmp = root->left->R;
			printf("SUB r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
		else if(c=='*'){
			root->val = root->left->val * root->right->val;
			int tmp = root->left->R;
			printf("MUL r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
		else if(c=='/'){
			if(root->right->val==0) error(); 
			root->val = root->left->val / root->right->val;
			int tmp = root->left->R;
			printf("DIV r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp; 
		}
		else if(c=='&'){
			root->val = root->left->val & root->right->val;
			int tmp = root->left->R;
			printf("AND r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
		else if(c=='|'){
			root->val = root->left->val | root->right->val;
			int tmp = root->left->R;
			printf("OR r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
		else if(c=='^'){
			root->val = root->left->val ^ root->right->val;
			int tmp = root->left->R;
			printf("XOR r%d r%d\n", tmp, root->right->R);
			r[root->right->R] = 0;
			root->R = tmp;
		}
	}
}
void Print(Node* root){
	if(root!=NULL){
		printf("%s ",root->data);
		Print(root->left);
		Print(root->right);
		
	}
}
void Free(Node* root){
	if(root!=NULL){
		Free(root->left);
		Free(root->right);
		free(root);
	}
}

 

Revise this Paste

Your Name: Code Language: