Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
19 kB
2
Indexable
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bengisuozdemir-hw3.h"

void yyerror (const char *s) 
{return;}

ExprNode * makeExpressionNodeFromIdent(IdentNode);
ExprNode * makeExpressionNodeFromNumber(NumberNode);


ExprNode * sumExpr(ExprNode *, ExprNode *);
ExprNode * mulExpr(ExprNode *, ExprNode *);
ExprNode * divExpr(ExprNode *, ExprNode *);
ExprNode * subExpr(ExprNode *, ExprNode *);
void assign(ExprNode *, ExprNode *);
int checkIdentifier(ExprNode *);

ExprNode ** expressions;
int expressionsSize = 100;
int exprIndex = 0;

int error = 0;

char ** errors;
int errorSize = 100;
int errorIndex = 0;

%}
%union{
    IdentNode identNode;
    NumberNode numberNode;
    ExprNode * exprNodePtr;
   
    int lineNum;
}
%token <lineNum> tASSIGN
%token <identNode> tIDENT
%token <numberNode> tNUMBER


%token tPLUS tSUB tMUL tDIV tSTRING tPRINT tGET tSET tFUNCTION tRETURN tEQUALITY tIF tGT tLT tGEQ tLEQ tINC tDEC

%start prog
%type <exprNodePtr> expr

%%
prog:		'[' stmtlst ']'
;

stmtlst:|
		|stmtlst stmt 
		|summationStatement stmtlst
        |multiplicationStatement stmtlst
        |divisionStatement stmtlst
        |subtractionStatement stmtlst
		|assignmentStatement stmtlst

;

stmt:		assignmentStatement | if | print | unaryOperation | expr | returnStmt
;

/*implemet other operations here*/
summationStatement :'[' tPLUS ',' expr ',' expr ']'{
                       sumExpr($4, $6);
                    }
;
multiplicationStatement :'[' tMUL ',' expr ',' expr ']'{
                       mulExpr($4, $6);
                    }
;
divisionStatement : '[' tDIV ',' expr ',' expr ']'{
                       divExpr($4, $6);
                    }
;
subtractionStatement : '[' tSUB ',' expr ',' expr ']'{
                       subExpr($4, $6);
                    }
;
/*implement set here*/
assignmentStatement : '[' tSET ',' expr ',' expr ']' {
    assign($4, $6);
}

;

expr : tIDENT {
        $$ = makeExpressionNodeFromIdent($1);
    }
    | tNUMBER{
        $$ = makeExpressionNodeFromNumber($1);
    }
    | getExpr | function | operation | condition
    
;



getExpr:	'[' tGET ',' tIDENT ',' '[' exprList ']' ']'
		| '[' tGET ',' tIDENT ',' '[' ']' ']'
		| '[' tGET ',' tIDENT ']'
;

setStmt:	'[' tSET ',' tIDENT ',' expr ']'
;

if:		'[' tIF ',' condition ',' '[' stmtlst ']' ']'
		| '[' tIF ',' condition ',' '[' stmtlst ']' '[' stmtlst ']' ']'
;

print:		'[' tPRINT ',' expr ']'
;

operation:	summationStatement
            | multiplicationStatement
            | divisionStatement
            | subtractionStatement 
;	

unaryOperation: '[' tINC ',' tIDENT ']'
		| '[' tDEC ',' tIDENT ']'
;



function:	 '[' tFUNCTION ',' '[' parametersList ']' ',' '[' stmtlst ']' ']'
		| '[' tFUNCTION ',' '[' ']' ',' '[' stmtlst ']' ']'
;

condition:	'[' tEQUALITY ',' expr ',' expr ']'
		| '[' tGT ',' expr ',' expr ']'
		| '[' tLT ',' expr ',' expr ']'
		| '[' tGEQ ',' expr ',' expr ']'
		| '[' tLEQ ',' expr ',' expr ']'
;

returnStmt:	'[' tRETURN ',' expr ']'
		| '[' tRETURN ']'
;

parametersList: parametersList ',' tIDENT | tIDENT
;

exprList:	exprList ',' expr | expr
;

%%
ExprNode * makeExpressionNodeFromIdent(IdentNode ident){

    ExprNode * newNode = (ExprNode *)malloc(sizeof(ExprNode));
    newNode->identifier = ident.value;
    newNode->value = -1;
    newNode->lineNum = ident.lineNum;
     printf("identifier: %d", newNode->identifier)
    return newNode;
}




ExprNode * makeExpressionNodeFromNumber(NumberNode number){

    ExprNode * newNode = (ExprNode *)malloc(sizeof(ExprNode));
    newNode->identifier = NULL;
    newNode->value = atoi(number.value);
    newNode->lineNum = number.lineNum;
    return newNode;
}


ExprNode * sumExpr(ExprNode * expr1, ExprNode * expr2){

    int expr_id1 = checkIdentifier(expr1);
    int expr_id2 = checkIdentifier(expr2);
    //int result_id = checkIdentifier(expr);
    ExprNode * expr = (ExprNode *)malloc(sizeof(ExprNode));
    expr->identifier = NULL;
    expr->lineNum = expr2->lineNum;
    //printf("Result id %d\n", result_id);
    //int result_id = checkIdentifier(expr);
    printf("exper_id1: %d", expr_id1)
    printf("exper_id2: %d", expr_id2)

    if(expr_id1 >= -1 && expr_id2 >= -1 ){
       if(expr_id1 >= 0 || expr_id2 >= 0)
       {
            if(expr_id1 >= 0)
            {
                expr1 = expressions[expr_id1];
                printf("expr1: %d", expr1)
            }
            if(expr_id2 >= 0)
            {
                expr2 = expressions[expr_id2];
                printf("expr2: %d", expr2)
            }
            expr->value = expr1->value + expr2->value;
            printf("expr: %d", expr)
            printf("expr->value: %d", expr->value)
            PLUSExpressionToList(expr);
        }
        if(expr_id1 == -1 && expr_id2 == -1){
            //expressions have num token
            expr->value = expr1->value + expr2->value;
            PLUSExpressionToList(expr);   
        }    
        else{
            error = 1;
            char * src =  "ERROR at line %d: Assigment to number is invalid\n";
            char * dest = (char *)malloc(strlen(src) + expr->lineNum + 10);
            sprintf(dest, src, expr->lineNum);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
    }
    else{
        error = 1;
        if(expr_id1 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr1->identifier) + expr1->lineNum + 10);
            sprintf(dest, src, expr1->lineNum, expr1->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        if(expr_id2 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr2->identifier) + expr2->lineNum + 10);
            sprintf(dest, src, expr2->lineNum, expr2->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        return NULL;
    }
}
ExprNode * mulExpr(ExprNode * expr1, ExprNode * expr2){

    int expr_id1 = checkIdentifier(expr1);
    int expr_id2 = checkIdentifier(expr2);
    //int result_id = checkIdentifier(expr);
    ExprNode * expr = (ExprNode *)malloc(sizeof(ExprNode));
    expr->identifier = NULL;
    expr->lineNum = expr2->lineNum;
    //printf("Result id %d\n", result_id);
    //int result_id = checkIdentifier(expr);

    if(expr_id1 >= -1 && expr_id2 >= -1 ){
        if(expr_id1 >= 0 || expr_id2 >= 0){
            if(expr_id1 >= 0){
            expr1 = expressions[expr_id1];
            }
            if(expr_id2 >= 0){
                expr2 = expressions[expr_id2];
            }
            expr->value = expr1->value * expr2->value;
            PLUSExpressionToList(expr);
        }
        if(expr_id1 == -1 && expr_id2 == -1){
            //expressions have num token
            expr->value = expr1->value * expr2->value;
            PLUSExpressionToList(expr);
        }
        else{
            error = 1;
            char * src =  "ERROR at line %d: Assigment to number is invalid\n";
            char * dest = (char *)malloc(strlen(src) + expr->lineNum + 10);
            sprintf(dest, src, expr->lineNum);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
    }
    else{
        error = 1;
        if(expr_id1 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr1->identifier) + expr1->lineNum + 10);
            sprintf(dest, src, expr1->lineNum, expr1->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        if(expr_id2 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr2->identifier) + expr2->lineNum + 10);
            sprintf(dest, src, expr2->lineNum, expr2->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        return NULL;
    }
}
ExprNode * divExpr(ExprNode * expr1, ExprNode * expr2){

    int expr_id1 = checkIdentifier(expr1);
    int expr_id2 = checkIdentifier(expr2);
    //int result_id = checkIdentifier(expr);
    ExprNode * expr = (ExprNode *)malloc(sizeof(ExprNode));
    expr->identifier = NULL;
    expr->lineNum = expr2->lineNum;
    //printf("Result id %d\n", result_id);
    //int result_id = checkIdentifier(expr);

    if(expr_id1 >= -1 && expr_id2 >= -1 ){
        if(expr_id1 >= 0 || expr_id2 >= 0){
            if(expr_id1 >= 0){
            expr1 = expressions[expr_id1];
            }
            if(expr_id2 >= 0){
                expr2 = expressions[expr_id2];
            }
            expr->value = expr1->value / expr2->value;
            PLUSExpressionToList(expr);
        }
        if(expr_id1 == -1 && expr_id2 == -1){
            //expressions have num token
            expr->value = expr1->value / expr2->value;
            PLUSExpressionToList(expr);
        }
        else{
            error = 1;
            char * src =  "ERROR at line %d: Assigment to number is invalid\n";
            char * dest = (char *)malloc(strlen(src) + expr->lineNum + 10);
            sprintf(dest, src, expr->lineNum);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
    }
    else{
        error = 1;
        if(expr_id1 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr1->identifier) + expr1->lineNum + 10);
            sprintf(dest, src, expr1->lineNum, expr1->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        if(expr_id2 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr2->identifier) + expr2->lineNum + 10);
            sprintf(dest, src, expr2->lineNum, expr2->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        return NULL;
    }
}
ExprNode * subExpr(ExprNode * expr1, ExprNode * expr2){

    int expr_id1 = checkIdentifier(expr1);
    int expr_id2 = checkIdentifier(expr2);
    //int result_id = checkIdentifier(expr);
    ExprNode * expr = (ExprNode *)malloc(sizeof(ExprNode));
    expr->identifier = NULL;
    expr->lineNum = expr2->lineNum;
    //printf("Result id %d\n", result_id);
    //int result_id = checkIdentifier(expr);

    if(expr_id1 >= -1 || expr_id2 >= -1 ){
        if(expr_id1 >= 0 || expr_id2 >= 0){
            if(expr_id1 >= 0){
            expr1 = expressions[expr_id1];
            }
            if(expr_id2 >= 0){
                expr2 = expressions[expr_id2];
            }
            expr->value = expr1->value - expr2->value;
            PLUSExpressionToList(expr);
        }
        if(expr_id1 == -1 && expr_id2 == -1){
            //expressions have num token
            expr->value = expr1->value - expr2->value;
            PLUSExpressionToList(expr);
        }
        else{
            error = 1;
            char * src =  "ERROR at line %d: Assigment to number is invalid\n";
            char * dest = (char *)malloc(strlen(src) + expr->lineNum + 10);
            sprintf(dest, src, expr->lineNum);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
    }
    else{
        error = 1;
        if(expr_id1 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr1->identifier) + expr1->lineNum + 10);
            sprintf(dest, src, expr1->lineNum, expr1->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        if(expr_id2 == -2) {
            char * src =  "ERROR at line %d: %s is undefined\n";
            char * dest = (char *)malloc(strlen(src) + strlen(expr2->identifier) + expr2->lineNum + 10);
            sprintf(dest, src, expr2->lineNum, expr2->identifier);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
        return NULL;
    }
}


int checkIdentifier(ExprNode * expr){
    /* RETURNS:
    -1 -> Number
    -2 -> not found
    i >= 0 -> index of identifier
    */
    if(expr->identifier == NULL){
        return -1;
    }
    int i = 0;
    for(;i<exprIndex;i++){
        //printf("Expr 1 %s - Expr 2 %s\n", expr->identifier, expressions[i]->identifier);
        if(strcmp(expr->identifier, expressions[i]->identifier) == 0 ){
            //printf("Expr index %d identifier %s\n", i, expressions[i]->identifier);
            //if they are equal return its occurence
            return i;
        }
    }
    return -2;
}

int PLUSExpressionToList(ExprNode * newExpr){
    /* PLUS expression to expressions list */
        if(exprIndex < expressionsSize){
            expressions[exprIndex] = newExpr;
            exprIndex += 1;
        }
        else{
            expressionsSize = expressionsSize + expressionsSize;
            expressions = realloc(expressions, expressionsSize);
            expressions[exprIndex] = newExpr;
            exprIndex += 1;
        }
}
//["Set", "x", "3"] : tSET tIDENT expr
void assign(ExprNode * expr1, ExprNode * expr2){
    int expr_id1 = checkIdentifier(expr1);
    int expr_id2 = checkIdentifier(expr2);

    if(expr_id2 >= -1 && expr_id1 >= -1){
        
        if(expr_id1 >= 0 || expr_id2 >= 0){
            expr2 = expressions[expr_id2];
            expr1 = expressions[expr_id1];
            expr1->value = expr2->value;
            
        }
        else if(expr_1 >= 0 || expr_id2 = -1){
            expr1 = expressions[expr_id1];
            expr_1->value = expr2
        }
       
        else{
            error = 1;
            char * src =  "Type missmatch on %d\n", expr2->lineNum ;
            char * dest = (char *)malloc(strlen(src) + expr2->lineNum + 10);
            sprintf(dest, src, expr2->lineNum);
            if(errorIndex < errorSize){
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
            else{
                errorSize = errorSize + errorSize;
                errors = realloc(errors, errorSize);
                errors[errorIndex] = dest;
                errorIndex += 1;
            }
        }
       
    }
    else{
        error = 1;
        char * src =  "Never initialized before undefined\n";
        char * dest = (char *)malloc(strlen(src) + strlen(expr2->identifier) + expr2->lineNum + 10);
        sprintf(dest, src, expr2->lineNum, expr2->identifier);
        if(errorIndex < errorSize){
            errors[errorIndex] = dest;
            errorIndex += 1;
        }
        else{
            errorSize = errorSize + errorSize;
            errors = realloc(errors, errorSize);
            errors[errorIndex] = dest;
            errorIndex += 1;
        }
    }

}

int main () 
{
    expressions = (ExprNode**)malloc(expressionsSize * sizeof(ExprNode*));
    errors = (char**)malloc(errorSize * sizeof(char*));

   if (yyparse())
   {
      // parse error
      printf("ERROR\n");
      return 1;
    } 
    else 
    {   
        if(error == 0){
            int i = 0;
            for(;i<exprIndex;i++){
                printf("Expression first defined at line %d with identifier %s with value %d\n", expressions[i]->lineNum, expressions[i]->identifier, expressions[i]->value );
            }
            // successful parsing
        }
        else{
            int i = 0;
            for(;i<errorIndex;i++){
                printf(errors[i]);
            }
        }
        //printf("OK\n");
        return 0;
    } 
}