init
This commit is contained in:
373
src/grammar.y~
Normal file
373
src/grammar.y~
Normal file
@ -0,0 +1,373 @@
|
||||
|
||||
/* Syntax Analyzer with Bison (3.8.2) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
%{
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
%type <words> assignable
|
||||
%type <words> expression
|
||||
%type <words> constant
|
||||
%type <words> id_or_types
|
||||
%type <words> types
|
||||
%token <words> ID 101
|
||||
%token <words> T_INTEGER 201
|
||||
%token <words> T_ADDRESS 202
|
||||
%token <words> T_BOOLEAN 203
|
||||
%token <words> T_CHARACTER 204
|
||||
%token <words> T_STRING 205
|
||||
%token <integ> C_INTEGER 301
|
||||
%token <words> C_NULL 302
|
||||
%token <words> C_CHARACTER 303
|
||||
%token <words> C_STRING 304
|
||||
%token <words> C_TRUE 305
|
||||
%token <words> 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), $<words>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), $<words>1)))), $<words>4, NULL);
|
||||
}R_PAREN ASSIGN sblock
|
||||
| ID {
|
||||
TableNode *node = table_lookup(getAncestor(cur), $<words>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), $<words>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, $<words>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, $<words>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", $<words>1, $<words>3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$<words>1),$<words>3,NULL); }
|
||||
;
|
||||
|
||||
id_or_types:
|
||||
ID {printf("string of id in id_or_type is %s\n",$<words>1); $$ = getType(look_up(cur,$1));}
|
||||
| types {printf("string of type in id_or_type is %s\n",$<words>1);} {$$ = $<words>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");} {$$ = $<words>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 {$<integ>$ = $<integ>2;} R_PAREN
|
||||
;
|
||||
|
||||
argument_list:
|
||||
expression COMMA argument_list {$<integ>$ = $<integ>3 + 1;}
|
||||
| expression {$<integ>$ = 1;}
|
||||
;
|
||||
|
||||
|
||||
memOp:
|
||||
RESERVE {printf("reserve expression\n");}
|
||||
| RELEASE {printf("release expression\n");}
|
||||
;
|
||||
|
||||
|
||||
constant:
|
||||
C_STRING {$$ = $<words>1;}
|
||||
| C_INTEGER {$$ = "integer";}
|
||||
| C_NULL {$$ = $<words>1;}
|
||||
| C_CHARACTER {$$ = $<words>1;}
|
||||
| C_TRUE {$$ = $<words>1;}
|
||||
| C_FALSE {$$ = $<words>1;}
|
||||
;
|
||||
|
||||
types:
|
||||
// Commented out T_String below
|
||||
// T_STRING {printf("string of T_STRING in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
T_INTEGER {printf("string of T_INTEGER in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$<words>1);} {$$ = $<words>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);
|
||||
}
|
Reference in New Issue
Block a user