From 982a8a045424cd402ff78aff152513f991100ead Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 18:22:05 -0400 Subject: [PATCH] init --- src/grammar.y~ | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 src/grammar.y~ diff --git a/src/grammar.y~ b/src/grammar.y~ new file mode 100644 index 0000000..5238aac --- /dev/null +++ b/src/grammar.y~ @@ -0,0 +1,373 @@ + +/* Syntax Analyzer with Bison (3.8.2) */ +/* The Translators - Spring 2025 */ + +%{ + #include + #include "../src/symbol_table.c" + #include + 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; +} + + +%type assignable +%type expression +%type constant +%type id_or_types +%type types +%token ID 101 +%token T_INTEGER 201 +%token T_ADDRESS 202 +%token T_BOOLEAN 203 +%token T_CHARACTER 204 +%token T_STRING 205 +%token C_INTEGER 301 +%token C_NULL 302 +%token C_CHARACTER 303 +%token C_STRING 304 +%token C_TRUE 305 +%token C_FALSE 306 +%token WHILE 401 +%token IF 402 +%token THEN 403 +%token ELSE 404 +%token TYPE 405 +%token FUNCTION 406 +%token RETURN 407 +%token EXTERNAL 408 +%token AS 409 +%token L_PAREN 501 +%token R_PAREN 502 +%token L_BRACKET 503 +%token R_BRACKET 504 +%token L_BRACE 505 +%token R_BRACE 506 +%token SEMI_COLON 507 +%token COLON 508 +%token COMMA 509 +%token ARROW 510 +%token MUL 603 +%token DIV 604 +%token REM 605 +%token ADD 601 +%token LESS_THAN 606 +%token EQUAL_TO 607 +%token AND 610 +%token OR 611 +%token ASSIGN 608 +%token SUB_OR_NEG 602 +%token NOT 609 +%token DOT 612 +%token RESERVE 613 +%token RELEASE 614 +%token COMMENT 700 + +//precedence order +%left ASSIGN +%left OR +%left AND +%left EQUAL_TO +%left LESS_THAN +%left ADD SUB_OR_NEG +%left MUL DIV REM +%precedence NOT +%precedence UMINUS +%precedence DOT +%precedence RESERVE RELEASE + + + +%% + +program: + prototype_or_definition_list + ; + +prototype_or_definition_list: + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; + +prototype: + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + +definition: +TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == NULL) { + printf("rec not found \n"); + } + }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur);} + | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + | function_declaration + | TYPE ID COLON id_or_types ARROW id_or_types { + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + } + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL) { + printf("null check\n"); + } + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + }AS L_PAREN { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + CreateEntry(cur, entry, NULL, NULL); + } + } + } idlist 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);} + ; + + +idlist: + ID { + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } COMMA idlist + | ID { + + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $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 + {printf("seen sblock with dblock\n");} 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 {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; + +id_or_types: + ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} + | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} + ; + +statement_list: + 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 //{printf("seen a compound statement rule\n");} + ; + +simple_statement: + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + }} + + | RETURN expression + ; + +assignable: + ID {$$ = getType(look_up(cur,$1));} + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ + {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} + ; + +rec_op : + DOT + +expression: + constant {printf("constant expression\n");} {$$ = $1;} + + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) + {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("undefined");}else{$$=$2;}} + + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + @1.first_line,@1.first_column,$2);}} + + | expression ADD expression + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression SUB_OR_NEG expression + {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression MUL expression + {printf("multiply expression\n"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression DIV expression + {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression REM expression + {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression AND expression + {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression OR expression + {printf("OR\n");if(strcmp($1,$3)==0 && + strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression LESS_THAN expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression EQUAL_TO expression {printf("equals check expression\n"); + 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{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} + + | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} + + | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} + + | memOp assignable {$$ = strdup("address");} + ; + + +ablock: +L_PAREN argument_list {$$ = $2;} R_PAREN + ; + +argument_list: +expression COMMA argument_list {$$ = $3 + 1;} +| expression {$$ = 1;} + ; + + +memOp: + RESERVE {printf("reserve expression\n");} + | RELEASE {printf("release expression\n");} + ; + + +constant: + C_STRING {$$ = $1;} + | C_INTEGER {$$ = "integer";} + | C_NULL {$$ = $1;} + | C_CHARACTER {$$ = $1;} + | C_TRUE {$$ = $1;} + | C_FALSE {$$ = $1;} + ; + +types: + // Commented out T_String below + // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} + | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} + | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + ; + +%% + +void yyerror(const char *err) { + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); +}