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 109000114 ( 5 years ago )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLEN 256
#define TBLSIZE 64
#define PRINTERR 1

#define error(errorNum) { \
    err(errorNum); \
}

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

typedef enum {
    UNDEFINED, MISPAREN, NOTNUMID, NOTFOUND,
    RUNOUT, NOTLVAL, DIVZERO, SYNTAXERR
} ErrorType;

typedef struct {
    int val;
    char name[MAXLEN];
} Symbol;

typedef struct _Node {
    TokenSet data;
    int val;
    char lexeme[MAXLEN];
    struct _Node *left;
    struct _Node *right;
} BTNode;

void initTable(void);
char *getLexeme(void);
int match(TokenSet token);
BTNode *makeNode(TokenSet tok, const char *lexe);
void statement(void);
BTNode *assign_expr(void);
BTNode *assign_expr(void);
BTNode *or_expr(void);
BTNode *or_expr_tail(BTNode *left);
BTNode *xor_expr(void);
BTNode *xor_expr_tail(BTNode *left);
BTNode *and_expr(void);
BTNode *and_expr_tail(BTNode *left);
BTNode *addsub_expr(void);
BTNode *addsub_expr_tail(BTNode *left);
BTNode *muldiv_expr(void);
BTNode *muldiv_expr_tail(BTNode *left);
BTNode *unary_expr(void);
BTNode *factor(void);
void printPrefix(BTNode *root);

void advance(void);
TokenSet getToken(void);
int getval(char *str);
int setval(char *str, int val);
int evaluateTree(BTNode *root);
void err(ErrorType errorNum);
void freeTree(BTNode *root);
BTNode *expr_tail(BTNode *left);
BTNode *expr(void);
BTNode *term_tail(BTNode *left);
BTNode *term(void);

char lexeme[MAXLEN];
int cnt = 0;
int sbcount = 0;
Symbol table[TBLSIZE];
TokenSet curToken = UNKNOWN;

int main()
{
    initTable();
    while (1) {
        statement();
    }
    return 0;
}

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;
}

char *getLexeme(void)
{
    return lexeme;
}

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


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 statement(void)
{
    BTNode *retp = NULL;
    if (match(END)) {
        advance();
    }
    else {
        retp = assign_expr();
        if (match(END)) {
            printPrefix(retp);
            printf("\n");
            evaluateTree(retp);

            cnt = 0;
            freeTree(retp);
            advance();
        }
        else error(SYNTAXERR);
    }
}

BTNode *assign_expr(void)
{
    BTNode *node = NULL;
    if(match(ID))
    {
        BTNode *left=NULL;
        left = makeNode(ID,getLexeme());
        advance();
        if(match(ASSIGN))
        {
            node = makeNode(ASSIGN, getLexeme());
            advance();
            node->left = left;
            node->right = assign_expr();
        }
        else if(match(END))
        {
            ungetc('\n',stdin);
            node=or_expr();
        }
        else
        {
            int len=0;
            len=strlen(left->lexeme);
            if(len>0)
            {
                for(int i=len-1;i>=0;i--)
                    ungetc(left->lexeme[i],stdin);
            }
            node=or_expr();
        }
    }
    else
        node=or_expr();
    return node;
}

BTNode *or_expr(void) {
    BTNode *node = xor_expr();
    return or_expr_tail(node);
}
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;
}

BTNode *xor_expr(void) {
    BTNode *node = and_expr();
    return xor_expr_tail(node);
}
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;
}

BTNode *and_expr(void) {
    BTNode *node = addsub_expr();
    return and_expr_tail(node);
}
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;
}

BTNode *addsub_expr(void) {
    BTNode *node = muldiv_expr();
    return addsub_expr_tail(node);
}
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;
}

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

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;
}

BTNode *unary_expr(void)
{
    BTNode *node = NULL;
    if(match(ADDSUB))
    {
        node = makeNode(ADDSUB, getLexeme());
        advance();
        node->right = unary_expr();
    }
    else
        node=factor();
    return node;
}

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))
    {
        left = makeNode(INCDEC, getLexeme());
        advance();
        retp = makeNode(ID, getLexeme());
        retp->left=left;
    }
    else if (match(LPAREN)) {
        advance();
        retp = assign_expr();
        if (match(RPAREN))
            advance();
        else error(MISPAREN);
    }
    else error(NOTNUMID);
    return retp;
}


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

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);
        }
        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 {
            ungetc(c, stdin);
            lexeme[1] = '\0';
            return ADDSUB;
        }
    }
    else if (c == '|' || c == '^'||c == '&' ) {
        lexeme[0] = c;
        lexeme[1] = '\0';
        return LOGICAL;
    }
    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 (isalpha(c) || c == '_') {
        lexeme[0] = c;
        c = fgetc(stdin);
        i = 1;
        while (isalpha(c) || isdigit(c) || c == '_') {
            lexeme[i] = c;
            ++i;
            c = fgetc(stdin);
        }
        ungetc(c, stdin);
        lexeme[i] = '\0';
        return ID;
    }
    else if (c == EOF) {
        return ENDFILE;
    }
    else return UNKNOWN;
}

int setval(char *str, int val)
{
    int i = 0;
    for (i = 0; i < sbcount; i++) {
        if (strcmp(str, table[i].name) == 0) {
            table[i].val = val;
            printf("MOV [%d] r%d\n", i*4, cnt-1);
            return val;
        }
    }

    if (sbcount >= TBLSIZE) error(RUNOUT);

    strcpy(table[sbcount].name, str);
    table[sbcount].val = val;
    printf("MOV [%d] r%d\n", sbcount*4, cnt-1);
    sbcount++;
    return val;
}


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

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

int evaluateTree(BTNode *root)
{
    int retval = 0, lv = 0, rv = 0;

    if (root != NULL) {
        switch (root->data) {
            case ID:
                retval = getval(root->lexeme);
                cnt++;
                break;
            case INT:
                retval = atoi(root->lexeme);
                printf("MOV r%d %d\n", cnt, retval);
                cnt++;
                break;
            case ASSIGN:
                rv = evaluateTree(root->right);
                retval = setval(root->left->lexeme, rv);
                break;
            case ADDSUB:
                lv = evaluateTree(root->left);
                rv = evaluateTree(root->right);
                if (strcmp(root->lexeme, "+") == 0) {
                    retval = lv + rv;
                    printf("ADD r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                else if (strcmp(root->lexeme, "-") == 0) {
                    retval = lv - rv;
                    printf("SUB r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                break;
            case MULDIV:
                lv = evaluateTree(root->left);
                rv = evaluateTree(root->right);
                if (strcmp(root->lexeme, "*") == 0) {
                    retval = lv * rv;
                    printf("MUL r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                else if (strcmp(root->lexeme, "/") == 0) {
                    if (rv == 0) error(DIVZERO);
                    retval = lv / rv;
                    printf("DIV r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                break;
            case INCDEC:
                lv = evaluateTree(root->left);
                rv = evaluateTree(root->right);
                if (strcmp(root->lexeme, "++") == 0) {
                    retval = lv + rv;
                    printf("ADD r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                    setval(root->left->lexeme, retval);
                }
                else if (strcmp(root->lexeme, "--") == 0) {
                    retval = lv - rv;
                    printf("SUB r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                    setval(root->left->lexeme, retval);
                }
                break;
            case LOGICAL://add
                lv = evaluateTree(root->left);
                rv = evaluateTree(root->right);
                if (strcmp(root->lexeme, "&") == 0) {
                    retval = lv & rv;
                    printf("AND r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                else if (strcmp(root->lexeme, "|") == 0) {
                    retval = lv | rv;
                    printf("OR r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                else if (strcmp(root->lexeme, "^") == 0) {
                    retval = lv ^ rv;
                    printf("XOR r%d r%d\n", cnt-2, cnt-1);
                    cnt--;
                }
                break;
            default:
                retval = 0;
        }
    }
    return retval;
}
void err(ErrorType errorNum)
{
    printf("EXIT 1\n");
    exit(0);
}
void freeTree(BTNode *root)
{
    if (root != NULL) {
        freeTree(root->left);
        freeTree(root->right);
        free(root);
    }
}

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

 

Revise this Paste

Your Name: Code Language: