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,6 +2,19 @@
/* Syntax Analyzer with Bison (3.8.2) */ /* Syntax Analyzer with Bison (3.8.2) */
/* The Translators - Spring 2025 */ /* 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 <stdio.h>
#include "../src/symbol_table.c" #include "../src/symbol_table.c"
@ -29,8 +42,9 @@
extern TableNode* boo; extern TableNode* boo;
TableNode * tn; TableNode * tn;
%} %}
//%define api.location.type {location_t}
%locations %locations
%union { %union {
int integ; int integ;
char * words; char * words;
@ -102,14 +116,14 @@
%precedence DOT %precedence DOT
%precedence RESERVE RELEASE %precedence RESERVE RELEASE
%% %%
program: program:
prototype_or_definition_list prototype_or_definition_list
; ;
prototype_or_definition_list: prototype_or_definition_list:
prototype prototype_or_definition_list prototype prototype_or_definition_list
| definition prototype_or_definition_list | definition prototype_or_definition_list
@ -117,89 +131,120 @@ prototype_or_definition_list:
| definition | definition
; ;
prototype: prototype:
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
definition: definition:
TYPE ID COLON { TYPE ID COLON
{
printdebug("Currently see a record definition for %s", $<words>2); printdebug("Currently see a record definition for %s", $<words>2);
tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0)));
if (table_lookup(getAncestor(cur), $2) == undefined) { if (table_lookup(getAncestor(cur), $2) == undefined) {
printdebug("rec not found "); printdebug("rec not found ");
} }
}dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); }
cur = getParent(cur);} dblock
{
setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur));
cur = getParent(cur);
}
| TYPE ID COLON C_INTEGER ARROW id_or_types | 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); 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))); CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));
printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6);
} }
| function_declaration | 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", | TYPE ID COLON id_or_types ARROW id_or_types
$2, $4, $6); {
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))); CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
} }
| ID {
| ID
{
TableNode *node = table_lookup(getAncestor(cur), $<words>1); TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) { if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
}else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} } else {
else {
setStartLine(node, @1.first_line); setStartLine(node, @1.first_line);
setAsKeyword(node, false); setAsKeyword(node, false);
} }
cur = CreateScope(cur, 0, 0); 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", L_PAREN ID
$1,$4); {
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); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1)))), $<words>4, NULL);
}R_PAREN ASSIGN sblock }
| ID { R_PAREN ASSIGN sblock
| ID
{
TableNode *node = table_lookup(getAncestor(cur), $<words>1); TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == undefined) { if (node == undefined) {
printdebug("null check"); printdebug("null check");
} }
if (node == undefined) { if (node == undefined) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
}else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
} } else {
else {
setStartLine(node, @1.first_line); setStartLine(node, @1.first_line);
setAsKeyword(node, true); setAsKeyword(node, true);
} }
cur = CreateScope(cur, 0, 0); cur = CreateScope(cur, 0, 0);
}AS L_PAREN { }
AS L_PAREN
{
TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1)))); TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1))));
printdebug("%s", getType(parameter)); printdebug("%s", getType(parameter));
if (parameter == undefined) { if (parameter == undefined) {
printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); 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){ } else if(getAdInfoType(parameter) != TYPE_RECORD) {
printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); 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); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column);
}else { } else {
for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) {
CreateEntry(cur, entry, NULL, NULL); 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_declaration:
FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} FUNCTION ID COLON ID
| EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} {
CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));
}
| EXTERNAL FUNCTION ID COLON ID
{
CreateEntry(cur, look_up(cur, $5), $3, NULL);
}
; ;
idlist: idlist:
ID { ID
{
TableNode *entry = getFirstEntry(cur); TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) { while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry); entry = getNextEntry(entry);
@ -208,9 +253,14 @@ idlist:
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
} }
addName(entry, $<words>1); addName(entry, $<words>1);
} COMMA idlist {$$ = $<integ>4 + 1;} }
| ID { COMMA idlist
{
$$ = $<integ>4 + 1;
}
| ID
{
TableNode *entry = getFirstEntry(cur); TableNode *entry = getFirstEntry(cur);
while (strcmp(getName(entry),"undefined") != 0) { while (strcmp(getName(entry),"undefined") != 0) {
entry = getNextEntry(entry); entry = getNextEntry(entry);
@ -225,19 +275,49 @@ idlist:
sblock: 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
| 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 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: dblock:
L_BRACKET declaration_list R_BRACKET; L_BRACKET declaration_list R_BRACKET;
declaration_list: declaration_list:
declaration SEMI_COLON declaration_list declaration SEMI_COLON declaration_list
| declaration | declaration
; ;
declaration: declaration:
id_or_types COLON ID id_or_types COLON ID
{ {
@ -246,14 +326,23 @@ declaration:
} }
; ;
id_or_types: id_or_types:
ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} ID
//{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 id is %s in ID 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;} }
;
| types
{
printdebug("string of type is %s in types pattern of id_or_type rule.",$1);
$$ = $1;
}
; ;
statement_list: statement_list:
compound_statement statement_list compound_statement statement_list
| compound_statement | compound_statement
@ -261,12 +350,16 @@ statement_list:
| simple_statement SEMI_COLON | simple_statement SEMI_COLON
; ;
compound_statement: compound_statement:
WHILE L_PAREN expression R_PAREN sblock WHILE L_PAREN expression R_PAREN sblock
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
| sblock //{printdebug("seen a compound statement rule");} | sblock
; ;
simple_statement: simple_statement:
assignable ASSIGN expression assignable ASSIGN expression
{ {
@ -291,111 +384,191 @@ simple_statement:
| RETURN expression | RETURN expression
; ;
rec_op :
rec_op:
DOT DOT
/////////// VERIFIED UP UNTIL THIS POINT
// assignable needs more code- specifically for arrays, records and ablock checks
ablock: 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: argument_list:
expression COMMA argument_list { expression COMMA argument_list
{
CreateEntry(cur, look_up(cur, $1), "", NULL); CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = $<integ>3 + 1; $<integ>$ = $<integ>3 + 1;
printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);} printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
| expression { }
| expression
{
CreateEntry(cur, look_up(cur, $1), "", NULL); CreateEntry(cur, look_up(cur, $1), "", NULL);
$<integ>$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);} $<integ>$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
}
; ;
// will ALWAYS be a TYPE // will ALWAYS be a TYPE
expression: 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) | SUB_OR_NEG expression %prec UMINUS
{printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); {
$$=strdup("undefined");}else{$$=$2;}} 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"); | NOT expression
printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", {
@1.first_line,@1.first_column,$2);}} 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 | 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.", printdebug("add expression");
@2.first_line,@2.first_column,$1,$3); if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("undefined");}} $$=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 | 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.", printdebug("sub or neg expression");
@2.first_line,@2.first_column,$1,$3); if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
$$=strdup("undefined");}} $$=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 | expression MUL expression
{printdebug("multiply expression"); {
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} printdebug("multiply expression");
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
@2.first_line,@2.first_column,$1,$3); $$=strdup("integer");
$$=strdup("undefined");}} } 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 | 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.", printdebug("divide expression");
@2.first_line,@2.first_column,$1,$3); if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("undefined");}} $$=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 | 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.", printdebug("remainder expression");
@2.first_line,@2.first_column,$1,$3); if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
$$=strdup("undefined");}} $$=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 | 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.", printdebug("AND expression");
@2.first_line,@2.first_column,$1,$3); if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
$$=strdup("undefined");}} $$=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 | expression OR expression
{printdebug("OR");if(strcmp($1,$3)==0 && {
strcmp($1,"Boolean")==0){$$=strdup("Boolean");} printdebug("OR");
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
@2.first_line,@2.first_column,$1,$3); $$=strdup("Boolean");
$$=strdup("undefined");}} } 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 | expression LESS_THAN expression
{printdebug("less than expression");if(strcmp($1,$3)==0 && {
strcmp($1,"integer")==0){$$=strdup("Boolean");} printdebug("less than expression");
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
@2.first_line,@2.first_column,$1,$3); $$=strdup("Boolean");
$$=strdup("undefined");}} } 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"); | expression EQUAL_TO expression
if(strcmp($1,$3)==0){$$=strdup("Boolean");} {
//else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| printdebug("equals check expression");
// strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} if(strcmp($1,$3)==0) {
else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", $$=strdup("Boolean");
@2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} } 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;} | L_PAREN expression R_PAREN
{
printdebug("paren expression. current type is %s",$2);
$$=$2;
}
| memOp assignable
{
$$ = strdup("address");
}
| memOp assignable {$$ = strdup("address");}
; ;
// prolly right, check back with me later // prolly right, check back with me later
// add array case // add array case
// include type check for ablock in arrays - ablock is always the int of the elements in array/rec // include type check for ablock in arrays - ablock is always the int of the elements in array/rec
@ -403,13 +576,16 @@ assignable:
ID ID
{ {
$$ = getType(look_up(cur,$1)); $$ = 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 | assignable
{ {
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
cur = CreateScope(cur, -1,-1); cur = CreateScope(cur, -1,-1);
} }
ablock { ablock
{
int type = getAdInfoType(look_up(getParent(cur), $1)); int type = getAdInfoType(look_up(getParent(cur), $1));
printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%stype is %d", COLOR_PURPLE, type);
@ -435,7 +611,6 @@ assignable:
} }
lastCheckedRef = tn; lastCheckedRef = tn;
} }
} else { } else {
char *expected = getName(getParameter(look_up(getParent(cur), $1))); char *expected = getName(getParameter(look_up(getParent(cur), $1)));
char *actual = getType(getFirstEntry(cur)); 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); 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))); $$ = getName(getReturn(table_lookup(getAncestor(cur), $1)));
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $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) { 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); 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))); $$ = getName(getArrType(look_up(getParent(cur), $1)));
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);
} }
cur = getParent(cur); cur = getParent(cur);
} }
| assignable rec_op ID | assignable rec_op ID
{ {
if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { 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); printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);
} }
; ;
memOp: memOp:
RESERVE {printdebug("reserve expression");} RESERVE
| RELEASE {printdebug("release expression");} {
printdebug("reserve expression");
}
| RELEASE
{
printdebug("release expression");
}
; ;
constant: constant:
C_STRING {$$ = $<words>1; printdebug("string of C_STRING in constant is %s",$<words>1);} C_STRING
| 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);} $$ = $<words>1;
| C_CHARACTER {$$ = $<words>1; printdebug("string of C_CHARACTER in constant is %s",$<words>1);} printdebug("string of C_STRING 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_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: types:
// Commented out T_String below T_INTEGER
// 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;} $$ = $1;
| T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$<words>1);} {$$ = $1;} printdebug("string of T_INTEGER in types is %s",$<words>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_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) { 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

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

0
test
View File