%{
#include <stdio.h>
#include <stdlib.h>
%}

%start program

%token IDENTIFIER
%token NUMBER
%token INTEGER
%token FLOAT
%token BOOLEAN
%token STRING

%token OR 
%token AND 
%token NOT 
%token EQUALS 
%token NOT_EQUALS 
%token GREATER_THAN 
%token LESS_THAN 
%token GREATER_THAN_EQUAL 
%token LESS_THAN_EQUAL 

%token FOR 
%token WHILE 

%token IF 
%token ELSE 
%token SEMICOLON
%token <string> type
%token VALUE

%left OR
%left AND
%nonassoc EQUALS NOT_EQUALS GREATER_THAN LESS_THAN GREATER_THAN_EQUAL LESS_THAN_EQUAL
%left '+' '-'
%left '*' '/'

//Define yyval
%union {
    int number;
    char *string;
}

%type <string> IDENTIFIER
%type <number> NUMBER
%type <string> STRING
%type <string> declaration
%type <string> loop
%type <string> condition
%type <bool> expression
%type <string> comparator
%type <statement_list> statement_list
%%

// Program
program: statement_list | YYEOF ;
statement: declaration | loop | condition | SEMICOLON ;
/*
 * Action Code
 */

// Declaration Action
declaration: type IDENTIFIER SEMICOLON {
    printf("Declared %s of type %s\n", $2, $1);
    // Allocate memory for the new variable
    if (strcmp($1, "int") == 0) {
        int *var = malloc(sizeof(int));
        // Save the pointer in the symbol table
        SymbolTable_add($2, var);
    } else if (strcmp($1, "float") == 0) {
        float *var = malloc(sizeof(float));
        // Save the pointer in the symbol table
        SymbolTable_add($2, var);
    } else if (strcmp($1, "bool") == 0) {
        bool *var = malloc(sizeof(bool));
        // Save the pointer in the symbol table
        SymbolTable_add($2, var);
    } else if (strcmp($1, "string") == 0) {
        char *var = malloc(sizeof(char*));
        // Save the pointer in the symbol table
        SymbolTable_add($2, var);
    }
} ;

// Loop Action
loop: FOR '(' type condition ')' statement_list {
    printf("Loop: for (%s) {\n", $3);
    // Execute the loop body
    executeLoop($3);
}
    | WHILE '(' type condition ')' statement_list {
    printf("Loop: while (%s) {\n", $3);
    // Execute the loop body
    executeLoop($3);
} ;

// Condition Action
condition: expression comparator expression {
    // Evaluate the expression
    bool result = evaluateCondition($1, $2, $3);
    if (result) {
        // Execute the statement list
        executeStatements(statement_list);
    } else {
        printf("Condition: %s %s %s\n", $1->string, $2->type, $3->string);
    }
};

// Expression Action
expression: IDENTIFIER {
	printf("Expression: %s\n", $1->string);
	// Lookup the variable in the symbol table
	void *var = SymbolTable_lookup($1->string);
	// Return the result of the expression
	return var;
}
          | NUMBER {
	printf("Expression: %d\n", $1->number);
	// Return the result of the expression
	return $1->number;
}
          | STRING {
	printf("Expression: %s\n", $1->string);
	// Return the result
	return $1->string;
}
          | expression '+' expression {
	printf("Addition: %d + %d\n", $1, $3);
	// Add the two operands
	return $1 + $3;
}         %prec '*'
          | expression '-' expression {
	printf("Subtraction: %d - %d\n", $1, $3);
	// Subtract the second operand from the first
	return $1 - $3;
}         %prec '*'
          | expression '*' expression {
	printf("Multiplication: %d * %d\n", $1, $3);
	// Multiply the two operands
	return $1 * $3;
}
          | expression '/' expression {
	printf("Division: %d / %d\n", $1, $3);
	// Check for division by zero
	if ($3 == 0) {
		fprintf(stderr, "Error: division by zero\n");
		exit(1);
	}
	// Divide the first operand by the second
	return $1 / $3;
}         %prec '*';

// Comparator Action
comparator: OR {printf("Comparator: ||\n");}
          | AND {printf("Comparator: &&\n");}
          | NOT {printf("Comparator: !\n");}
          | EQUALS {printf("Comparator: ==\n");}
          | NOT_EQUALS {printf("Comparator: !=\n");}
          | GREATER_THAN {printf("Comparator: >\n");}

          | LESS_THAN {printf("Comparator: <\n");}

          | GREATER_THAN_EQUAL {printf("Comparator: >=\n");}

          | LESS_THAN_EQUAL {printf("Comparator: <=\n");} ;

// Statement List Action
statement_list: statement_list statement {printf("Statement List: \n");}
              | statement {printf("Statement List: \n");} ;
Fix shift/reduce conflicts in this code