Merge pull request #39 from UB-CSE443/Sprint3-Table_Restructure_Part2-FE-t#NoTask

New grammar formatting rules applied.
This commit is contained in:
scarlett
2025-04-03 16:43:33 -04:00
committed by GitHub
4 changed files with 535 additions and 297 deletions

View File

@ -2,38 +2,52 @@
/* Syntax Analyzer with Bison (3.8.2) */
/* The Translators - Spring 2025 */
// ----- THIS FILE MUST BE FORMATTED CORRECTLY FOR READABILITY ----- //
// ✏️ FORMATTING RULES:
// 1⃣ Use 4 spaces for indentation.
// 2⃣ Grammar rules (terminals and nonterminals) should always be on their own line.
// 3⃣ Grammar rules and C-blocks should always begin 8 spaces in.
// 4⃣ Rule end-markers (;, |) should always be 4 spaces in.
// 5⃣ C-blocks should always be clearly defined and follow clang formatting rules.
// 6⃣ 1-line if/for/while statements must be wrapped in curly braces.
// 7⃣ DO NOT USE TABS. EVER.
// Please ask Scarlett if you are unsure of how to format something. Thanks! 😀
%{
#include <stdio.h>
#include "../src/symbol_table.c"
#include <math.h>
extern int yylex(void);
void yyerror(const char *err);
extern char* yytext;
extern int yyleng;
extern int yychar;
extern SymbolTable * cur;
//char* cur_value;
//char* cur_type;
int token_tracker;
extern int line_number;
extern int column_number;
extern FILE * yyin;
extern TableNode* funprime;
extern TableNode* arrayprim;
extern TableNode* recprime;
extern TableNode* funtypeprime;
extern TableNode* integ;
extern TableNode* addr;
extern TableNode* chara;
extern TableNode* stri;
extern TableNode* boo;
TableNode * tn;
#include <stdio.h>
#include "../src/symbol_table.c"
#include <math.h>
extern int yylex(void);
void yyerror(const char *err);
extern char* yytext;
extern int yyleng;
extern int yychar;
extern SymbolTable * cur;
//char* cur_value;
//char* cur_type;
int token_tracker;
extern int line_number;
extern int column_number;
extern FILE * yyin;
extern TableNode* funprime;
extern TableNode* arrayprim;
extern TableNode* recprime;
extern TableNode* funtypeprime;
extern TableNode* integ;
extern TableNode* addr;
extern TableNode* chara;
extern TableNode* stri;
extern TableNode* boo;
TableNode * tn;
%}
//%define api.location.type {location_t}
%locations
%union {
int integ;
char * words;
int integ;
char * words;
}
%type <integ> idlist
@ -102,174 +116,253 @@
%precedence DOT
%precedence RESERVE RELEASE
%%
program:
prototype_or_definition_list
;
prototype_or_definition_list
;
prototype_or_definition_list:
prototype prototype_or_definition_list
| definition prototype_or_definition_list
| prototype
| definition
;
prototype prototype_or_definition_list
| definition prototype_or_definition_list
| prototype
| definition
;
prototype:
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
definition:
TYPE ID COLON {
printdebug("Currently see a record definition for %s", $<words>2);
tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0)));
if (table_lookup(getAncestor(cur), $2) == undefined) {
printdebug("rec not found ");
}
}dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur));
cur = getParent(cur);}
| TYPE ID COLON C_INTEGER ARROW id_or_types
{printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d",
$2, $6, $4);
CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));
printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6);
TYPE ID COLON
{
printdebug("Currently see a record definition for %s", $<words>2);
tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0)));
if (table_lookup(getAncestor(cur), $2) == undefined) {
printdebug("rec not found ");
}
}
| function_declaration
| TYPE ID COLON id_or_types ARROW id_or_types {
printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s",
$2, $4, $6);
CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
dblock
{
setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur));
cur = getParent(cur);
}
| ID {
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
}else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
| TYPE ID COLON C_INTEGER ARROW id_or_types
{
printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4);
CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));
printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6);
}
| function_declaration
| TYPE ID COLON id_or_types ARROW id_or_types
{
printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6);
CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
}
| ID
{
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} else {
setStartLine(node, @1.first_line);
setAsKeyword(node, false);
}
cur = CreateScope(cur, 0, 0);
}
L_PAREN ID
{
printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4);
CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1)))), $<words>4, NULL);
}
R_PAREN ASSIGN sblock
| ID
{
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) {
printdebug("null check");
}
if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} else {
setStartLine(node, @1.first_line);
setAsKeyword(node, true);
}
cur = CreateScope(cur, 0, 0);
}
AS L_PAREN
{
TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1))));
printdebug("%s", getType(parameter));
if (parameter == undefined) {
printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column);
} else if(getAdInfoType(parameter) != TYPE_RECORD) {
printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime));
printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column);
} else {
for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) {
CreateEntry(cur, entry, NULL, NULL);
}
else {
setStartLine(node, @1.first_line);
setAsKeyword(node, false);
}
cur = CreateScope(cur, 0, 0);
} L_PAREN ID {
printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s",
$1,$4);
CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1)))), $<words>4, NULL);
}R_PAREN ASSIGN sblock
| ID {
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) {
printdebug("null check");
}
if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
}else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
}
else {
setStartLine(node, @1.first_line);
setAsKeyword(node, true);
}
cur = CreateScope(cur, 0, 0);
}AS L_PAREN {
TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1))));
printdebug("%s", getType(parameter));
if (parameter == undefined) {
printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column);
}else if(getAdInfoType(parameter) != TYPE_RECORD){
printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime));
printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column);
}else {
for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){
CreateEntry(cur, entry, NULL, NULL);
}
}
} idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d",
$1,$6);} R_PAREN ASSIGN sblock
;
}
}
idlist
{
printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6);
}
R_PAREN ASSIGN sblock
;
function_declaration:
FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));}
| EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);}
;
FUNCTION ID COLON ID
{
CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));
}
| EXTERNAL FUNCTION ID COLON ID
{
CreateEntry(cur, look_up(cur, $5), $3, NULL);
}
;
idlist:
ID {
TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) == NULL) {
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
} COMMA idlist {$$ = $<integ>4 + 1;}
| ID {
ID
{
TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) == NULL) {
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
}
COMMA idlist
{
$$ = $<integ>4 + 1;
}
TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) != NULL) {
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
$$ = 1;
}
;
| ID
{
TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) != NULL) {
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
$$ = 1;
}
;
sblock:
L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE
| L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock
{printdebug("seen sblock with dblock");} statement_list {cur = getParent(cur);} R_BRACE
;
L_BRACE
{
if (getLine(cur) != 0 && getColumn(cur)) {
cur = CreateScope(cur,@1.first_line,@1.first_column);
}
}
statement_list
{
cur = getParent(cur);
}
R_BRACE
| L_BRACE
{
if (getLine(cur) != 0 && getColumn(cur)) {
cur = CreateScope(cur,@1.first_line,@1.first_column);
}
}
dblock
{
printdebug("seen sblock with dblock");
}
statement_list
{
cur = getParent(cur);
}
R_BRACE
;
dblock:
L_BRACKET declaration_list R_BRACKET;
L_BRACKET declaration_list R_BRACKET;
declaration_list:
declaration SEMI_COLON declaration_list
| declaration
;
declaration SEMI_COLON declaration_list
| declaration
;
declaration:
id_or_types COLON ID
id_or_types COLON ID
{
printdebug("ID/TYPE: %s, ID: %s", $<words>1, $<words>3) ;
CreateEntry(cur,table_lookup(getAncestor(cur),$<words>1),$<words>3,NULL);
}
;
id_or_types:
ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;}
//{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));}
| types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;}
//{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$<words>1);} {$$ = $<words>1;}
;
;
ID
{
printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;
}
| types
{
printdebug("string of type is %s in types pattern of id_or_type rule.",$1);
$$ = $1;
}
;
statement_list:
compound_statement statement_list
| compound_statement
| simple_statement SEMI_COLON statement_list
| simple_statement SEMI_COLON
;
compound_statement statement_list
| compound_statement
| simple_statement SEMI_COLON statement_list
| simple_statement SEMI_COLON
;
compound_statement:
WHILE L_PAREN expression R_PAREN sblock
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
| sblock //{printdebug("seen a compound statement rule");}
;
WHILE L_PAREN expression R_PAREN sblock
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
| sblock
;
simple_statement:
assignable ASSIGN expression
{
assignable ASSIGN expression
{
if(strcmp($1, $3) == 0) {
printdebug("Passed standard type check; assignable = expression");
} else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) {
@ -287,114 +380,194 @@ simple_statement:
printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE);
printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1)));
}
}
}
| RETURN expression
;
rec_op :
DOT
| RETURN expression
;
/////////// VERIFIED UP UNTIL THIS POINT
// assignable needs more code- specifically for arrays, records and ablock checks
rec_op:
DOT
ablock:
L_PAREN argument_list R_PAREN {$<integ>$ = $<integ>2; printdebug("ablock is %d", $<integ>$);}
;
L_PAREN argument_list R_PAREN
{
$<integ>$ = $<integ>2;
printdebug("ablock is %d", $<integ>$);
}
;
argument_list:
expression COMMA argument_list {
CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = $<integ>3 + 1;
printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);}
| expression {
CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);}
;
expression COMMA argument_list
{
CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = $<integ>3 + 1;
printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
}
| expression
{
CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
}
;
// will ALWAYS be a TYPE
expression:
constant {printdebug("constant expression");} {$$ = $<words>1;}
constant
{
printdebug("constant expression");
$$ = $<words>1;
}
| SUB_OR_NEG expression %prec UMINUS {printdebug("negative expression");if(strcmp($2,"integer") != 0)
{printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column);
$$=strdup("undefined");}else{$$=$2;}}
| SUB_OR_NEG expression %prec UMINUS
{
printdebug("negative expression");
if(strcmp($2,"integer") != 0) {
printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column);
$$=strdup("undefined");
} else {
$$=$2;
}
}
| NOT expression {printdebug("not expression"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined");
printdebug("mismatch at line %d and column %d. Invalid type being negated is %s",
@1.first_line,@1.first_column,$2);}}
| NOT expression
{
printdebug("not expression");
if(strcmp($2,"Boolean")==0) {
$$=$2;
} else {
$$=strdup("undefined");
printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2);
}
}
| expression ADD expression
{printdebug("add expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression ADD expression
{
printdebug("add expression");
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("integer");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression SUB_OR_NEG expression
{printdebug("sub or neg expression");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression SUB_OR_NEG expression
{
printdebug("sub or neg expression");
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
$$=strdup("integer");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression MUL expression
{printdebug("multiply expression");
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression MUL expression
{
printdebug("multiply expression");
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
$$=strdup("integer");
} else{
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression DIV expression
{printdebug("divide expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression DIV expression
{
printdebug("divide expression");
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("integer");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression REM expression
{printdebug("remainder expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression REM expression
{
printdebug("remainder expression");
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("integer");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression AND expression
{printdebug("AND expression");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression AND expression
{
printdebug("AND expression");
if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
$$=strdup("Boolean");
} else{
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression OR expression
{printdebug("OR");if(strcmp($1,$3)==0 &&
strcmp($1,"Boolean")==0){$$=strdup("Boolean");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression OR expression
{
printdebug("OR");
if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
$$=strdup("Boolean");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression LESS_THAN expression
{printdebug("less than expression");if(strcmp($1,$3)==0 &&
strcmp($1,"integer")==0){$$=strdup("Boolean");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression LESS_THAN expression
{
printdebug("less than expression");
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("Boolean");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| expression EQUAL_TO expression {printdebug("equals check expression");
if(strcmp($1,$3)==0){$$=strdup("Boolean");}
//else if((strcmp($1,"array")==0||strcmp($1,"record")==0||
// strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");}
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s",
@2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}}
| expression EQUAL_TO expression
{
printdebug("equals check expression");
if(strcmp($1,$3)==0) {
$$=strdup("Boolean");
} else {
printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");
}
}
| assignable {printdebug("assignable expression. current type is %s",$1);$$=$1;}
| assignable
{
printdebug("assignable expression. current type is %s",$1);
$$=$1;
}
| L_PAREN expression R_PAREN
{
printdebug("paren expression. current type is %s",$2);
$$=$2;
}
| memOp assignable
{
$$ = strdup("address");
}
;
| L_PAREN expression R_PAREN {printdebug("paren expression. current type is %s",$2);$$=$2;}
| memOp assignable {$$ = strdup("address");}
;
// prolly right, check back with me later
// add array case
@ -403,13 +576,16 @@ assignable:
ID
{
$$ = getType(look_up(cur,$1));
printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);}
printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);
}
| assignable
{
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
cur = CreateScope(cur, -1,-1);
}
ablock {
ablock
{
int type = getAdInfoType(look_up(getParent(cur), $1));
printdebug("%stype is %d", COLOR_PURPLE, type);
@ -435,7 +611,6 @@ assignable:
}
lastCheckedRef = tn;
}
} else {
char *expected = getName(getParameter(look_up(getParent(cur), $1)));
char *actual = getType(getFirstEntry(cur));
@ -443,6 +618,7 @@ assignable:
printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column);
}
}
$$ = getName(getReturn(table_lookup(getAncestor(cur), $1)));
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);
@ -451,16 +627,12 @@ assignable:
if (getNumArrDim(look_up(getParent(cur), $1)) != $<integ>2) {
printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $<integ>2, @2.first_line, @2.first_column);
}
// for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) {
// if (strcmp(getName(tn), "integer") != 0) {
// printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column);
// }
// }
$$ = getName(getArrType(look_up(getParent(cur), $1)));
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);
}
cur = getParent(cur);
}
| assignable rec_op ID
{
if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) {
@ -468,34 +640,97 @@ assignable:
}
printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);
}
;
memOp:
RESERVE {printdebug("reserve expression");}
| RELEASE {printdebug("release expression");}
;
RESERVE
{
printdebug("reserve expression");
}
| RELEASE
{
printdebug("release expression");
}
;
constant:
C_STRING {$$ = $<words>1; printdebug("string of C_STRING in constant is %s",$<words>1);}
| C_INTEGER {$$ = "integer"; printdebug("string of C_INTEGER in constant is integer");}
| C_NULL {$$ = $<words>1; printdebug("string of C_NULL in constant is %s",$<words>1);}
| C_CHARACTER {$$ = $<words>1; printdebug("string of C_CHARACTER in constant is %s",$<words>1);}
| C_TRUE {$$ = $<words>1; printdebug("string of C_TRUE in constant is %s",$<words>1);}
| C_FALSE {$$ = $<words>1; printdebug("string of C_FALSE in constant is %s",$<words>1);}
;
C_STRING
{
$$ = $<words>1;
printdebug("string of C_STRING in constant is %s",$<words>1);
}
| C_INTEGER
{
$$ = "integer";
printdebug("string of C_INTEGER in constant is integer");
}
| C_NULL
{
$$ = $<words>1;
printdebug("string of C_NULL in constant is %s",$<words>1);
}
| C_CHARACTER
{
$$ = $<words>1;
printdebug("string of C_CHARACTER in constant is %s",$<words>1);
}
| C_TRUE
{
$$ = $<words>1;
printdebug("string of C_TRUE in constant is %s",$<words>1);
}
| C_FALSE
{
$$ = $<words>1;
printdebug("string of C_FALSE in constant is %s",$<words>1);
}
;
types:
// Commented out T_String below
// T_STRING {printdebug("string of T_STRING in types is %s",$<words>1);} {$$ = $<words>1;}
T_INTEGER {printdebug("string of T_INTEGER in types is %s",$<words>1);} {$$ = $1;}
| T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$<words>1);} {$$ = $1;}
| T_CHARACTER {printdebug("string of T_CHARACTER in types is %s",$<words>1);} {$$ = $1;}
| T_BOOLEAN {printdebug("string of T_BOOLEAN in types is %s",$<words>1);} {$$ = $1;}
;
T_INTEGER
{
$$ = $1;
printdebug("string of T_INTEGER in types is %s",$<words>1);
}
| T_ADDRESS
{
$$ = $1;
printdebug("string of T_ADDRESS in types is %s",$<words>1);
}
| T_CHARACTER
{
$$ = $1;
printdebug("string of T_CHARACTER in types is %s",$<words>1);
}
| T_BOOLEAN
{
$$ = $1;
printdebug("string of T_BOOLEAN in types is %s",$<words>1);
}
;
%%
void yyerror(const char *err) {
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column);
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column);
}

View File

@ -5,25 +5,25 @@
%option header-file="flex.h"
%option yylineno
%{
#include <stdbool.h>
#include "../tmp/grammar.tab.h"
#include "../src/symbol_table.h"
#ifndef DEBUG
#define DEBUG 0
#endif
extern SymbolTable * cur;
extern FILE* tok_flag;
extern void incr(int lnum,int cnum, int tok);
extern void print_tok(int tok);
#include <stdbool.h>
#include "../tmp/grammar.tab.h"
#include "../src/symbol_table.h"
#ifndef DEBUG
#define DEBUG 0
#endif
extern SymbolTable * cur;
extern FILE* tok_flag;
extern void incr(int lnum,int cnum, int tok);
extern void print_tok(int tok);
int line_number = 1, column_number = 1;
int yycolumn = 1;
#define YY_USER_ACTION { \
yylloc.first_line = yylineno; \
yylloc.last_line = yylineno; \
yylloc.first_column = yycolumn; \
yylloc.last_column = yycolumn + yyleng - 1; \
yycolumn += yyleng; }
int line_number = 1, column_number = 1;
int yycolumn = 1;
#define YY_USER_ACTION { \
yylloc.first_line = yylineno; \
yylloc.last_line = yylineno; \
yylloc.first_column = yycolumn; \
yylloc.last_column = yycolumn + yyleng - 1; \
yycolumn += yyleng; }
%}
STARCOM [^\*]|\*+[^\)\*]+

View File

@ -66,7 +66,8 @@ typedef enum {
// TYPE_ADDRESS,
// Type String is an array of char enclosed in double quotes per lexer
TYPE_STRING = 1,
// Array can be multidimensional. Information should be stored here. This is the type of the array
// Array can be multidimensional. Information should be stored here.
// This is the type of the array
TYPE_ARRAY_TYPE = 2,
// Record is user defined types
TYPE_RECORD_TYPE = 3,
@ -513,8 +514,9 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) {
// types
SymbolTable *init(SymbolTable *start) {
if (start->Parent_Scope != NULL) {
printdebug(
"%s[FATAL] Cannot initialize a scope that is not the parent scope", COLOR_RED);
printdebug("%s[FATAL] Cannot initialize a scope that is not "
"the parent scope",
COLOR_RED);
return NULL;
}
integ = (TableNode *)calloc(1, sizeof(TableNode));
@ -707,15 +709,15 @@ int getAdInfoType(TableNode *tn) {
if (strcmp(getName(tn), getName(undefined)) == 0) {
return TYPE_UNDEFINED;
} else {
if(strcmp(getType(tn), getName(funtypeprime))==0){
if (strcmp(getType(tn), getName(funtypeprime)) == 0) {
printdebug("passed in a function to getAdInfoType");
return TYPE_FUNCTION_DECLARATION;
}
if(strcmp(getType(tn), getName(arrayprim))==0){
if (strcmp(getType(tn), getName(arrayprim)) == 0) {
printdebug("passed in an array to getAdInfoType");
return TYPE_ARRAY_TYPE;
}
if(strcmp(getType(tn), getName(recprime))==0){
if (strcmp(getType(tn), getName(recprime)) == 0) {
printdebug("passed in a record to getAdInfoType");
return TYPE_RECORD;
}
@ -1139,13 +1141,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) {
if (getChildren(table) != NULL) {
ListOfTable *node = getChildren(table);
for (; node != NULL; node = node->next) {
if((node->table) == NULL){
print_symbol_table(node->table, file_ptr);
}else{
if ((node->table)->Line_Number == -1){
continue;
}else{
print_symbol_table(node->table, file_ptr);
if ((node->table) == NULL) {
print_symbol_table(node->table, file_ptr);
} else {
if ((node->table)->Line_Number == -1) {
continue;
} else {
print_symbol_table(node->table,
file_ptr);
}
}
}

0
test
View File