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