Merge pull request #36 from UB-CSE443/Sprint3-Symbol_Table_Restructure-FE-t#NoTask
Sprint3 symbol table restructure fe t#no task
This commit is contained in:
3
Makefile
3
Makefile
@ -41,9 +41,8 @@ test-s1:
|
||||
|
||||
test-s2:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) -tok $(test);)
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);)
|
||||
./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) $(test);)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
|
19
check.sh
19
check.sh
@ -5,6 +5,11 @@
|
||||
# The Translators - Spring 2025 #
|
||||
|
||||
TOK_DIR="out"
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
WHITE='\033[0m'
|
||||
PURPLE='\033[0;35m'
|
||||
ORANGE='\033[0;33m'
|
||||
|
||||
if [[ ! -d "$TOK_DIR" ]]; then
|
||||
echo "Directory $TOK_DIR does not exist."
|
||||
@ -19,9 +24,15 @@ for file in "$TOK_DIR"/*; do
|
||||
exp="./tests/sprint$num/expected/$filename.expected"
|
||||
|
||||
if [[ -f "$exp" ]]; then
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "Checking $file...\n"
|
||||
diff --color=always "$file" "$exp"
|
||||
echo -e "--------------------------------------------\n"
|
||||
diff -q "$file" "$exp" > /dev/null
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed."
|
||||
else
|
||||
echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value..."
|
||||
diff --color=always "$file" "$exp"
|
||||
echo -e ""
|
||||
fi
|
||||
else
|
||||
echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value."
|
||||
fi
|
||||
done
|
127
src/grammar.y
127
src/grammar.y
@ -2,21 +2,30 @@
|
||||
/* 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;
|
||||
#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;
|
||||
%}
|
||||
//%define api.location.type {location_t}
|
||||
%locations
|
||||
@ -26,6 +35,9 @@
|
||||
}
|
||||
|
||||
|
||||
%type <words> assignable
|
||||
%type <words> expression
|
||||
%type <words> constant
|
||||
%type <words> id_or_types
|
||||
%type <words> types
|
||||
%token <words> ID 101
|
||||
@ -34,7 +46,7 @@
|
||||
%token <words> T_BOOLEAN 203
|
||||
%token <words> T_CHARACTER 204
|
||||
%token <words> T_STRING 205
|
||||
%token <integ> C_INTEGER 301
|
||||
%token <words> C_INTEGER 301
|
||||
%token <words> C_NULL 302
|
||||
%token <words> C_CHARACTER 303
|
||||
%token <words> C_STRING 304
|
||||
@ -110,7 +122,9 @@ definition:
|
||||
TYPE ID COLON dblock
|
||||
| TYPE ID COLON constant ARROW ID
|
||||
| function_declaration
|
||||
| TYPE ID COLON id_or_types ARROW id_or_types
|
||||
| TYPE ID COLON id_or_types ARROW id_or_types {
|
||||
CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
|
||||
}
|
||||
| ID parameter ASSIGN sblock
|
||||
;
|
||||
|
||||
@ -143,7 +157,7 @@ declaration_list:
|
||||
;
|
||||
|
||||
declaration:
|
||||
id_or_types COLON ID {CreateEntry(cur,$<words>1,$<words>3); }
|
||||
id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$<words>1),$<words>3,NULL); }
|
||||
;
|
||||
|
||||
id_or_types:
|
||||
@ -179,23 +193,33 @@ rec_op :
|
||||
DOT
|
||||
|
||||
expression:
|
||||
|
||||
constant {printf("constant expression\n");}
|
||||
| SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");}
|
||||
| NOT expression {printf("not expression\n");}
|
||||
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\n",@1.first_line,@1.first_column);}}
|
||||
| expression ADD expression {printf("add expression\n");}
|
||||
| expression SUB_OR_NEG expression {printf("subtract expression\n");}
|
||||
| expression MUL expression {printf("multiply expression\n");}
|
||||
| expression DIV expression {printf("division expression\n");}
|
||||
| expression REM expression {printf("remainder expression\n");}
|
||||
|
||||
| expression AND expression {printf("and expression\n");}
|
||||
|
||||
| expression OR expression {printf("or expression\n");}
|
||||
| expression LESS_THAN expression {printf("less than expression\n");}
|
||||
| expression EQUAL_TO expression {printf("equals check expression\n");}
|
||||
| assignable {printf("assignable expression\n");}
|
||||
| L_PAREN expression R_PAREN {printf("paren expression\n");}
|
||||
| memOp assignable
|
||||
;
|
||||
|
||||
| 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\n",@2.first_line,@2.first_column);
|
||||
$$=strdup("Boolean");$$=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\n",@2.first_line,@2.first_column);$$=strdup("undefined");}}
|
||||
| assignable {printf("assignable expression\n");$$=$1;}
|
||||
| L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;}
|
||||
| memOp assignable {$$ = strdup("address");}
|
||||
;
|
||||
|
||||
|
||||
ablock:
|
||||
@ -215,17 +239,18 @@ memOp:
|
||||
|
||||
|
||||
constant:
|
||||
C_STRING
|
||||
| C_INTEGER
|
||||
| C_NULL
|
||||
| C_CHARACTER
|
||||
| C_TRUE
|
||||
| C_FALSE
|
||||
C_STRING {$$ = $<words>1;}
|
||||
| C_INTEGER {$$ = $<words>1;}
|
||||
| C_NULL {$$ = $<words>1;}
|
||||
| C_CHARACTER {$$ = $<words>1;}
|
||||
| C_TRUE {$$ = $<words>1;}
|
||||
| C_FALSE {$$ = $<words>1;}
|
||||
;
|
||||
|
||||
types:
|
||||
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;}
|
||||
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;}
|
||||
@ -234,31 +259,5 @@ types:
|
||||
%%
|
||||
|
||||
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);
|
||||
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column);
|
||||
}
|
||||
/*
|
||||
int main(int argc, char * argv[]) {
|
||||
token_tracker = 1;
|
||||
cur=CreateScope(NULL,1,1);
|
||||
//int a;
|
||||
FILE * fp;
|
||||
if(argc > 1){
|
||||
fp = fopen(argv[1], "r");
|
||||
yyin = fp;
|
||||
} else {
|
||||
fp = stdin;
|
||||
yyin = fp;
|
||||
}
|
||||
yyparse();
|
||||
//while ((a = yyparse() != EOF){
|
||||
// token_tracker++;
|
||||
//printf("%d = a: yytext = %s: yychar = %d, token number: %d\n", a, yytext, yychar,token_tracker);
|
||||
//if(yytext[0] == '\n'){
|
||||
FILE* f = fdopen(1,"w");
|
||||
print_symbol_table(getAncestor(cur),f);
|
||||
fclose(f);
|
||||
// break;
|
||||
//}
|
||||
//}
|
||||
return 0;
|
||||
} */
|
||||
|
@ -72,9 +72,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
"," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}}
|
||||
"->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}}
|
||||
|
||||
{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext);return C_INTEGER;}}
|
||||
'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);return C_CHARACTER;}}
|
||||
\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);return C_STRING;}}
|
||||
{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.words = strdup("integer");return C_INTEGER;}}
|
||||
'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}}
|
||||
\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}}
|
||||
{COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}}
|
||||
|
||||
"(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}}
|
||||
@ -84,9 +84,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
"{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}}
|
||||
"}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}}
|
||||
|
||||
"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup(yytext);return C_TRUE;}}
|
||||
"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup(yytext);return C_FALSE;}}
|
||||
"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup(yytext);return C_NULL;}}
|
||||
"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup("Boolean");return C_TRUE;}}
|
||||
"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup("Boolean");return C_FALSE;}}
|
||||
"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup("address");return C_NULL;}}
|
||||
|
||||
{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}}
|
||||
|
||||
|
86
src/runner.c
86
src/runner.c
@ -2,6 +2,13 @@
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "runner.h"
|
||||
extern TableNode *funprime;
|
||||
extern TableNode *arrayprim;
|
||||
extern TableNode *integ;
|
||||
extern TableNode *addr;
|
||||
extern TableNode *chara;
|
||||
extern TableNode *stri;
|
||||
extern TableNode *boo;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 1) {
|
||||
@ -22,13 +29,16 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
else {
|
||||
if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) {
|
||||
if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) !=
|
||||
0) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
} else {
|
||||
for (int i = 1; i < argc - 1; i++) {
|
||||
if (check_flag(argv[i], argv[argc - 1]) != 0) {
|
||||
fprintf(stderr, "INVALID FLAG(S): Use -help to view valid inputs \n");
|
||||
fprintf(stderr,
|
||||
"INVALID FLAG(S): Use -help to "
|
||||
"view valid inputs \n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -57,25 +67,26 @@ int check_flag(char *arg, char *alpha) {
|
||||
}
|
||||
}
|
||||
|
||||
void incr(int lnum,int cnum, int tok){
|
||||
//if (tok == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
// }else{
|
||||
// column_number += yyleng;
|
||||
// }
|
||||
void incr(int lnum, int cnum, int tok) {
|
||||
// if (tok == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
// }else{
|
||||
// column_number += yyleng;
|
||||
// }
|
||||
}
|
||||
void print_tok(int tok){
|
||||
fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,tok, yytext);
|
||||
void print_tok(int tok) {
|
||||
fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok,
|
||||
yytext);
|
||||
}
|
||||
int run(FILE *alpha) {
|
||||
int token;
|
||||
top = cur = CreateScope(NULL, 1, 1);
|
||||
top = cur = init(CreateScope(NULL, 1, 1));
|
||||
|
||||
// If file is not found
|
||||
if (alpha == NULL) {
|
||||
@ -87,10 +98,11 @@ int run(FILE *alpha) {
|
||||
// TOK FLAG
|
||||
if (tok_flag != NULL) {
|
||||
while (0 != (token = yylex())) {
|
||||
//if (tok_flag != NULL) {
|
||||
// fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,
|
||||
// token, yytext);
|
||||
//}
|
||||
// if (tok_flag != NULL) {
|
||||
// fprintf(tok_flag, "%d %d %3d \"%s\"\n",
|
||||
// line_number, column_number,
|
||||
// token, yytext);
|
||||
// }
|
||||
/*if (token == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
@ -103,9 +115,10 @@ int run(FILE *alpha) {
|
||||
}
|
||||
if (token == 1999) {
|
||||
printf(
|
||||
"On line number %d and column number %d we have an invalid "
|
||||
"character:%s\n",
|
||||
line_number, column_number, yytext);
|
||||
"On line number %d and column
|
||||
number %d we have an invalid " "character:%s\n",
|
||||
line_number, column_number,
|
||||
yytext);
|
||||
}
|
||||
column_number += yyleng; */
|
||||
}
|
||||
@ -118,8 +131,13 @@ int run(FILE *alpha) {
|
||||
}
|
||||
|
||||
if (st_flag != NULL) {
|
||||
// output symbol table, file pointer is
|
||||
// print_symbol_table(top,st_flag);
|
||||
yyparse();
|
||||
print_symbol_table(getAncestor(cur), st_flag);
|
||||
fclose(st_flag);
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
yyparse();
|
||||
@ -165,14 +183,15 @@ int new_file(char *arg, char *alpha) {
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
type_len = ST_LEN;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help to view valid inputs\n");
|
||||
fprintf(stderr,
|
||||
"INVALID FLAG: Use -help to view valid inputs\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// calculate lengths
|
||||
int basename_len = strlen(basename);
|
||||
char *file_name =
|
||||
calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char));
|
||||
calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char));
|
||||
|
||||
// coy filename and add extension
|
||||
strncpy(file_name, basename, basename_len - ALPHA_OFFSET);
|
||||
@ -188,15 +207,14 @@ int new_file(char *arg, char *alpha) {
|
||||
}
|
||||
|
||||
int is_alpha_file(char *alpha, int file_len) {
|
||||
if (strcmp(".alpha", alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) {
|
||||
return -1; // not alpha file
|
||||
if (strcmp(".alpha",
|
||||
alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) {
|
||||
return -1; // not alpha file
|
||||
}
|
||||
return 0; // is alpha file
|
||||
return 0; // is alpha file
|
||||
}
|
||||
|
||||
void enter_scope(int line, int column) {
|
||||
cur = CreateScope(cur, line, column);
|
||||
}
|
||||
void enter_scope(int line, int column) { cur = CreateScope(cur, line, column); }
|
||||
void exit_scope() {
|
||||
if (cur->Parent_Scope == NULL) {
|
||||
printf("Can't close top");
|
||||
|
20
src/runner.h
20
src/runner.h
@ -5,14 +5,18 @@
|
||||
#define TOK_LEN 3
|
||||
#define ST_LEN 2
|
||||
#define HELP \
|
||||
"HELP:\nHow to run the alpha compiler:\n./alpha [options] program\nValid " \
|
||||
"options:\n-tok output the token number, token, line number, and column " \
|
||||
"number for each of the tokens to the .tok file\n-st output the symbol " \
|
||||
"table for the program to the .st file\n-help print this message and exit " \
|
||||
"the alpha compiler\n"
|
||||
"HELP:\nHow to run the alpha compiler:\n./alpha [options] " \
|
||||
"program\nValid " \
|
||||
"options:\n-tok output the token number, token, line number, and " \
|
||||
"column " \
|
||||
"number for each of the tokens to the .tok file\n-st output the " \
|
||||
"symbol " \
|
||||
"table for the program to the .st file\n-help print this message " \
|
||||
"and exit " \
|
||||
"the alpha compiler\n"
|
||||
#define SET_FLAG 1 // Used to set flags for arg types
|
||||
#define INVALID \
|
||||
"INVALID INPUT: Include a .alpha file or use -help for more inputs \n"
|
||||
#define INVALID \
|
||||
"INVALID INPUT: Include a .alpha file or use -help for more inputs \n"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -22,7 +26,7 @@
|
||||
|
||||
#include "../tmp/flex.h"
|
||||
#include "symbol_table.h"
|
||||
//#include "typedefs.h"
|
||||
// #include "typedefs.h"
|
||||
#include "../tmp/grammar.tab.h"
|
||||
|
||||
extern int line_number, column_number;
|
||||
|
@ -6,10 +6,244 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
char * typey = "type";
|
||||
char * funy = "function";
|
||||
SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) {
|
||||
SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable));
|
||||
char *typey = "type";
|
||||
char *funy = "function";
|
||||
TableNode *funprime;
|
||||
TableNode *arrayprim;
|
||||
extern SymbolTable *cur;
|
||||
TableNode *integ;
|
||||
TableNode *addr;
|
||||
TableNode *chara;
|
||||
TableNode *stri;
|
||||
TableNode *boo;
|
||||
TableNode *recprime;
|
||||
TableNode *funtypeprime;
|
||||
|
||||
typedef enum {
|
||||
// First 4 below are primitive types that are all encapsulated in
|
||||
// primitive type
|
||||
// TYPE_INTEGER,
|
||||
// TYPE_CHARACTER,
|
||||
// TYPE_BOOLEAN,
|
||||
// TYPE_ADDRESS,
|
||||
// Type String is an array of char enclosed in double quotes per lexer
|
||||
TYPE_STRING,
|
||||
// Array can be multidimensional. Information should be stored here
|
||||
TYPE_ARRAY,
|
||||
// Record is user defined types
|
||||
TYPE_RECORD,
|
||||
// Declaring what type a particular function is without as
|
||||
TYPE_FUNCTION_DECLARATION,
|
||||
// Declaring what type a particular function is with as
|
||||
// TYPE_AS_FUNCTION_DECLARATION,
|
||||
// Declaring what type a function is (what the parameters and output
|
||||
// are)
|
||||
TYPE_FUNCTION_TYPE,
|
||||
// The Type being pointed to by the first 4 above that only stores the
|
||||
// size
|
||||
TYPE_PRIMITIVE,
|
||||
//likely NULL
|
||||
TYPE_ALL_ELSE
|
||||
|
||||
} types;
|
||||
|
||||
/* put in symbol_table.h
|
||||
typedef struct{
|
||||
int size; if(strcmp(getType(tn),getName(integ))==0){
|
||||
return
|
||||
}
|
||||
}primitive_info;
|
||||
|
||||
typedef struct{
|
||||
int length;
|
||||
char* location;
|
||||
}string_info;
|
||||
|
||||
typedef struct{
|
||||
int numofdimensions;
|
||||
//the above value tells you how long the below array is. For example if num
|
||||
of dimensions is 5, I can store 1,3,2,5,9 to define > int* sizesofdimensions;
|
||||
TableNode* typeofarray;
|
||||
}array_info;
|
||||
|
||||
typedef struct{
|
||||
//similar to above we define a record to hold the number of elements and an
|
||||
array of tablenodes (types) that it contains in the order specified by the user
|
||||
int numofelements;
|
||||
TableNode* listoftypes;
|
||||
}record_info;
|
||||
|
||||
typedef struct{
|
||||
int startlinenumber;
|
||||
bool regularoras;
|
||||
}function_declaration_info;
|
||||
|
||||
typedef struct{
|
||||
TableNode* parameter;
|
||||
TableNode* returntype;
|
||||
}function_type_info;
|
||||
|
||||
typedef union {
|
||||
PrimAdInfo* primitive_info;
|
||||
ArrayAdInfo* array_info;
|
||||
RecAdInfo* record_info;
|
||||
StringAdInfo* string_info;
|
||||
FunDecAdInfo* func_dec_info;
|
||||
FunTypeAdInfo* func_type_info;
|
||||
}AdInfo;
|
||||
*/
|
||||
// primitive additional info only stores the size of that type
|
||||
AdInfo *CreatePrimitiveInfo(int size) {
|
||||
|
||||
AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo));
|
||||
info->PrimAdInfo = (primitive_info *)malloc(sizeof(primitive_info));
|
||||
info->PrimAdInfo->size = size;
|
||||
return info;
|
||||
}
|
||||
|
||||
// only gets the size of a primitive type
|
||||
int getPrimSize(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "primitive") != 0) {
|
||||
printf("not checking the size of a primitive -- invalid op\n");
|
||||
return 0;
|
||||
}
|
||||
return definition->additionalinfo->PrimAdInfo->size;
|
||||
}
|
||||
|
||||
// probably don't need the below structure since can create from an array
|
||||
/*string_info* CreateStringInfo(int length, char* loc){
|
||||
string_info* stringy = (string_info*)malloc(sizeof(string_info));
|
||||
stringy.length=length;
|
||||
char* location = loc;
|
||||
return stringy;
|
||||
}
|
||||
*/
|
||||
|
||||
// Only information stored in array info is the number of dimensions and the
|
||||
// type stored in the array per professor, the actual size of the array is
|
||||
// calculated at runtime so bounds checking only needs to be done then
|
||||
AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) {
|
||||
AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo));
|
||||
info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info));
|
||||
info->ArrayAdInfo->numofdimensions = dim;
|
||||
info->ArrayAdInfo->typeofarray = type;
|
||||
// avoiding storing any types like below
|
||||
// int* dimensionsizes = loc;
|
||||
return info;
|
||||
}
|
||||
// This gets the number of dimensions from array info
|
||||
int getNumArrDim(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "array") != 0) {
|
||||
printf("not checking the dim of an array -- invalid op\n");
|
||||
return 0;
|
||||
}
|
||||
return definition->additionalinfo->ArrayAdInfo->numofdimensions;
|
||||
}
|
||||
// This gets the type stored in an array from arrtype. It returns a reference to
|
||||
// the entry of that type
|
||||
TableNode *getArrType(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "array") != 0) {
|
||||
printf("not checking the type of an array -- invalid op\n");
|
||||
return NULL;
|
||||
}
|
||||
return definition->additionalinfo->ArrayAdInfo->typeofarray;
|
||||
}
|
||||
|
||||
// Record type currently stores the number of elements as well as the types, in
|
||||
// order, of what make up that type in an array. Unfortunately this second part
|
||||
// should probably instead be replaced by a reference to a scope in which those
|
||||
// elements are found.
|
||||
AdInfo *CreateRecordInfo(int length, TableNode *typesarray) {
|
||||
AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo));
|
||||
info->RecAdInfo = (record_info *)malloc(sizeof(record_info));
|
||||
info->RecAdInfo->numofelements = length;
|
||||
// replace below with reference to a scope, not an array
|
||||
info->RecAdInfo->listoftypes = typesarray;
|
||||
return info;
|
||||
}
|
||||
// This gets the number of elements that make up a record.
|
||||
// Perhaps this may not be needed since we need to iterate over all elements
|
||||
// anyways.
|
||||
int getRecLength(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "record") != 0) {
|
||||
printf("not checking the length of an record -- invalid op\n");
|
||||
return 0;
|
||||
}
|
||||
return definition->additionalinfo->RecAdInfo->numofelements;
|
||||
}
|
||||
// This gets the array. Needs to up be updated to get the scope instead
|
||||
TableNode *getRecList(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "record") != 0) {
|
||||
printf("not checking the list of types of a record -- invalid "
|
||||
"op\n");
|
||||
return NULL;
|
||||
}
|
||||
return definition->additionalinfo->RecAdInfo->listoftypes;
|
||||
}
|
||||
|
||||
// below function takes a bool to see if parameter should be decomposed or not
|
||||
// note that functions only take one input and have one output
|
||||
// using "as" the input record can be decomposed to give the illusion of
|
||||
// multiple inputs Below function also has the line number where the function is
|
||||
// first defined
|
||||
AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) {
|
||||
AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo));
|
||||
info->FunDecAdInfo = (function_declaration_info *)malloc(
|
||||
sizeof(function_declaration_info));
|
||||
info->FunDecAdInfo->startlinenumber = line;
|
||||
info->FunDecAdInfo->regularoras = asorregular;
|
||||
return info;
|
||||
}
|
||||
// gets the line at which the function was first defined. (Can be used to print
|
||||
// out in table if needed)
|
||||
int getStartLine(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "function primitive") != 0) {
|
||||
printf("not checking the start line of a function -- invalid "
|
||||
"op\n");
|
||||
return 0;
|
||||
}
|
||||
return definition->additionalinfo->FunDecAdInfo->startlinenumber;
|
||||
}
|
||||
// checks if "as" keyword was used for function definition. Either 0 or 1 for
|
||||
// not used or used.
|
||||
bool getAsKeyword(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "function primitive") != 0) {
|
||||
printf("not checking if a function is called with as or not -- "
|
||||
"invalid op\n");
|
||||
return NULL;
|
||||
}
|
||||
return definition->additionalinfo->FunDecAdInfo->regularoras;
|
||||
}
|
||||
// stores the type of a function (parameter type and return type)
|
||||
AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) {
|
||||
AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo));
|
||||
info->FunTypeAdInfo =
|
||||
(function_type_info *)malloc(sizeof(function_type_info));
|
||||
info->FunTypeAdInfo->parameter = parameter;
|
||||
info->FunTypeAdInfo->returntype = returntype;
|
||||
return info;
|
||||
}
|
||||
// returns parameter type of a function
|
||||
TableNode *getParameter(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "function type primitive") != 0) {
|
||||
printf(
|
||||
"not checking the parameter of a function -- invalid op\n");
|
||||
return NULL;
|
||||
}
|
||||
return definition->additionalinfo->FunTypeAdInfo->parameter;
|
||||
}
|
||||
// returns return type of a function
|
||||
TableNode *getReturn(TableNode *definition) {
|
||||
if (strcmp(getType(definition), "function type primitive") != 0) {
|
||||
printf("not checking the return of a function -- invalid op\n");
|
||||
return NULL;
|
||||
}
|
||||
return definition->additionalinfo->FunTypeAdInfo->returntype;
|
||||
}
|
||||
|
||||
// creates a new scope (not the top scope though)
|
||||
SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) {
|
||||
SymbolTable *table = (SymbolTable *)malloc(sizeof(SymbolTable));
|
||||
table->Line_Number = Line;
|
||||
table->Column_Number = Column;
|
||||
table->Parent_Scope = ParentScope;
|
||||
@ -17,16 +251,18 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) {
|
||||
table->entries = NULL;
|
||||
if (ParentScope != NULL) {
|
||||
if (ParentScope->Children_Scope == NULL) {
|
||||
ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable));
|
||||
ListOfTable *newEntry =
|
||||
(ListOfTable *)malloc(sizeof(ListOfTable));
|
||||
newEntry->next = NULL;
|
||||
// newEntry->prev = NULL;
|
||||
newEntry->table = table;
|
||||
ParentScope->Children_Scope = newEntry;
|
||||
} else {
|
||||
ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable));
|
||||
ListOfTable *newEntry =
|
||||
(ListOfTable *)malloc(sizeof(ListOfTable));
|
||||
// newEntry->prev = NULL;
|
||||
newEntry->table = table;
|
||||
ListOfTable* oldEntry = ParentScope->Children_Scope;
|
||||
ListOfTable *oldEntry = ParentScope->Children_Scope;
|
||||
ParentScope->Children_Scope = newEntry;
|
||||
newEntry->next = oldEntry;
|
||||
}
|
||||
@ -34,38 +270,190 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) {
|
||||
return table;
|
||||
}
|
||||
|
||||
//create entry just for things below top level scope
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) {
|
||||
// create entry just for things below top level scope
|
||||
// This function defines the integer, address, character, and bool primitive
|
||||
// types
|
||||
SymbolTable *init(SymbolTable *start) {
|
||||
if (start->Parent_Scope != NULL) {
|
||||
printf(
|
||||
"Cannot initialize a scope that is not the parent scope\n");
|
||||
return NULL;
|
||||
}
|
||||
integ = (TableNode *)malloc(sizeof(TableNode));
|
||||
addr = (TableNode *)malloc(sizeof(TableNode));
|
||||
chara = (TableNode *)malloc(sizeof(TableNode));
|
||||
stri = (TableNode *)malloc(sizeof(TableNode));
|
||||
boo = (TableNode *)malloc(sizeof(TableNode));
|
||||
// TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable));
|
||||
start->entries = integ;
|
||||
integ->next = addr;
|
||||
addr->next = chara;
|
||||
chara->next = stri;
|
||||
stri->next = boo;
|
||||
// boo->next = arr;
|
||||
boo->next = NULL;
|
||||
|
||||
if(table ==NULL /*|| table->Parent_Scope == NULL*/){
|
||||
printf("Null reference to table given for create entry or given top level scope which is invalid\n");
|
||||
return NULL;
|
||||
integ->theName = "integer";
|
||||
addr->theName = "address";
|
||||
chara->theName = "character";
|
||||
boo->theName = "Boolean";
|
||||
stri->theName = "string";
|
||||
// arr->theName= "array"
|
||||
|
||||
// root TableNode that all are pointing to but not in table
|
||||
// This is only to solve the issue that all entries must have a name and
|
||||
// a type and the type must point to an actual table entry Again, this
|
||||
// primitive table entry isn't in the top scope. It is outside the top
|
||||
// scope and is only there to facilitate the fact that these are
|
||||
// primitive
|
||||
TableNode *prime = (TableNode *)malloc(sizeof(TableNode));
|
||||
prime->theName = "primitive";
|
||||
prime->theType = NULL;
|
||||
prime->additionalinfo = NULL;
|
||||
prime->next = NULL;
|
||||
|
||||
// not sure exatly how to get array types to look right so using a dummy
|
||||
// Table Node below and updating the print symbol table function to
|
||||
// access the additional information to print for array types, similar
|
||||
// to function types when printing symbol table, if array is seen
|
||||
arrayprim = (TableNode *)malloc(sizeof(TableNode));
|
||||
arrayprim->theName = "array";
|
||||
arrayprim->theType = NULL;
|
||||
arrayprim->additionalinfo = NULL;
|
||||
prime->next = NULL;
|
||||
|
||||
// funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL);
|
||||
|
||||
// similar workaround to arrays above
|
||||
funprime = (TableNode *)malloc(sizeof(TableNode));
|
||||
funprime->theName = "primitive function";
|
||||
funprime->theType = NULL;
|
||||
funprime->additionalinfo = NULL;
|
||||
funprime->next = NULL;
|
||||
|
||||
// record
|
||||
recprime = (TableNode *)malloc(sizeof(TableNode));
|
||||
recprime->theName = "record";
|
||||
recprime->theType = NULL;
|
||||
recprime->additionalinfo = NULL;
|
||||
recprime->next = NULL;
|
||||
|
||||
funtypeprime = (TableNode *)malloc(sizeof(TableNode));
|
||||
funtypeprime->theName = "primitive function type";
|
||||
funtypeprime->theType = NULL;
|
||||
funtypeprime->additionalinfo = NULL;
|
||||
funtypeprime->next = NULL;
|
||||
|
||||
integ->theType = prime;
|
||||
addr->theType = prime;
|
||||
chara->theType = prime;
|
||||
stri->theType = arrayprim;
|
||||
boo->theType = prime;
|
||||
// arr->theType=arrayprim;
|
||||
|
||||
// filling in all the values for the additional info for initial types
|
||||
// These numbers below for create primitive specifically are supposed to
|
||||
// be the size of these primitive types. We can change these if needed
|
||||
// to not be hard coded numbers as a reminder, stri below is defined as
|
||||
// a one dimensional array of characters
|
||||
integ->additionalinfo = CreatePrimitiveInfo(4);
|
||||
addr->additionalinfo = CreatePrimitiveInfo(8);
|
||||
chara->additionalinfo = CreatePrimitiveInfo(1);
|
||||
stri->additionalinfo = CreateArrayInfo(1, chara);
|
||||
boo->additionalinfo = CreatePrimitiveInfo(1);
|
||||
// addr->additionalinfo = CreatePrimitiveInfo(8);
|
||||
|
||||
start->Line_Number = 1;
|
||||
start->Column_Number = 1;
|
||||
start->Parent_Scope = NULL;
|
||||
start->Children_Scope = NULL;
|
||||
|
||||
return start;
|
||||
}
|
||||
/*TableNode* topDef = (table_lookup(getAncestor(table),typeOf));
|
||||
if(topDef == NULL){
|
||||
printf("This type is not defined at the top level\n");
|
||||
return NULL;
|
||||
}*/
|
||||
TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode));
|
||||
//newEntry->theType = topDef->theName;
|
||||
newEntry->theType=typeOf;
|
||||
newEntry->theName = id;
|
||||
if (table->entries == NULL) {
|
||||
table->entries = newEntry;
|
||||
return newEntry;
|
||||
} else {
|
||||
TableNode* oldEntry = table->entries;
|
||||
table->entries = newEntry;
|
||||
newEntry->next = oldEntry;
|
||||
return newEntry;
|
||||
}
|
||||
/*
|
||||
TableNode* integ;
|
||||
TableNode* addr;
|
||||
TableNode* chara;
|
||||
TableNode* stri;
|
||||
TableNode* boo;
|
||||
TableNode* recprime;
|
||||
TableNode* funtypeprime;
|
||||
*/
|
||||
|
||||
int getAdInfoType(TableNode* tn){
|
||||
if(strcmp(getType(tn),getName(integ))==0){
|
||||
return TYPE_PRIMITIVE;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(addr))==0){
|
||||
return TYPE_PRIMITIVE;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(chara))==0){
|
||||
return TYPE_PRIMITIVE;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(stri))==0){
|
||||
return TYPE_ARRAY;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(boo))==0){
|
||||
return TYPE_PRIMITIVE;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(recprime))==0){
|
||||
return TYPE_RECORD;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(funtypeprime))==0){
|
||||
return TYPE_FUNCTION_TYPE;
|
||||
}
|
||||
if(strcmp(getType(tn),getName(arrayprim))==0){
|
||||
return TYPE_ARRAY;
|
||||
}
|
||||
else{
|
||||
return TYPE_FUNCTION_DECLARATION;
|
||||
}
|
||||
}
|
||||
|
||||
TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id,
|
||||
AdInfo *ad) {
|
||||
|
||||
if (table == NULL) {
|
||||
printf("Null reference to table");
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
TableNode* topDef = (table_lookup(getAncestor(table),typeOf));
|
||||
if(topDef == NULL){
|
||||
printf("This type is not defined at the top level\n");
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
if (typeOf == NULL) {
|
||||
printf("This is not pointing to a proper definition\n");
|
||||
return NULL;
|
||||
}
|
||||
TableNode *newEntry = (TableNode *)malloc(sizeof(TableNode));
|
||||
newEntry->theType = typeOf /*topDef*/;
|
||||
newEntry->theName = id;
|
||||
newEntry->additionalinfo = ad;
|
||||
if (table->entries == NULL) {
|
||||
table->entries = newEntry;
|
||||
return newEntry;
|
||||
} else {
|
||||
TableNode *oldEntry = table->entries;
|
||||
table->entries = newEntry;
|
||||
newEntry->next = oldEntry;
|
||||
return newEntry;
|
||||
}
|
||||
}
|
||||
|
||||
char *getType(TableNode *tn) { return tn->theType->theName; }
|
||||
char *getName(TableNode *tn) { return tn->theName; }
|
||||
int getLine(SymbolTable *st) { return st->Line_Number; }
|
||||
int getColumn(SymbolTable *st) { return st->Column_Number; }
|
||||
|
||||
/*
|
||||
//we use false for type defs and true for functions for parameter of typeOf
|
||||
TableNode* Define(SymbolTable* table, bool typeOf, char* id) {
|
||||
if(table ==NULL || table->Parent_Scope != NULL){
|
||||
printf("No valid table given for header defs\n");
|
||||
return NULL;
|
||||
printf("No valid table given for header defs\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -73,14 +461,14 @@ if(table ==NULL || table->Parent_Scope != NULL){
|
||||
|
||||
//possible issues with referencing text instead of heap
|
||||
if(typeOf == 0){
|
||||
newEntry->theType = typey;
|
||||
newEntry->theType = typey;
|
||||
}
|
||||
if (typeOf == 1){
|
||||
newEntry->theType = funy;
|
||||
newEntry->theType = funy;
|
||||
}
|
||||
if(table_lookup(table,id) != NULL){
|
||||
printf("already defined at the top level, can't define duplicate names\n");
|
||||
return NULL;
|
||||
printf("already defined at the top level, can't define duplicate
|
||||
names\n"); return NULL;
|
||||
}
|
||||
newEntry->theName = id;
|
||||
if (table->entries == NULL) {
|
||||
@ -94,9 +482,9 @@ if(table_lookup(table,id) != NULL){
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TableNode* table_lookup(SymbolTable* table, char* x) {
|
||||
TableNode* entrie = table->entries;
|
||||
*/
|
||||
TableNode *table_lookup(SymbolTable *table, char *x) {
|
||||
TableNode *entrie = table->entries;
|
||||
for (; entrie != NULL; entrie = entrie->next) {
|
||||
if (!strcmp(entrie->theName, x)) {
|
||||
return entrie;
|
||||
@ -104,63 +492,71 @@ TableNode* table_lookup(SymbolTable* table, char* x) {
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
TableNode* look_up(SymbolTable* table, char* x) {
|
||||
TableNode *look_up(SymbolTable *table, char *x) {
|
||||
if (table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
TableNode* ret = table_lookup(table, x);
|
||||
TableNode *ret = table_lookup(table, x);
|
||||
if (ret != NULL) {
|
||||
return ret;
|
||||
}
|
||||
return look_up(table->Parent_Scope, x);
|
||||
}
|
||||
|
||||
void print_symbol_table(SymbolTable* table, FILE* file_ptr) {
|
||||
void print_symbol_table(SymbolTable *table, FILE *file_ptr) {
|
||||
if (table->Parent_Scope == NULL) {
|
||||
fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE",
|
||||
"PARENT", "TYPE", "Extra annotation");
|
||||
fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME",
|
||||
"SCOPE", "PARENT", "TYPE", "Extra annotation");
|
||||
}
|
||||
TableNode* entrie = table->entries;
|
||||
fprintf(file_ptr,
|
||||
"-----------------:--------:--------:----------------------:---------"
|
||||
"--------------------\n");
|
||||
TableNode *entrie = table->entries;
|
||||
fprintf(file_ptr, "-----------------:--------:--------:----------------"
|
||||
"------:---------"
|
||||
"--------------------\n");
|
||||
int parant_scope = 0;
|
||||
int current_scope = 0;
|
||||
if (table->Parent_Scope != NULL) {
|
||||
parant_scope = table->Parent_Scope->Line_Number * 1000 +
|
||||
table->Parent_Scope->Column_Number;
|
||||
current_scope = table->Line_Number * 1000 + table->Column_Number;
|
||||
table->Parent_Scope->Column_Number;
|
||||
current_scope =
|
||||
table->Line_Number * 1000 + table->Column_Number;
|
||||
} else {
|
||||
current_scope = 1001;
|
||||
}
|
||||
if ( entrie == NULL ) {
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "",
|
||||
current_scope, parant_scope, "", "Empty Scope");
|
||||
if (entrie == NULL) {
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "",
|
||||
current_scope, parant_scope, "", "Empty Scope");
|
||||
}
|
||||
for (; entrie != NULL; entrie = entrie->next) {
|
||||
if (parant_scope == 0) {
|
||||
fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n",
|
||||
entrie->theName, current_scope, entrie->theType,
|
||||
"Extra annotation");
|
||||
/*have to update*/ if (strcmp(entrie->theType->theName,
|
||||
"function primitive") ||
|
||||
strcmp(entrie->theType->theName,
|
||||
"array")) {
|
||||
}
|
||||
fprintf(file_ptr,
|
||||
"%-17s: %06d : : %-21s: %-28s\n",
|
||||
entrie->theName, current_scope,
|
||||
entrie->theType->theName, "Extra annotation");
|
||||
} else {
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName,
|
||||
current_scope, parant_scope, entrie->theType, "Extra annotation");
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n",
|
||||
entrie->theName, current_scope, parant_scope,
|
||||
entrie->theType->theName, "Extra annotation");
|
||||
}
|
||||
}
|
||||
if (table->Children_Scope != NULL) {
|
||||
ListOfTable* node = table->Children_Scope;
|
||||
ListOfTable *node = table->Children_Scope;
|
||||
for (; node != NULL; node = node->next) {
|
||||
print_symbol_table(node->table, file_ptr);
|
||||
}
|
||||
}
|
||||
if (table->Parent_Scope == NULL) {
|
||||
fprintf(file_ptr,
|
||||
"-----------------:--------:--------:----------------------:-------"
|
||||
"----------------------\n");
|
||||
fprintf(file_ptr, "-----------------:--------:--------:--------"
|
||||
"--------------:-------"
|
||||
"----------------------\n");
|
||||
}
|
||||
}
|
||||
|
||||
SymbolTable* getAncestor(SymbolTable* table) {
|
||||
SymbolTable *getAncestor(SymbolTable *table) {
|
||||
if (table->Parent_Scope == NULL) {
|
||||
// if table has no parent, return itself
|
||||
return table;
|
||||
@ -170,17 +566,78 @@ SymbolTable* getAncestor(SymbolTable* table) {
|
||||
}
|
||||
}
|
||||
|
||||
SymbolTable* getParent(SymbolTable* st) { return st->Parent_Scope; }
|
||||
SymbolTable *removeEntry(SymbolTable *scope, char *search) {
|
||||
|
||||
ListOfTable* getChildren(SymbolTable* st) { return st->Children_Scope; }
|
||||
SymbolTable* getFirstChild(ListOfTable* lt) { return lt->table; }
|
||||
ListOfTable* getRestOfChildren(ListOfTable* lt) { return lt->next; }
|
||||
TableNode* getFirstEntry(SymbolTable* st) { return st->entries; }
|
||||
TableNode* getNextEntry(TableNode* tn) { return tn->next; }
|
||||
char* getType(TableNode* tn) { return tn->theType; }
|
||||
char* getName(TableNode* tn) { return tn->theName; }
|
||||
int getLine(SymbolTable* st) { return st->Line_Number; }
|
||||
int getColumn(SymbolTable* st) { return st->Column_Number; }
|
||||
if (scope == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (scope->entries == NULL) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
TableNode *prev = NULL;
|
||||
TableNode *now = scope->entries;
|
||||
|
||||
while (now != NULL) {
|
||||
if (strcmp(getName(now), search) == 0) {
|
||||
if (prev == NULL) {
|
||||
scope->entries = getNextEntry(now);
|
||||
return scope;
|
||||
} else {
|
||||
prev->next = now->next;
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
prev = now;
|
||||
now = now->next;
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
bool typeCheck(char *firstID, char *secondID) {
|
||||
|
||||
TableNode *entry1 = look_up(cur, firstID);
|
||||
TableNode *entry2 = look_up(cur, secondID);
|
||||
if (entry1 == NULL) {
|
||||
printf("first type not defined\n");
|
||||
return false;
|
||||
}
|
||||
if (entry2 == NULL) {
|
||||
printf("second type not defined\n");
|
||||
return false;
|
||||
}
|
||||
if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) ==
|
||||
table_lookup(getAncestor(cur), getType(look_up(cur, secondID)))) {
|
||||
if (strcmp(getType(look_up(cur, firstID)), "array") == 0) {
|
||||
if (look_up(cur, firstID)
|
||||
->additionalinfo->ArrayAdInfo
|
||||
->numofdimensions ==
|
||||
look_up(cur, secondID)
|
||||
->additionalinfo->ArrayAdInfo
|
||||
->numofdimensions &&
|
||||
look_up(cur, firstID)
|
||||
->additionalinfo->ArrayAdInfo
|
||||
->typeofarray ==
|
||||
look_up(cur, secondID)
|
||||
->additionalinfo->ArrayAdInfo
|
||||
->typeofarray) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SymbolTable *getParent(SymbolTable *st) { return st->Parent_Scope; }
|
||||
|
||||
ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; }
|
||||
SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; }
|
||||
ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; }
|
||||
TableNode *getFirstEntry(SymbolTable *st) { return st->entries; }
|
||||
TableNode *getNextEntry(TableNode *tn) { return tn->next; }
|
||||
// uncomment the below main function along with the headers above for a simple
|
||||
// standalone test of table and entry creation
|
||||
|
||||
|
@ -3,40 +3,101 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct TableNode;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
} primitive_info;
|
||||
|
||||
/*This structure can be subsumed into the structure below (1-d array of chars)
|
||||
typedef struct{
|
||||
//shouldn't need to store any values since would be compiled at runtime
|
||||
//int length;
|
||||
//char* location;
|
||||
}string_info;
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int numofdimensions;
|
||||
// the above value tells you how long the below array is. For example if
|
||||
// num of dimensions is 5, I can store 1,3,2,5,9 to define > int*
|
||||
// arr; shouldn't need to store any values (like sizes of dimenions or
|
||||
// the location int* sizesofdimensions; do have to store type of array
|
||||
struct TableNode *typeofarray;
|
||||
} array_info;
|
||||
|
||||
typedef struct {
|
||||
// similar to above we define a record to hold the number of elements
|
||||
// and an array of tablenodes (types) that it contains in the >
|
||||
int numofelements;
|
||||
struct TableNode *listoftypes;
|
||||
} record_info;
|
||||
|
||||
typedef struct {
|
||||
int startlinenumber;
|
||||
bool regularoras;
|
||||
} function_declaration_info;
|
||||
|
||||
typedef struct {
|
||||
struct TableNode *parameter;
|
||||
struct TableNode *returntype;
|
||||
} function_type_info;
|
||||
|
||||
typedef union {
|
||||
primitive_info *PrimAdInfo;
|
||||
array_info *ArrayAdInfo;
|
||||
record_info *RecAdInfo;
|
||||
// string_info* StringAdInfo;
|
||||
function_declaration_info *FunDecAdInfo;
|
||||
function_type_info *FunTypeAdInfo;
|
||||
} AdInfo;
|
||||
|
||||
typedef struct ListOfTable {
|
||||
struct SymbolTable* table;
|
||||
struct SymbolTable *table;
|
||||
// struct ListOfTable* prev;
|
||||
struct ListOfTable* next;
|
||||
struct ListOfTable *next;
|
||||
} ListOfTable;
|
||||
|
||||
typedef struct TableNode {
|
||||
char* theType;
|
||||
char* theName;
|
||||
struct TableNode* next;
|
||||
// reference to the type entry that this is
|
||||
struct TableNode *theType;
|
||||
char *theName;
|
||||
AdInfo *additionalinfo;
|
||||
struct TableNode *next;
|
||||
} TableNode;
|
||||
|
||||
typedef struct SymbolTable {
|
||||
TableNode* entries;
|
||||
struct SymbolTable* Parent_Scope;
|
||||
struct ListOfTable* Children_Scope;
|
||||
TableNode *entries;
|
||||
struct SymbolTable *Parent_Scope;
|
||||
struct ListOfTable *Children_Scope;
|
||||
int Line_Number;
|
||||
int Column_Number;
|
||||
} SymbolTable;
|
||||
|
||||
SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column);
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id);
|
||||
TableNode* table_lookup(SymbolTable* table, char* x);
|
||||
TableNode* look_up(SymbolTable* table, char* x);
|
||||
void print_symbol_table(SymbolTable* table, FILE* file_ptr);
|
||||
SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column);
|
||||
TableNode *table_lookup(SymbolTable *table, char *x);
|
||||
TableNode *look_up(SymbolTable *table, char *x);
|
||||
void print_symbol_table(SymbolTable *table, FILE *file_ptr);
|
||||
|
||||
SymbolTable* getAncestor(SymbolTable* table);
|
||||
SymbolTable* getParent(SymbolTable* st);
|
||||
ListOfTable* getChildren(SymbolTable* st);
|
||||
SymbolTable* getFirstChild(ListOfTable* lt);
|
||||
ListOfTable* getRestOfChildren(ListOfTable* lt);
|
||||
TableNode* getFirstEntry(SymbolTable* st);
|
||||
TableNode* getNextEntry(TableNode* tn);
|
||||
char* getType(TableNode* tn);
|
||||
char* getName(TableNode* tn);
|
||||
int getLine(SymbolTable* st);
|
||||
int getColumn(SymbolTable* st);
|
||||
SymbolTable *getAncestor(SymbolTable *table);
|
||||
SymbolTable *getParent(SymbolTable *st);
|
||||
ListOfTable *getChildren(SymbolTable *st);
|
||||
SymbolTable *getFirstChild(ListOfTable *lt);
|
||||
ListOfTable *getRestOfChildren(ListOfTable *lt);
|
||||
TableNode *getFirstEntry(SymbolTable *st);
|
||||
TableNode *getNextEntry(TableNode *tn);
|
||||
SymbolTable *init(SymbolTable *scope);
|
||||
int getPrimSize(TableNode *definition);
|
||||
int getNumArrDim(TableNode *definition);
|
||||
TableNode *getArrType(TableNode *definition);
|
||||
int getRecLength(TableNode *definition);
|
||||
TableNode *getRecList(TableNode *definition);
|
||||
int getStartLine(TableNode *definition);
|
||||
bool getAsKeyword(TableNode *definition);
|
||||
TableNode *getParameter(TableNode *definition);
|
||||
TableNode *getReturn(TableNode *definition);
|
||||
|
||||
char *getType(TableNode *tn);
|
||||
char *getName(TableNode *tn);
|
||||
int getLine(SymbolTable *st);
|
||||
int getColumn(SymbolTable *st);
|
||||
|
@ -1 +1 @@
|
||||
daskmskdfm
|
||||
1 1 700 "(***)"
|
||||
|
3
tests/sprint1/expected/sp1_comment_fix2.expected
Normal file
3
tests/sprint1/expected/sp1_comment_fix2.expected
Normal file
@ -0,0 +1,3 @@
|
||||
1 1 700 "(*(**)"
|
||||
1 7 603 "*"
|
||||
1 8 502 ")"
|
22
tests/sprint1/expected/sp1_comment_issues.expected
Normal file
22
tests/sprint1/expected/sp1_comment_issues.expected
Normal file
@ -0,0 +1,22 @@
|
||||
1 1 700 "(*(**)"
|
||||
1 7 603 "*"
|
||||
1 8 502 ")"
|
||||
2 1 700 "(***)"
|
||||
3 1 700 "(******)"
|
||||
3 9 700 "(*\kpp*********)"
|
||||
4 1 501 "("
|
||||
4 2 700 "(*((*)"
|
||||
4 8 502 ")"
|
||||
5 1 700 "(***)"
|
||||
5 6 700 "(*)
|
||||
(* *)"
|
||||
7 1 700 "(***)"
|
||||
7 6 502 ")"
|
||||
7 7 502 ")"
|
||||
7 8 502 ")"
|
||||
7 9 502 ")"
|
||||
7 10 502 ")"
|
||||
7 11 502 ")"
|
||||
7 12 603 "*"
|
||||
7 13 700 "(*))))))))*)"
|
||||
7 25 502 ")"
|
9
tests/sprint1/expected/sp1_comments.expected
Normal file
9
tests/sprint1/expected/sp1_comments.expected
Normal file
@ -0,0 +1,9 @@
|
||||
1 1 700 "(* hello *)"
|
||||
2 1 700 "(* hello *)"
|
||||
3 1 700 "(* I'd think this is a legal "string" that contains several \n \t
|
||||
escaped characters, isn't it? *)"
|
||||
5 1 700 "(* \ *)"
|
||||
6 1 700 "(* *)"
|
||||
7 1 700 "(*{COMMENT}+ *)"
|
||||
8 1 700 "(* * *)"
|
||||
9 1 700 "(* (hello) *)"
|
68
tests/sprint1/expected/sp1_general_token.expected
Normal file
68
tests/sprint1/expected/sp1_general_token.expected
Normal file
@ -0,0 +1,68 @@
|
||||
1 1 101 "This"
|
||||
1 6 101 "is"
|
||||
1 9 101 "a"
|
||||
1 11 101 "test"
|
||||
2 1 301 "9"
|
||||
2 2 101 "combined"
|
||||
2 11 301 "7"
|
||||
2 12 101 "okens"
|
||||
3 1 301 "12345"
|
||||
4 1 301 "893247892"
|
||||
5 1 101 "combined"
|
||||
5 10 101 "DueToUnknownChar"
|
||||
5 27 101 "_validtoken"
|
||||
5 39 101 "__validtoken1"
|
||||
5 53 101 "_valid_token2"
|
||||
5 67 101 "validToken3_"
|
||||
6 1 305 "true"
|
||||
6 6 306 "false"
|
||||
7 1 302 "null"
|
||||
7 6 401 "while"
|
||||
7 12 609 "!"
|
||||
7 13 101 "wrong"
|
||||
7 19 402 "if"
|
||||
7 22 101 "when"
|
||||
8 1 404 "else"
|
||||
8 6 405 "type"
|
||||
8 11 406 "function"
|
||||
9 1 407 "return"
|
||||
9 9 408 "external"
|
||||
9 25 409 "as"
|
||||
10 1 101 "string"
|
||||
10 8 101 "_NOte_that_was_not_reserved"
|
||||
11 1 501 "("
|
||||
11 2 503 "["
|
||||
11 3 502 ")"
|
||||
11 4 504 "]"
|
||||
11 5 505 "{"
|
||||
11 6 506 "}"
|
||||
11 7 508 ":"
|
||||
11 8 507 ";"
|
||||
11 9 509 ","
|
||||
11 10 510 "->"
|
||||
12 1 601 "+"
|
||||
12 2 602 "-"
|
||||
12 3 603 "*"
|
||||
12 4 604 "/"
|
||||
12 5 605 "%"
|
||||
13 1 606 "<"
|
||||
13 2 607 "="
|
||||
14 1 608 ":="
|
||||
15 2 101 "This"
|
||||
15 7 101 "is"
|
||||
15 10 101 "not"
|
||||
15 14 101 "a"
|
||||
15 16 101 "valid"
|
||||
16 1 101 "String"
|
||||
17 1 304 ""This is a valid String""
|
||||
18 1 609 "!"
|
||||
18 2 611 "|"
|
||||
19 1 612 "."
|
||||
19 2 612 "."
|
||||
20 1 700 "(* this is a comment *)"
|
||||
21 1 501 "("
|
||||
21 2 603 "*"
|
||||
21 3 101 "Not"
|
||||
21 7 101 "a"
|
||||
21 9 101 "comment"
|
||||
22 3 610 "&"
|
29
tests/sprint1/expected/sp1_keywords.expected
Normal file
29
tests/sprint1/expected/sp1_keywords.expected
Normal file
@ -0,0 +1,29 @@
|
||||
1 1 401 "while"
|
||||
2 1 101 "While"
|
||||
3 1 101 "whiLe"
|
||||
4 1 402 "if"
|
||||
5 1 101 "IF"
|
||||
6 1 101 "If"
|
||||
7 1 101 "iF"
|
||||
8 1 403 "then"
|
||||
9 1 101 "Then"
|
||||
10 1 101 "theN"
|
||||
11 1 404 "else"
|
||||
12 1 101 "eLse"
|
||||
13 1 101 "elSe"
|
||||
14 1 101 "Else"
|
||||
15 1 405 "type"
|
||||
16 1 101 "Type"
|
||||
17 1 101 "tyPe"
|
||||
18 1 406 "function"
|
||||
19 1 101 "Function"
|
||||
20 1 101 "functioN"
|
||||
21 1 407 "return"
|
||||
22 1 101 "Return"
|
||||
23 1 101 "returN"
|
||||
24 1 408 "external"
|
||||
25 1 101 "External"
|
||||
26 1 101 "exteRnal"
|
||||
27 1 409 "as"
|
||||
28 1 101 "As"
|
||||
29 1 101 "aS"
|
22
tests/sprint1/expected/sp1_operators.expected
Normal file
22
tests/sprint1/expected/sp1_operators.expected
Normal file
@ -0,0 +1,22 @@
|
||||
1 1 601 "+"
|
||||
2 1 602 "-"
|
||||
3 1 603 "*"
|
||||
4 1 604 "/"
|
||||
6 1 605 "%"
|
||||
7 1 606 "<"
|
||||
9 1 607 "="
|
||||
10 1 608 ":="
|
||||
11 1 607 "="
|
||||
11 2 508 ":"
|
||||
12 1 508 ":"
|
||||
13 1 607 "="
|
||||
14 1 609 "!"
|
||||
15 1 610 "&"
|
||||
16 1 611 "|"
|
||||
17 1 612 "."
|
||||
18 1 101 "relEASE"
|
||||
19 1 614 "release"
|
||||
20 1 101 "RELEASE"
|
||||
21 1 613 "reserve"
|
||||
22 1 101 "RESERVE"
|
||||
23 1 101 "reSERVe"
|
7
tests/sprint1/expected/sp1_other_punc.expected
Normal file
7
tests/sprint1/expected/sp1_other_punc.expected
Normal file
@ -0,0 +1,7 @@
|
||||
1 1 507 ";"
|
||||
2 1 508 ":"
|
||||
3 1 509 ","
|
||||
4 1 510 "->"
|
||||
5 1 510 "->"
|
||||
6 1 602 "-"
|
||||
6 2 510 "->"
|
59
tests/sprint1/expected/sp1_punc_grouping.expected
Normal file
59
tests/sprint1/expected/sp1_punc_grouping.expected
Normal file
@ -0,0 +1,59 @@
|
||||
1 1 502 ")"
|
||||
2 1 101 "a"
|
||||
2 2 502 ")"
|
||||
3 1 502 ")"
|
||||
3 2 101 "a"
|
||||
4 1 502 ")"
|
||||
4 2 603 "*"
|
||||
5 1 603 "*"
|
||||
5 2 502 ")"
|
||||
7 1 700 "(* jellsls
|
||||
well this seems to work
|
||||
|
||||
|
||||
*)"
|
||||
13 1 501 "("
|
||||
14 1 101 "a"
|
||||
14 2 501 "("
|
||||
15 1 501 "("
|
||||
15 2 101 "a"
|
||||
16 1 501 "("
|
||||
16 2 603 "*"
|
||||
17 1 603 "*"
|
||||
17 2 501 "("
|
||||
20 1 505 "{"
|
||||
21 1 101 "a"
|
||||
21 2 505 "{"
|
||||
22 1 505 "{"
|
||||
22 2 101 "a"
|
||||
23 1 505 "{"
|
||||
23 2 603 "*"
|
||||
24 1 603 "*"
|
||||
24 2 505 "{"
|
||||
25 1 506 "}"
|
||||
26 1 101 "a"
|
||||
26 2 506 "}"
|
||||
27 1 506 "}"
|
||||
27 2 101 "a"
|
||||
28 1 506 "}"
|
||||
28 2 603 "*"
|
||||
29 1 603 "*"
|
||||
29 2 506 "}"
|
||||
33 1 503 "["
|
||||
34 1 101 "a"
|
||||
34 2 503 "["
|
||||
35 1 503 "["
|
||||
35 2 101 "a"
|
||||
36 1 503 "["
|
||||
36 2 603 "*"
|
||||
37 1 603 "*"
|
||||
37 2 503 "["
|
||||
38 1 504 "]"
|
||||
39 1 101 "a"
|
||||
39 2 504 "]"
|
||||
40 1 504 "]"
|
||||
40 2 101 "a"
|
||||
41 1 504 "]"
|
||||
41 2 603 "*"
|
||||
42 1 603 "*"
|
||||
42 2 504 "]"
|
145
tests/sprint1/expected/sp1_real_alpha_file1.expected
Normal file
145
tests/sprint1/expected/sp1_real_alpha_file1.expected
Normal file
@ -0,0 +1,145 @@
|
||||
1 1 405 "type"
|
||||
1 6 101 "rec"
|
||||
1 9 508 ":"
|
||||
1 11 503 "["
|
||||
1 12 201 "integer"
|
||||
1 19 508 ":"
|
||||
1 21 101 "x"
|
||||
1 22 507 ";"
|
||||
1 24 201 "integer"
|
||||
1 31 508 ":"
|
||||
1 33 101 "y"
|
||||
1 34 504 "]"
|
||||
2 1 405 "type"
|
||||
2 6 101 "T1"
|
||||
2 8 508 ":"
|
||||
2 10 201 "integer"
|
||||
2 18 510 "->"
|
||||
2 21 201 "integer"
|
||||
3 1 405 "type"
|
||||
3 6 101 "T2"
|
||||
3 8 508 ":"
|
||||
3 10 101 "rec"
|
||||
3 14 510 "->"
|
||||
3 17 201 "integer"
|
||||
4 1 406 "function"
|
||||
4 10 101 "foo"
|
||||
4 14 508 ":"
|
||||
4 16 101 "T1"
|
||||
5 1 406 "function"
|
||||
5 10 101 "bar1"
|
||||
5 15 508 ":"
|
||||
5 17 101 "T2"
|
||||
6 1 406 "function"
|
||||
6 10 101 "bar2"
|
||||
6 15 508 ":"
|
||||
6 17 101 "T2"
|
||||
7 1 101 "foo"
|
||||
7 4 501 "("
|
||||
7 5 101 "x"
|
||||
7 6 502 ")"
|
||||
7 8 608 ":="
|
||||
7 11 505 "{"
|
||||
8 2 407 "return"
|
||||
8 9 101 "x"
|
||||
8 11 603 "*"
|
||||
8 13 101 "x"
|
||||
8 14 507 ";"
|
||||
9 9 506 "}"
|
||||
10 1 101 "bar1"
|
||||
10 5 501 "("
|
||||
10 6 101 "a"
|
||||
10 7 502 ")"
|
||||
10 9 608 ":="
|
||||
10 12 505 "{"
|
||||
11 9 407 "return"
|
||||
11 16 101 "a"
|
||||
11 17 612 "."
|
||||
11 18 101 "x"
|
||||
11 20 603 "*"
|
||||
11 22 101 "a"
|
||||
11 23 612 "."
|
||||
11 24 101 "y"
|
||||
11 25 507 ";"
|
||||
12 9 506 "}"
|
||||
13 1 101 "bar2"
|
||||
13 6 409 "as"
|
||||
13 9 501 "("
|
||||
13 10 101 "r"
|
||||
13 11 509 ","
|
||||
13 12 101 "s"
|
||||
13 13 502 ")"
|
||||
13 15 608 ":="
|
||||
13 18 505 "{"
|
||||
14 9 407 "return"
|
||||
14 16 101 "r"
|
||||
14 18 603 "*"
|
||||
14 20 101 "s"
|
||||
14 21 507 ";"
|
||||
15 9 506 "}"
|
||||
16 1 101 "entry"
|
||||
16 6 501 "("
|
||||
16 7 101 "arg"
|
||||
16 10 502 ")"
|
||||
16 12 608 ":="
|
||||
16 15 505 "{"
|
||||
17 9 503 "["
|
||||
17 11 201 "integer"
|
||||
17 18 508 ":"
|
||||
17 20 101 "result"
|
||||
17 27 507 ";"
|
||||
17 29 101 "rec"
|
||||
17 32 508 ":"
|
||||
17 34 101 "w"
|
||||
17 35 504 "]"
|
||||
18 9 101 "result"
|
||||
18 16 608 ":="
|
||||
18 19 101 "foo"
|
||||
18 22 501 "("
|
||||
18 23 301 "5"
|
||||
18 24 502 ")"
|
||||
18 25 507 ";"
|
||||
19 9 101 "w"
|
||||
19 11 608 ":="
|
||||
19 14 613 "reserve"
|
||||
19 21 501 "("
|
||||
19 22 101 "w"
|
||||
19 23 502 ")"
|
||||
19 24 507 ";"
|
||||
19 26 700 "(* see types.alpha – reserve returns a value of type address,
|
||||
which can be assigned to array and record variables
|
||||
*)"
|
||||
22 9 101 "w"
|
||||
22 10 612 "."
|
||||
22 11 101 "x"
|
||||
22 13 608 ":="
|
||||
22 16 301 "5"
|
||||
22 17 507 ";"
|
||||
23 9 101 "w"
|
||||
23 10 612 "."
|
||||
23 11 101 "y"
|
||||
23 13 608 ":="
|
||||
23 16 301 "7"
|
||||
23 17 507 ";"
|
||||
24 9 101 "result"
|
||||
24 16 608 ":="
|
||||
24 19 101 "bar1"
|
||||
24 23 501 "("
|
||||
24 24 101 "w"
|
||||
24 25 502 ")"
|
||||
24 26 507 ";"
|
||||
24 28 700 "(* pass w (a rec type value) to bar1 *)"
|
||||
25 9 101 "result"
|
||||
25 16 608 ":="
|
||||
25 19 101 "bar2"
|
||||
25 23 501 "("
|
||||
25 24 301 "5"
|
||||
25 25 509 ","
|
||||
25 26 301 "7"
|
||||
25 27 502 ")"
|
||||
25 28 507 ";"
|
||||
25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)"
|
||||
27 9 407 "return"
|
||||
27 16 301 "0"
|
||||
27 17 507 ";"
|
||||
28 1 506 "}"
|
100
tests/sprint1/expected/sp1_real_alpha_file2.expected
Normal file
100
tests/sprint1/expected/sp1_real_alpha_file2.expected
Normal file
@ -0,0 +1,100 @@
|
||||
1 1 700 "(* Type definitions *)"
|
||||
2 1 405 "type"
|
||||
2 6 101 "string"
|
||||
2 12 508 ":"
|
||||
2 14 301 "1"
|
||||
2 16 510 "->"
|
||||
2 19 204 "character"
|
||||
3 1 405 "type"
|
||||
3 6 101 "int2int"
|
||||
3 13 508 ":"
|
||||
3 15 201 "integer"
|
||||
3 23 510 "->"
|
||||
3 26 201 "integer"
|
||||
4 1 405 "type"
|
||||
4 6 101 "string2int"
|
||||
4 16 508 ":"
|
||||
4 18 101 "string"
|
||||
4 25 510 "->"
|
||||
4 28 201 "integer"
|
||||
5 1 700 "(* Function prototypes
|
||||
They use the above type definitions
|
||||
*)"
|
||||
8 1 406 "function"
|
||||
8 10 101 "square"
|
||||
8 17 508 ":"
|
||||
8 19 101 "int2int"
|
||||
9 1 406 "function"
|
||||
9 10 101 "entry"
|
||||
9 16 508 ":"
|
||||
9 18 101 "string2int"
|
||||
10 1 700 "(* Function definition
|
||||
Functions must be declared before they are defined
|
||||
*)"
|
||||
13 1 101 "square"
|
||||
13 7 501 "("
|
||||
13 8 101 "x"
|
||||
13 9 502 ")"
|
||||
13 11 608 ":="
|
||||
13 14 505 "{"
|
||||
14 1 407 "return"
|
||||
14 8 101 "x"
|
||||
14 10 603 "*"
|
||||
14 12 101 "x"
|
||||
14 13 507 ";"
|
||||
15 1 506 "}"
|
||||
16 1 700 "(* Function definition
|
||||
entry is the first function called
|
||||
*)"
|
||||
19 1 101 "entry"
|
||||
19 6 501 "("
|
||||
19 7 101 "arg"
|
||||
19 10 502 ")"
|
||||
19 12 608 ":="
|
||||
19 15 505 "{"
|
||||
20 1 101 "input"
|
||||
20 7 607 "="
|
||||
20 9 301 "7"
|
||||
20 10 507 ";"
|
||||
21 1 101 "expected"
|
||||
21 10 607 "="
|
||||
21 12 301 "49"
|
||||
21 14 507 ";"
|
||||
22 1 101 "actual"
|
||||
22 8 608 ":="
|
||||
22 11 101 "square"
|
||||
22 17 501 "("
|
||||
22 18 101 "input"
|
||||
22 23 502 ")"
|
||||
22 24 507 ";"
|
||||
23 1 101 "rseult"
|
||||
23 8 608 ":="
|
||||
23 11 101 "expected"
|
||||
23 20 607 "="
|
||||
23 22 101 "actual"
|
||||
23 28 507 ";"
|
||||
24 1 407 "return"
|
||||
24 8 301 "0"
|
||||
24 9 507 ";"
|
||||
25 1 503 "["
|
||||
25 3 201 "integer"
|
||||
25 10 508 ":"
|
||||
25 12 101 "input"
|
||||
25 17 507 ";"
|
||||
25 19 201 "integer"
|
||||
25 26 508 ":"
|
||||
25 28 101 "expected"
|
||||
25 36 507 ";"
|
||||
25 38 201 "integer"
|
||||
25 45 508 ":"
|
||||
25 47 101 "actual"
|
||||
25 53 507 ";"
|
||||
25 55 101 "boolean"
|
||||
25 62 508 ":"
|
||||
25 64 101 "result"
|
||||
25 70 507 ";"
|
||||
25 72 101 "string"
|
||||
25 78 508 ":"
|
||||
25 80 101 "input"
|
||||
25 86 504 "]"
|
||||
26 1 506 "}"
|
8
tests/sprint1/expected/sp1_simple_int.expected
Normal file
8
tests/sprint1/expected/sp1_simple_int.expected
Normal file
@ -0,0 +1,8 @@
|
||||
1 1 301 "45"
|
||||
2 1 301 "123"
|
||||
3 1 301 "8392"
|
||||
4 1 301 "40"
|
||||
4 4 301 "40"
|
||||
5 2 301 "200"
|
||||
5 6 301 "50"
|
||||
5 9 301 "21783"
|
64
tests/sprint1/expected/sp1_simple_literals.expected
Normal file
64
tests/sprint1/expected/sp1_simple_literals.expected
Normal file
@ -0,0 +1,64 @@
|
||||
1 1 304 ""this is a string""
|
||||
1 20 301 "721398"
|
||||
1 27 303 "'g'"
|
||||
1 32 604 "/"
|
||||
1 33 101 "n"
|
||||
1 36 700 "(* should print 3 tokens before this *)"
|
||||
4 1 301 "12893"
|
||||
4 8 101 "this"
|
||||
4 13 101 "is"
|
||||
4 16 101 "not"
|
||||
4 20 101 "a"
|
||||
4 22 101 "string"
|
||||
4 29 700 "(*one valid token before this*)"
|
||||
5 1 700 "(* spacey comment here
|
||||
over multiple lines
|
||||
will it work? *)"
|
||||
7 18 306 "false"
|
||||
11 1 306 "false"
|
||||
12 1 700 "(**)"
|
||||
14 1 101 "nullfalse"
|
||||
15 2 101 "nulltrue"
|
||||
16 1 302 "null"
|
||||
17 1 303 "'7'"
|
||||
18 1 305 "true"
|
||||
19 2 301 "189"
|
||||
20 1 303 "'\t'"
|
||||
21 1 303 "'"'"
|
||||
22 1 303 "'/'"
|
||||
23 1 303 "'\n'"
|
||||
24 1 303 "'\''"
|
||||
25 1 303 "'\t'"
|
||||
26 1 303 "'\\'"
|
||||
27 1 303 "'n'"
|
||||
29 2 101 "fdsf"
|
||||
30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)"
|
||||
35 1 304 ""STRINGwithnotSPaces""
|
||||
36 1 303 "' '"
|
||||
38 1 304 ""J""
|
||||
39 1 304 """"
|
||||
40 1 304 "" ""
|
||||
42 1 304 ""{SCHAR}""
|
||||
43 1 304 ""SCHAR""
|
||||
44 1 304 ""[SCHAR]""
|
||||
45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?""
|
||||
46 2 101 "I"
|
||||
46 4 101 "d"
|
||||
46 6 101 "think"
|
||||
46 12 101 "this"
|
||||
46 17 101 "is"
|
||||
46 20 101 "a"
|
||||
46 22 101 "legal"
|
||||
46 30 101 "string"
|
||||
46 39 101 "that"
|
||||
46 44 101 "contains"
|
||||
46 53 101 "several"
|
||||
46 63 101 "n"
|
||||
46 66 101 "t"
|
||||
46 68 101 "escaped"
|
||||
46 76 101 "characters"
|
||||
46 86 509 ","
|
||||
46 88 101 "isn"
|
||||
46 92 101 "t"
|
||||
46 94 101 "it"
|
||||
47 1 101 "nullLike"
|
13
tests/sprint1/expected/sp1_variables.expected
Normal file
13
tests/sprint1/expected/sp1_variables.expected
Normal file
@ -0,0 +1,13 @@
|
||||
1 1 101 "valid1"
|
||||
2 1 101 "Valid2"
|
||||
3 1 101 "_valid3"
|
||||
4 1 101 "_valid_name_4"
|
||||
5 1 101 "VALID"
|
||||
6 1 301 "0"
|
||||
6 2 101 "Invalid"
|
||||
7 1 301 "1"
|
||||
7 2 101 "invalid"
|
||||
8 2 101 "invalid"
|
||||
9 1 101 "invalid"
|
||||
9 8 607 "="
|
||||
10 1 101 "String"
|
@ -1,48 +0,0 @@
|
||||
/* Function type. */
|
||||
typedef double (func_t) (double);
|
||||
/* Data type for links in the chain of symbols. */
|
||||
struct symrec
|
||||
{
|
||||
char *name; /* name of symbol */
|
||||
int type; /* type of symbol: either VAR or FUN */
|
||||
union
|
||||
{
|
||||
double var; /* value of a VAR */
|
||||
func_t *fun; /* value of a FUN */
|
||||
} value;
|
||||
struct symrec *next; /* link field */
|
||||
};
|
||||
typedef struct symrec symrec;
|
||||
|
||||
/* The symbol table: a chain of 'struct symrec'. */
|
||||
extern symrec *sym_table;
|
||||
|
||||
symrec *putsym (char const *name, int sym_type);
|
||||
symrec *getsym (char const *name);
|
||||
struct init
|
||||
{
|
||||
char const *name;
|
||||
func_t *fun;
|
||||
};
|
||||
struct init const funs[] =
|
||||
{
|
||||
{ "atan", atan },
|
||||
{ "cos", cos },
|
||||
{ "exp", exp },
|
||||
{ "ln", log },
|
||||
{ "sin", sin },
|
||||
{ "sqrt", sqrt },
|
||||
{ 0, 0 },
|
||||
};
|
||||
/* The symbol table: a chain of 'struct symrec'. */
|
||||
symrec *sym_table;
|
||||
/* Put functions in table. */
|
||||
static void
|
||||
init_table (void)
|
||||
{
|
||||
for (int i = 0; funs[i].name; i++)
|
||||
{
|
||||
symrec *ptr = putsym (funs[i].name, FUN);
|
||||
ptr->value.fun = funs[i].fun;
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "symbol_table.h"
|
||||
|
||||
int main(void){
|
||||
char *prim = strdup("primitive");
|
||||
char *inte = strdup("integer");
|
||||
SymbolTable * parant = CreateScope(NULL, 1,1);
|
||||
char *boole = strdup("Boolean");
|
||||
char *chare = strdup("character");
|
||||
char *str = strdup("string");
|
||||
char *arg = strdup("arg");
|
||||
char *one_to_char = strdup("1 -> character");
|
||||
char *int_to_int = strdup("integer -> integer");
|
||||
char *int2int = strdup("int2int");
|
||||
char *str_to_int = strdup("string -> integer");
|
||||
char *str2int = strdup("string2int");
|
||||
char *square = strdup("square");
|
||||
char *string2int = strdup("string2int");
|
||||
char *entry = strdup("entry");
|
||||
char *x = strdup("x");
|
||||
char *input = strdup("input");
|
||||
char *expected = strdup("expected");
|
||||
char *actual = strdup("actual");
|
||||
char *$_und_type = strdup("$_undefined_type");
|
||||
char *result = strdup("result");
|
||||
char *BOO = strdup("BOO");
|
||||
char *YAZOO = strdup("YAZOO");
|
||||
|
||||
CreateEntry(parant, prim, boole);
|
||||
CreateEntry(parant, prim, chare);
|
||||
CreateEntry(parant, prim, inte);
|
||||
CreateEntry(parant, one_to_char, str);
|
||||
CreateEntry(parant, int_to_int, int2int);
|
||||
CreateEntry(parant, str_to_int, str2int);
|
||||
CreateEntry(parant, int2int, square);
|
||||
CreateEntry(parant, string2int, entry);
|
||||
SymbolTable * child = CreateScope(parant, 14,14);
|
||||
CreateEntry(child, inte, x);
|
||||
SymbolTable * second = CreateScope(parant, 21,15);
|
||||
CreateEntry(second, str, arg);
|
||||
CreateEntry(second, inte, input);
|
||||
CreateEntry(second, inte, expected);
|
||||
CreateEntry(second, inte, actual);
|
||||
CreateEntry(second, $_und_type, result);
|
||||
SymbolTable * third = CreateScope(second, 33,44);
|
||||
CreateEntry(third, BOO, arg);
|
||||
CreateEntry(third, YAZOO, input);
|
||||
|
||||
TableNode *ret = table_lookup(third, "arg");
|
||||
printf("%s == %s\n", ret->theName, "arg");
|
||||
|
||||
ret = table_lookup(third, "hello");
|
||||
printf("This should be nil %p != %s\n", ret, "BOO");
|
||||
|
||||
ret = look_up(second, "input");
|
||||
printf("%s == %s\n", ret->theName, "input");
|
||||
|
||||
ret = look_up(second, "square");
|
||||
printf("%s == %s\n", ret->theName, "square");
|
||||
|
||||
ret = look_up(second, "spuare");
|
||||
printf("This should be nil %p == %s\n", ret, "square");
|
||||
|
||||
print_symbol_table(parant, stderr);
|
||||
free(inte);
|
||||
free(boole);
|
||||
free(prim);
|
||||
free(str);
|
||||
free(chare);
|
||||
free(arg);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
%{
|
||||
#include <stdio.h> /* For printf, etc. */
|
||||
#include <math.h> /* For pow, used in the grammar. */
|
||||
#include "calc.h" /* Contains definition of 'symrec'. */
|
||||
int yylex (void);
|
||||
void yyerror (char const *);
|
||||
%}
|
||||
%define api.value.type union /* Generate YYSTYPE from these types: */
|
||||
%token <double> NUM /* Double precision number. */
|
||||
%token <symrec*> VAR FUN /* Symbol table pointer: variable/function. */
|
||||
%nterm <double> exp
|
||||
%precedence '='
|
||||
%left '-' '+'
|
||||
%left '*' '/'
|
||||
%precedence NEG /* negation--unary minus */
|
||||
%right '^' /* exponentiation */
|
||||
%% /* The grammar follows. */
|
||||
input:
|
||||
%empty
|
||||
| input line
|
||||
;
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' { printf ("%.10g\n", $1); }
|
||||
| error '\n' { yyerrok; }
|
||||
;
|
||||
exp:
|
||||
NUM
|
||||
| VAR { $$ = $1->value.var; }
|
||||
| VAR '=' exp { $$ = $3; $1->value.var = $3; }
|
||||
| FUN '(' exp ')' { $$ = $1->value.fun ($3); }
|
||||
| exp '+' exp { $$ = $1 + $3; }
|
||||
| exp '-' exp { $$ = $1 - $3; }
|
||||
| exp '*' exp { $$ = $1 * $3; }
|
||||
| exp '/' exp { $$ = $1 / $3; }
|
||||
| '-' exp %prec NEG { $$ = -$2; }
|
||||
| exp '^' exp { $$ = pow ($1, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
;
|
||||
/* End of grammar. */
|
||||
%%
|
Reference in New Issue
Block a user