Merge pull request #39 from UB-CSE443/Sprint3-Table_Restructure_Part2-FE-t#NoTask
New grammar formatting rules applied.
This commit is contained in:
497
src/grammar.y
497
src/grammar.y
@ -2,6 +2,19 @@
|
||||
/* 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"
|
||||
@ -29,8 +42,9 @@
|
||||
extern TableNode* boo;
|
||||
TableNode * tn;
|
||||
%}
|
||||
//%define api.location.type {location_t}
|
||||
|
||||
%locations
|
||||
|
||||
%union {
|
||||
int integ;
|
||||
char * words;
|
||||
@ -102,14 +116,14 @@
|
||||
%precedence DOT
|
||||
%precedence RESERVE RELEASE
|
||||
|
||||
|
||||
|
||||
%%
|
||||
|
||||
program:
|
||||
prototype_or_definition_list
|
||||
;
|
||||
|
||||
|
||||
|
||||
prototype_or_definition_list:
|
||||
prototype prototype_or_definition_list
|
||||
| definition prototype_or_definition_list
|
||||
@ -117,89 +131,120 @@ prototype_or_definition_list:
|
||||
| definition
|
||||
;
|
||||
|
||||
|
||||
|
||||
prototype:
|
||||
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
|
||||
|
||||
|
||||
|
||||
definition:
|
||||
TYPE ID COLON {
|
||||
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);}
|
||||
}
|
||||
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);
|
||||
{
|
||||
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);
|
||||
|
||||
| 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 {
|
||||
|
||||
| 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){
|
||||
} else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
}
|
||||
else {
|
||||
} 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);
|
||||
}
|
||||
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 {
|
||||
}
|
||||
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){
|
||||
} else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setStartLine(node, @1.first_line);
|
||||
setAsKeyword(node, true);
|
||||
}
|
||||
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))));
|
||||
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){
|
||||
} 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)){
|
||||
} 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 {
|
||||
ID
|
||||
{
|
||||
TableNode *entry = getFirstEntry(cur);
|
||||
while (strcmp(getName(entry),"undefined") != 0) {
|
||||
entry = getNextEntry(entry);
|
||||
@ -208,9 +253,14 @@ idlist:
|
||||
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 {
|
||||
}
|
||||
COMMA idlist
|
||||
{
|
||||
$$ = $<integ>4 + 1;
|
||||
}
|
||||
|
||||
| ID
|
||||
{
|
||||
TableNode *entry = getFirstEntry(cur);
|
||||
while (strcmp(getName(entry),"undefined") != 0) {
|
||||
entry = getNextEntry(entry);
|
||||
@ -225,19 +275,49 @@ idlist:
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
declaration_list:
|
||||
declaration SEMI_COLON declaration_list
|
||||
| declaration
|
||||
;
|
||||
|
||||
|
||||
|
||||
declaration:
|
||||
id_or_types COLON ID
|
||||
{
|
||||
@ -246,14 +326,23 @@ declaration:
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
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
|
||||
@ -261,12 +350,16 @@ 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");}
|
||||
| sblock
|
||||
;
|
||||
|
||||
|
||||
|
||||
simple_statement:
|
||||
assignable ASSIGN expression
|
||||
{
|
||||
@ -291,111 +384,191 @@ simple_statement:
|
||||
|
||||
| RETURN expression
|
||||
;
|
||||
rec_op :
|
||||
|
||||
|
||||
|
||||
rec_op:
|
||||
DOT
|
||||
|
||||
|
||||
|
||||
|
||||
/////////// VERIFIED UP UNTIL THIS POINT
|
||||
|
||||
// assignable needs more code- specifically for arrays, records and ablock checks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 {
|
||||
expression COMMA argument_list
|
||||
{
|
||||
CreateEntry(cur, look_up(cur, $1), "", NULL);
|
||||
$<integ>$ = $<integ>3 + 1;
|
||||
printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);}
|
||||
| expression {
|
||||
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>$);}
|
||||
$<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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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");}}
|
||||
{
|
||||
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;}
|
||||
| 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
|
||||
// add array case
|
||||
// include type check for ablock in arrays - ablock is always the int of the elements in array/rec
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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){
|
||||
if ((node->table) == NULL) {
|
||||
print_symbol_table(node->table, file_ptr);
|
||||
}else{
|
||||
if ((node->table)->Line_Number == -1){
|
||||
} else {
|
||||
if ((node->table)->Line_Number == -1) {
|
||||
continue;
|
||||
}else{
|
||||
print_symbol_table(node->table, file_ptr);
|
||||
} else {
|
||||
print_symbol_table(node->table,
|
||||
file_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user