%{
#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;
}
}