Untitled

 avatar
unknown
c_cpp
2 years ago
25 kB
3
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLEN 256

// Token types
typedef enum {
    UNKNOWN, END, ENDFILE, 
    INT, ID,
    ADDSUB, MULDIV,
    ASSIGN, 
    LPAREN, RPAREN,
    INCDEC,
    AND, OR, XOR
} TokenSet;

// Test if a token matches the current token 
int match(TokenSet token);

// Get the next token
void advance(void);

// Get the lexeme of the current token
char *getLexeme(void);

#define TBLSIZE 64

// Set PRINTERR to 1 to print error message while calling error()
// Make sure you set PRINTERR to 0 before you submit your code
#define PRINTERR 1

// Call this macro to print error message and exit the program
// This will also print where you called it in your program
#define error(errorNum) { \
    if (PRINTERR) \
        fprintf(stderr, "error() called at %s:%d: ", __FILE__, __LINE__); \
    err(errorNum); \
}

// Error types
typedef enum {
    UNDEFINED, MISPAREN, NOTNUMID, NOTFOUND, RUNOUT, NOTLVAL, DIVZERO, SYNTAXERR, ILLEGAL_VAR
} ErrorType;

// Structure of the symbol table
typedef struct {
    int val;
    char name[MAXLEN];
} Symbol;

// Structure of a tree node
typedef struct _Node {
    TokenSet data;
    int val;
    char lexeme[MAXLEN];
    struct _Node *left; 
    struct _Node *right;
} BTNode;

// The symbol table
extern Symbol table[TBLSIZE];
static int in = 0;
static BTNode *innode;
// Initialize the symbol table with builtin variables
extern void initTable(void);

// Get the value of a variable
extern int getval(char *str);

// Set the value of a variable
extern int setval(char *str, int val);

// Make a new node according to token type and lexeme
extern BTNode *makeNode(TokenSet tok, const char *lexe);

// Free the syntax tree
extern void freeTree(BTNode *root);

extern BTNode *factor(void);
extern BTNode *unary_expr();
extern BTNode *muldiv_expr_tail(BTNode *left);
extern BTNode *muldiv_expr();
extern BTNode *addsub_expr_tail(BTNode *left);
extern BTNode *addsub_expr();
extern BTNode *and_expr_tail(BTNode *left);
extern BTNode *and_expr();
extern BTNode *xor_expr_tail(BTNode *left);
extern BTNode *xor_expr();
BTNode *or_expr_tail(BTNode *left);
extern BTNode *or_expr();
BTNode *assign_expr();
void statement(void);

// Print error message and exit the program
void err(ErrorType errorNum);

extern int evaluateTree(BTNode *root);

// Print the syntax tree in prefix
extern void printPrefix(BTNode *root);

int count=0;
int inc,dec,indiv,have_v;
int have_val(BTNode* root);
//int reg_value[1] = {0};
//int regs[8];

int main() {
    freopen("input.txt", "w", stdout);
    initTable();
    //printf(">> ");
    //printf("MOV r%d [0]\n", count++);
    //printf("MOV r%d [4]\n", count++);
    //printf("MOV r%d [8]\n", count++);
    count = 0;
    while (1) {
        statement();
    }
    printf("EXIT 0\n");
    return 0;
}

static TokenSet getToken(void);
static TokenSet curToken = UNKNOWN;
static char lexeme[MAXLEN];

TokenSet getToken(void)
{
    int i = 0;
    char c = '\0';

    while ((c = fgetc(stdin)) == ' ' || c == '\t');

    if (isdigit(c)) {
        lexeme[0] = c;
        c = fgetc(stdin);
        i = 1;
        while (isdigit(c) && i < MAXLEN) {
            lexeme[i] = c;
            ++i;
            c = fgetc(stdin);
        }
        if(isalpha(c) || c == '_')
        {
            error(ILLEGAL_VAR);
        }
        if(i >= MAXLEN)
            error(RUNOUT);
        ungetc(c, stdin);
        lexeme[i] = '\0';
        return INT;
    } else if (c == '+' || c == '-') {
        lexeme[0] = c;
        c = fgetc(stdin);
        if(c == '+' && lexeme[0] == '+')
        {
            lexeme[1] = c;
            lexeme[2] = '\0';
            return INCDEC;
        }
        else if(c == '-' && lexeme[0] == '-')
        {
            lexeme[1] = c;
            lexeme[2] = '\0';
            return INCDEC;
        }
        ungetc(c, stdin);
        lexeme[1] = '\0';
        return ADDSUB;
    } else if (c == '*' || c == '/') {
        lexeme[0] = c;
        lexeme[1] = '\0';
        return MULDIV;
    } else if (c == '\n') {
        lexeme[0] = '\0';
        return END;
    } else if (c == '=') {
        strcpy(lexeme, "=");
        return ASSIGN;
    } else if (c == '(') {
        strcpy(lexeme, "(");
        return LPAREN;
    } else if (c == ')') {
        strcpy(lexeme, ")");
        return RPAREN;
    } else if (c == '&'){
        strcpy(lexeme, "&");
        return AND;
    } else if (c == '|'){
        strcpy(lexeme, "|");
        return OR;
    } else if (c == '^'){
        strcpy(lexeme, "^");
        return XOR;
    } else if (isalpha(c) || c == '_') {
        lexeme[0] = c;
        c = fgetc(stdin);
        i=1;
        while((isalpha(c) || c == '_' || isdigit(c)) && i<MAXLEN){
            lexeme[i] = c;
            ++i;
            c = fgetc(stdin);
        }
        if(i >= MAXLEN)
            error(RUNOUT);
        ungetc(c, stdin);
        lexeme[i] = '\0';
        return ID;
    } else if (c == EOF) {
        return ENDFILE;
    } else {
        return UNKNOWN;
    }
}

void advance(void) {
    curToken = getToken();
}

int match(TokenSet token) {
    if (curToken == UNKNOWN)
        advance();
    return token == curToken;
}

char *getLexeme(void) {
    return lexeme;
}


int sbcount = 0;
Symbol table[TBLSIZE];

void initTable(void) {
    strcpy(table[0].name, "x");
    table[0].val = 0;
    strcpy(table[1].name, "y");
    table[1].val = 0;
    strcpy(table[2].name, "z");
    table[2].val = 0;
    sbcount = 3;
}

int getval(char *str) {
    int i = 0;

    for (i = 0; i < sbcount; i++){
        if (strcmp(str, table[i].name) == 0)
        {
            /*for(int j=0; j<8; j++)
            {
                if(reg_value[j] == table[i].val && table[i].val != 0)
                {
                    printf("MOV r%d r%d\n", count, j);
                    //printf("MOV r%d %d\n", count, table[i].val);
                    reg_value[count] = table[i].val;
                    return table[i].val;
                }
            }*/
            if(count>7)
                exit(1);
            printf("MOV r%d [%d]\n", count, i*4);
            //reg_value[count] = table[i].val;
            return table[i].val;
        }
    }

    error(NOTFOUND);
    return 0;
}

int setval(char *str, int val) {
    int i = 0;

    for (i = 0; i < sbcount; i++) {
        if (strcmp(str, table[i].name) == 0) {
            if(count>7)
                exit(1);
            printf("MOV [%d] r%d\n", i*4, count);
            table[i].val = val;
            return val;
        }
    }

    if (sbcount >= TBLSIZE)
        error(RUNOUT);
    
    strcpy(table[sbcount].name, str);
    table[sbcount].val = val;
    if(count>7)
        exit(1);
    printf("MOV [%d] r%d\n", sbcount*4, count);
    sbcount++;
    return val;
}

BTNode *makeNode(TokenSet tok, const char *lexe) {
    BTNode *node = (BTNode*)malloc(sizeof(BTNode));
    strcpy(node->lexeme, lexe);
    node->data = tok;
    node->val = 0;
    node->left = NULL;
    node->right = NULL;
    return node;
}

void freeTree(BTNode *root) {
    if (root != NULL) {
        freeTree(root->left);
        freeTree(root->right);
        free(root);
    }
}

//factor := INT | ID | INCDEC ID | LPAREN assign_expr RPAREN

BTNode *factor(void) {
    BTNode *retp = NULL, *left = NULL;

    if (match(INT)) {
        retp = makeNode(INT, getLexeme());
        advance();
    } else if (match(ID)) {
        retp = makeNode(ID, getLexeme());
        advance();
    } else if (match(INCDEC)){
        retp = makeNode(INCDEC, getLexeme());
        advance();
        
        if(match(ID)){
            retp->right = makeNode(ID, getLexeme());
            advance();
        }
        else{
            error(NOTLVAL);
        }
    } else if (match(LPAREN)) {
        //retp = makeNode(LPAREN, getLexeme());
        advance();
        //retp->right = assign_expr();
        retp = assign_expr();
        if (match(RPAREN))
            advance();
        else
            error(MISPAREN);
    } else {
        error(NOTNUMID);
    }
    return retp;
}

//unary_expr := ADDSUB unary_expr | factor 
BTNode *unary_expr() {
    BTNode *node = NULL;

    if(innode != NULL) {
        node = innode;
        innode = NULL;
        return node;
    }
    if(match(ADDSUB)) {
        node = makeNode(ADDSUB, getLexeme());
        node->left = makeNode(INT, "0");
        advance();
        node->right = unary_expr();
        return node;
    } else {
        node = factor();
        return node;
    }
}


//muldiv_expr_tail := MULDIV unary_expr muldiv_expr_tail | NiL 
BTNode *muldiv_expr_tail(BTNode *left) {
    BTNode *node = NULL;

    if(match(MULDIV)) {
        node = makeNode(MULDIV, getLexeme());
        advance();
        node->left = left;
        node->right = unary_expr();
        return muldiv_expr_tail(node);
    } else {
        return left;
    }
}


//muldiv_expr := unary_expr muldiv_expr_tail 
BTNode *muldiv_expr() {
    BTNode *node = unary_expr();
    return muldiv_expr_tail(node);
}


//addsub_expr_tail := ADDSUB muldiv_expr addsub_expr_tail | NiL 
BTNode *addsub_expr_tail(BTNode *left) {
    BTNode *node = NULL;

    if(match(ADDSUB)) {
        node = makeNode(ADDSUB, getLexeme());
        advance();
        node->left = left;
        node->right = muldiv_expr();
        return addsub_expr_tail(node);
    } else {
        return left;
    }
}


//addsub_expr := muldiv_expr addsub_expr_tail 
BTNode *addsub_expr() {
    BTNode *node = muldiv_expr();
    return addsub_expr_tail(node);
}


//and_expr_tail := AND addsub_expr and_expr_tail | NiL 
BTNode *and_expr_tail(BTNode *left) {
    BTNode *node = NULL;

    if(match(AND)) {
        node = makeNode(AND, getLexeme());
        advance();
        node->left = left;
        node->right = addsub_expr();
        return and_expr_tail(node);
    } else {
        return left;
    }
}


//and_expr := addsub_expr and_expr_tail 
BTNode *and_expr() {
    BTNode *node = addsub_expr();
    return and_expr_tail(node);
}


//xor_expr_tail := XOR and_expr xor_expr_tail | NiL 
BTNode *xor_expr_tail(BTNode *left) {
    BTNode *node = NULL;

    if(match(XOR)) {
        node = makeNode(XOR, getLexeme());
        advance();
        node->left = left;
        node->right = and_expr();
        return xor_expr_tail(node);
    }
    else {
        return left;
    }
}


//xor_expr := and_expr xor_expr_tail 
BTNode *xor_expr() {
    BTNode *node = and_expr();
    return xor_expr_tail(node);
}


// or_expr_tail := OR xor_expr or_expr_tail | NiL 
BTNode *or_expr_tail(BTNode *left) {
    BTNode *node = NULL;

    if(match(OR)) {
        node = makeNode(OR, getLexeme());
        advance();
        node->left = left;
        node->right = xor_expr();
        return or_expr_tail(node);
    } else {
        return left;
    }
}


// or_expr := xor_expr or_expr_tail 
BTNode *or_expr() {
    //printf("C");
    BTNode *node = xor_expr();
    return or_expr_tail(node);
}


// assign_expr := ID ASSIGN assign_expr | or_expr
BTNode *assign_expr() {
    BTNode *node = NULL, *left = NULL;

    if(match(ID)) {
        left = makeNode(ID, getLexeme());
        advance();
        if(match(ASSIGN)) {
            node = makeNode(ASSIGN, getLexeme());
            advance();
            node->left = left;
            node->right = assign_expr();
            return node;
        } else {
            //printf("c");
            in = 1;
            innode = left;
            node = or_expr();
            innode = NULL;
            in = 0;
            return node;
        }  
    } else {
        node = or_expr();
        return node;
    }
}


// statement := ENDFILE | END | expr END
void statement(void) {
    BTNode *retp = NULL;

    if (match(ENDFILE)) {
        printf("MOV r0 [0]\n");
        printf("MOV r1 [4]\n");
        printf("MOV r2 [8]\n");
        printf("EXIT 0\n");
        exit(0);
    } else if (match(END)) {
        //printf(">> ");
        advance();
    } else {
        retp = assign_expr();
        if (match(END)) {
            evaluateTree(retp);
            freeTree(retp);
            //printf("%d\n", evaluateTree(retp));
            //printf("Prefix traversal: ");
            //printPrefix(retp);
            //printf("\n");
            //freeTree(retp);
            //printf(">> ");
            advance();
            count = 0;
        } else {
            error(SYNTAXERR);
        }
    }
}

void err(ErrorType errorNum) {
    if (PRINTERR)  printf("EXIT 1\n");
    exit(0);
}

int parcount;
int evaluateTree(BTNode *root) {
    int retval = 0, lv = 0, rv = 0;
    int recount;
    //int regs[1000][8];
    BTNode* temp = NULL;
    int tmp=0;

    if (root != NULL) {
        switch (root->data) {
            case ID:
                retval = getval(root->lexeme);
                break;
            case INT:
                retval = atoi(root->lexeme);
                if(count>7)
                    exit(1);
                printf("MOV r%d %d\n", count, retval);
                //reg_value[count] = retval;
                break;
            case ASSIGN:
                rv = evaluateTree(root->right);
                if(root->left->data!=ID) error(SYNTAXERR);
                retval = setval(root->left->lexeme, rv);
                break;
            case ADDSUB:
            if(strcmp(root->lexeme, "+") == 0)
            {
                if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }
                lv = evaluateTree(root->left);

                if(strcmp(root->right->lexeme, "+") == 0)
                {
                    rv = evaluateTree(root->right);
                    //printf("MOV r%d r%d\n", count-1,count);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    printf("ADD r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = retval;
                }
                retval = lv + rv;
                //reg_value[count] = retval;
            }
            else if(strcmp(root->lexeme, "-") == 0)
            {
                /*if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }*/
                lv = evaluateTree(root->left);

                if(strcmp(root->right->lexeme, "-") == 0)
                {
                    rv = evaluateTree(root->right);
                    //printf("MOV r%d r%d\n", count-1,count);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    /*if(root->right->data == ID || root->right->data == INT)
                    {
                        printf("SUB r%d r%d\n", count, count-1);
                        printf("MOV r%d r%d\n", count-1, count);
                    }
                    else*/
                        printf("SUB r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = retval;
                }
                if(root->right->data == ID || root->right->data == INT)
                {
                    //printf("%d\n", lv);
                    retval = rv-lv;
                }
                else
                    retval = lv - rv;
                //reg_value[count] = retval;
            }
            break;
            case MULDIV:
            if(strcmp(root->lexeme, "*") == 0)
            {
                if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }
                lv = evaluateTree(root->left);

                if(strcmp(root->right->lexeme, "*") == 0)
                {
                    rv = evaluateTree(root->right);
                    //printf("MOV r%d r%d\n", count-1,count);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    printf("MUL r%d r%d\n", count-1, count);
                    //reg_value[count] = retval;
                    count--;
                }
                retval = lv * rv;
                //reg_value[count] = retval;
            }
            else if(strcmp(root->lexeme, "/") == 0)
            {
                /*if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }*/
                lv = evaluateTree(root->left);

                if(strcmp(root->right->lexeme, "/") == 0)
                {
                    //indiv = 1;
                    //have_v = 0;
                    rv = evaluateTree(root->right);
                    /*if(root->right->data == ID || root->right->data == INT)
                    {
                        tmp = lv;
                        lv = rv;
                        rv = tmp;
                    }*/
                    if(rv == 0)
                    {
                        if(have_val(root->right))
                        {
                            retval = 0;
                        }
                        else
                            error(DIVZERO);
                    }
                    else
                        retval = lv/rv;
                    //printf("MOV r%d r%d\n", count-1,count);
                }
                else
                {
                    //indiv = 1;
                    //have_v = 0;
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    /*if(root->right->data == ID || root->right->data == INT)
                    {
                        tmp = lv;
                        lv = rv;
                        rv = tmp;
                    }*/
                    if(rv == 0)
                    {
                        if(have_val(root->right))
                        {
                            retval = 0;
                        }
                        else
                            error(DIVZERO);
                    
                    }
                    else
                        retval = lv/rv;

                    /*if(root->right->data == ID || root->right->data == INT)
                    {
                        printf("DIV r%d r%d\n", count, count-1);
                        printf("MOV r%d r%d\n", count-1, count);
                    }
                    else*/
                        printf("DIV r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = reg_value[count+1];
                }
                //reg_value[count] = retval;
            }
                break;
            case INCDEC:
                if(strcmp(root->lexeme, "++") == 0)
                {
                    //inc = 1;
                    //lv = evaluateTree(root->left);
                    printf("MOV r%d 1\n", count);
                    //reg_value[count] = 1;
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    //reg_value[count] = rv;
                    printf("ADD r%d r%d\n", count-1, count);
                    count--;
                    retval = rv+1;
                    //reg_value[count] = retval;
                    //inc = 0;
                }
                else if(strcmp(root->lexeme, "--") == 0)
                {
                    //dec = 1;
                    //lv = evaluateTree(root->left);
                    printf("MOV r%d -1\n", count);
                    //reg_value[count] = -1;
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    //reg_value[count] = rv;
                    printf("ADD r%d r%d\n", count-1, count);
                    count--;
                    retval = rv-1;
                    //reg_value[count] = retval;
                    //dec = 0;
                }
                setval(root->right->lexeme, retval);
                break;
            case AND:
            if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }
                lv = evaluateTree(root->left);
            
                if(root->right->data == AND)
                {
                    rv = evaluateTree(root->right);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    printf("AND r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = retval;
                }
                retval = lv & rv;
                //reg_value[count] = retval;
                break;
            case OR:
            if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }
                lv = evaluateTree(root->left);
            
                if(root->right->data == OR)
                {
                    rv = evaluateTree(root->right);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    printf("OR r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = retval;
                }
                retval = lv | rv;
                //reg_value[count] = retval;
                break;
            case XOR:
            if(root->left->data == ID || root->left->data == INT)
                {
                    temp = root->left;
                    root->left = root->right;
                    root->right = temp;
                }
                lv = evaluateTree(root->left);
            
                if(root->right->data == XOR)
                {
                    rv = evaluateTree(root->right);
                }
                else
                {
                    count++;
                    if(count>=8)
                        exit(1);
                    rv = evaluateTree(root->right);
                    printf("XOR r%d r%d\n", count-1, count);
                    count--;
                    //reg_value[count] = retval;
                }
                retval = lv ^ rv;
                //reg_value[count] = retval;
                break;
            default:
                retval = 0;
        }
    }
    return retval;
}

int have_val(BTNode* root)
{
    if(root!=NULL)
    {
        if(root->data == ID)
            return 1;
        if(have_val(root->left))
            return 1;
        if(have_val(root->right))
            return 1;
            
            return 0;
    }
    return 0;
}

void printPrefix(BTNode *root) {
    if (root != NULL) {
        printf("%s ", root->lexeme);
        printPrefix(root->left);
        printPrefix(root->right);
    }
}
Editor is loading...