%{
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <iostream>
using namespace std;
#define Trace(t) printf(t)
#define MAX 256
int yylex(void);
void yyerror(const char *s);
struct content {
int ival;
float fval;
bool bval;
char id[MAX];
char sval[MAX];
char type[MAX];
char bigtype[MAX];
};
/*
//Symbol Table and Variables
struct content symbolTable[MAX][MAX]
int id_total=0;
int scope = 0;
//Function Prototypes
int insert(struct content a);
int lookup(char *c);
void dump();
//Function Defnitions
int insert(struct content a) {
// Check if id already in the symbol table
for(int i = 0 ; i < id_total; i++) {
if(strcmp(a.id, symbolTable[scope][i].id)==0) return 0;
}
// Copy a's content to symbol table
strcpy(symbolTable[scope][id_total].id, a.id);
strcpy(symbolTable[scope][id_total].type, a.type);
strcpy(symbolTable[scope][id_total].bigtype, a.bigtype);
if(strcmp("arrays", a.bigtype) != 0) {
if(strcmp("int", a.type) == 0) symbolTable[scope][id_total].ival = a.ival;
else if(strcmp("float", a.type) == 0) symbolTable[scope][id_total].fval = a.fval;
else if(strcmp("str", a.type) == 0) strcpy(symbolTable[scope][id_total].sval, a.sval);
else if(strcmp("bool", a.type) == 0) symbolTable[scope][id_total].bval = a.bval;
}
id_total++;
return 1;
}
int lookup(char *c){
for (int i = 0; i <= scope; i++) {
for(int j=0; j<=id_total; j++){
if (strcmp(c , symbolTable[i][j].id) == 0 && strcmp(symbolTable[i][j].type,"int") == 0) {
return symbolTable[i][j].ival;
}
}
}
return -1; // Add error handling (e.g., not found)
}
void printEntry(int i, int j) {
const char *print_format = "%-*s\t%-*s\t%-*s\t%-*s\t%-*d\n";
char value[256];
memset(value, 0, sizeof(value));
if(strcmp(symbolTable[i][j].type,"int")==0 && strcmp("arrays",symbolTable[i][j].bigtype)!=0){
sprintf(value, "%d", symbolTable[i][j].ival);
}
else if(strcmp(symbolTable[i][j].type,"float")==0 && strcmp("arrays",symbolTable[i][j].bigtype)!=0){
sprintf(value, "%.2f", symbolTable[i][j].fval);
}
else if(strcmp(symbolTable[i][j].type,"str")==0 && strcmp("arrays",symbolTable[i][j].bigtype)!=0){
strcpy(value, symbolTable[i][j].sval);
}
else if(strcmp(symbolTable[i][j].type,"bool")==0 && strcmp("arrays",symbolTable[i][j].bigtype)!=0){
strcpy(value, symbolTable[i][j].bval == 0 ? "False" : "True");
}
printf(print_format, 10, symbolTable[i][j].id, 10, symbolTable[i][j].type,
10, symbolTable[i][j].bigtype, 10, value, 10, i);
}
void dump() {
for (int i = 0; i <= scope; i++) {
for (int j = 0; j <= id_total; j++) {
printEntry(i, j);
}
}
}*/
%}
%union{
string* idString;
int integerValue;
float floatValue;
char *strValue;
char type[MAX];
}
/* tokens */
%token DOT COMMA COLON SEMICOLON LP RP LSB RSB LCB RCB PLUS MINUS MULTIPLY DIVIDE MOD COLONEQUALS LT LE GT GE EQ EQUALS NOTEQUALS AND OR NOT
%token ARRAY BOOL CHAR CONST DECREASING DEFAULT TO DO ELSE BEGIN_KEYWORD END EXIT FALSE FOR FUNCTION GET IF INT LOOP OF PUT PROCEDURE REAL RESULT RETURN SKIP STRING THEN TRUE VAR WHEN
%token <idString> IDENTIFIER
%token <floatValue> FLOATVAL
%token <integerValue> INTEGERVAL
%token <strValue> STRINGVAL
%token <integerValue> TRUEVAL
%token <integerValue> FALSEVAL
%token <integerValue> INT_RANGE
%nonassoc LT LE GT EG NE
%nonassoc EQ
%left AND
%left OR
%right NOT
%left PLUS MINUS
%left MULTIPLY DIVIDE MOD
%nonassoc UMINUS
%type<integerValue> unary_expression
%start program
%%
program:
|program_units {Trace("Reducing to program\n");}
;
program_units: program_unit
| program_units program_unit
|
;
program_unit: constant_declaration
| variables_declaration
| statements
;
constant_declaration:
CONST IDENTIFIER COLON type COLONEQUALS constant_exp
{
Trace("Reducing to [constant_declaration]\n");
}
| CONST IDENTIFIER COLONEQUALS constant_exp
{
Trace("Reducing to [constant_declaration]\n");
}
| CONST IDENTIFIER COLON type COLONEQUALS MINUS constant_exp
{
Trace("Reducing to [constant_declaration]\n");
}
| CONST IDENTIFIER COLONEQUALS MINUS constant_exp
{
Trace("Reducing to [constant_declaration]\n");
}
;
variables_declaration:
VAR IDENTIFIER COLON type COLONEQUALS constant_exp { Trace("Reducing to [variables_declaration]\n");}
| VAR IDENTIFIER COLONEQUALS constant_exp { Trace("Reducing to [variables_declaration]\n");}
| VAR IDENTIFIER COLON type { Trace("Reducing to [variables_declaration]\n");}
;
arrays_declaration:
VAR IDENTIFIER COLON ARRAY INT_RANGE OF type { Trace("Reducing to [arrays_declaration]\n");}
;
statements:
blocks
|
simple
;
blocks:
BEGIN_KEYWORD program_units END
;
simple:
IDENTIFIER COLONEQUALS expression
|PUT expression
|GET IDENTIFIER
|RESULT expression OR RETURN
|EXIT
|EXIT WHEN bool_expression
|SKIP
;
expression:UMINUS
|MULTIPLY
|MOD
|DIVIDE
|LT
|LE
|EQUALS
|EG
|GT
|NOTEQUALS
|NOT
|AND
|OR
;
function_expression:
FUNCTION IDENTIFIER LP formal_arguments RP COLON type program_units END IDENTIFIER
;
procedure_expression:
PROCEDURE IDENTIFIER LP formal_arguments RP program_units END IDENTIFIER
formal_arguments:
formal_arguments COMMA formal_argument
| formal_argument
|
;
formal_argument: IDENTIFIER COLON type
{
Trace("Reducing to [formal_argument]\n");
};
bool_expression:
TRUEVAL
|FALSEVAL
;
unary_expression:
primary_expression
{
Trace("Reducing to [unary_expression]\n");
}
| MINUS primary_expression %prec UMINUS
{
Trace("Reducing to [unary_expression]\n");
}
;
multiplicative_expression:
unary_expression
{
Trace("Reducing to [multiplicative_expression]\n");
}
| multiplicative_expression MULTIPLY unary_expression
{
Trace("Reducing to [multiplicative_expression]\n");
}
| multiplicative_expression DIVIDE unary_expression
{
Trace("Reducing to [multiplicative_expression]\n");
}
;
primary_expression:
IDENTIFIER
{
Trace("Reducing to [primary_expression]\n");
}
| INTEGERVAL
{
Trace("Reducing to [primary_expression]\n");
}
| STRINGVAL
{
Trace("Reducing to [primary_expression]\n");
}
| FLOATVAL
{
Trace("Reducing to [primary_expression]\n");
}
| TRUEVAL
{
Trace("Reducing to [primary_expression]\n");
}
| FALSEVAL
{
Trace("Reducing to [primary_expression]\n");
}
| LP expression RP
{
Trace("Reducing to [primary_expression]\n");
}
;
condition:
condition AND simple_condition {Trace("Reducing to [condition]\n");}
| condition OR simple_condition {Trace("Reducing to [condition]\n");}
| simple_condition {Trace("Reducing to [simple_condition]\n");}
;
simple_condition:
NOT condition {Trace("Reducing to [simple_condition]\n");}
| comparison {Trace("Reducing to [simple_condition]\n");}
;
comparison:
expression EQ expression {Trace("Reducing to [comparison]\n");}
| expression NOTEQUALS expression {Trace("Reducing to [comparison]\n");}
| expression LT expression {Trace("Reducing to [comparison]\n");}
| expression LE expression {Trace("Reducing to [comparison]\n");}
| expression GT expression {Trace("Reducing to [comparison]\n");}
| expression GE expression {Trace("Reducing to [ comparison]\n");}
;
constant_exp:
INTEGERVAL
| STRINGVAL
| FLOATVAL
| TRUEVAL
| FALSEVAL
;
type: STRING
| BOOL
| REAL
| INT
;
%%
#include "lex.yy.c"
void yyerror(const char *msg)
{
fprintf(stderr, "%s\n", msg);
}
int main(int argc, char *argv[])
{
if(yyparse()){
yyerror("Parsing error !");
}
return 0;
}