%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 ‘+’ ‘-’
%left ‘*’ ‘/’
%left UNARY
%nonassoc COMPARE

%precedence AND
%precedence OR

%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
%type <statement> statement

%%

program: statement_list ;

statement_list: statement_list statement
| statement ;

statement: declaration ‘;’
| loop
| condition
| expression ‘;’
| ‘;’ ;

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

loop: FOR ‘(’ declaration condition ‘;’ expression ‘)’ statement_list {
printf(“Loop: for (%s; %s; %s) {\n”, $3, $4, $6);
// Execute the loop body
executeLoop($3, $4, $6, statement_list);
}
| WHILE ‘(’ expression ‘)’ statement_list {
printf(“Loop: while (%s) {\n”, $3);
// Execute the loop body
executeLoop(NULL, NULL, $3, statement_list);
}
;

condition: IF ‘(’ expression ‘)’ statement {
printf(“Condition: if (%s) {\n”, $3);
// Execute the statement list
executeCondition($3, $5);
}
| IF ‘(’ expression ‘)’ statement ELSE statement {
printf(“Condition: if (%s) {\n”, $3);
// Execute the first statement
executeCondition($3, $5);
printf(“} else {\n”);
// Execute the second statement
executeCondition(NULL, $7);
}
;

expression: IDENTIFIER {
printf(“Expression: %s\n”, $1);
// Lookup the variable in the symbol table
void var = SymbolTable_lookup(1);
// Return the result of the expression
$ = var;
}
| NUMBER {
printf(“Expression: %d\n”, 1);
// Return the result of the expression
$ = $1;
}
| STRING {
printf(“Expression: %s\n”, 1);
// Return the result
$ = $1;
}
| expression ‘+’ expression {
printf(“Addition: %d + %d\n”, $1, 3);
// Add the two operands
$ = $1 + $3;
}
| expression ‘-’ expression {
printf(“Subtraction: %d - %d\n”, $1, 3);
// Subtract the second operand from the first
$ = $1 - $3;
}
| expression '’ expression {
printf(“Multiplication: %d * %d\n”, $1, 3);
// Multiply the two operands
$ = $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
$ = $1 / $3;
}
| ‘-’ expression %prec UNARY {
printf(“Negation: -%d\n”, 2);
// Negate the operand
$ = -$2;
}
| expression comparator expression %prec COMPARE {
printf(“Comparison: %d %s %d\n”, $1, $2, $3);
// Evaluate the comparison

Complete the code