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:
Moroseui
2025-03-26 13:00:20 -04:00
committed by GitHub
25 changed files with 1314 additions and 379 deletions

View File

@ -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

View File

@ -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 -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 "--------------------------------------------\n"
echo -e ""
fi
else
echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value."
fi
done

View File

@ -17,6 +17,15 @@
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,22 +193,32 @@ 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");}
;
@ -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;}
// 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;}
@ -236,29 +261,3 @@ 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);
}
/*
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;
} */

View File

@ -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;}}

View File

@ -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;
}
}
@ -71,11 +81,12 @@ void incr(int lnum,int cnum, int tok){
// }
}
void print_tok(int tok) {
fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,tok, yytext);
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) {
@ -88,7 +99,8 @@ int run(FILE *alpha) {
if (tok_flag != NULL) {
while (0 != (token = yylex())) {
// if (tok_flag != NULL) {
// fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,
// fprintf(tok_flag, "%d %d %3d \"%s\"\n",
// line_number, column_number,
// token, yytext);
// }
/*if (token == COMMENT) {
@ -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,7 +183,8 @@ 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;
}
@ -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) {
if (strcmp(".alpha",
alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) {
return -1; // not 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");

View File

@ -5,10 +5,14 @@
#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 " \
"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 \

View File

@ -8,6 +8,240 @@
#include <stdlib.h>
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;
@ -17,13 +251,15 @@ 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;
@ -35,21 +271,167 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) {
}
// create entry just for things below top level scope
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) {
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");
// 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;
}
/*TableNode* topDef = (table_lookup(getAncestor(table),typeOf));
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;
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* 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 = topDef->theName;
newEntry->theType=typeOf;
newEntry->theType = typeOf /*topDef*/;
newEntry->theName = id;
newEntry->additionalinfo = ad;
if (table->entries == NULL) {
table->entries = newEntry;
return newEntry;
@ -61,6 +443,12 @@ if(topDef == NULL){
}
}
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){
@ -79,8 +467,8 @@ if (typeOf == 1){
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,7 +482,7 @@ if(table_lookup(table,id) != NULL){
}
}
*/
TableNode *table_lookup(SymbolTable *table, char *x) {
TableNode *entrie = table->entries;
for (; entrie != NULL; entrie = entrie->next) {
@ -117,19 +505,20 @@ TableNode* look_up(SymbolTable* table, char* x) {
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,
"-----------------:--------:--------:----------------------:---------"
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;
current_scope =
table->Line_Number * 1000 + table->Column_Number;
} else {
current_scope = 1001;
}
@ -139,12 +528,19 @@ void print_symbol_table(SymbolTable* table, FILE* file_ptr) {
}
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) {
@ -154,8 +550,8 @@ void print_symbol_table(SymbolTable* table, FILE* file_ptr) {
}
}
if (table->Parent_Scope == NULL) {
fprintf(file_ptr,
"-----------------:--------:--------:----------------------:-------"
fprintf(file_ptr, "-----------------:--------:--------:--------"
"--------------:-------"
"----------------------\n");
}
}
@ -170,6 +566,71 @@ SymbolTable* getAncestor(SymbolTable* table) {
}
}
SymbolTable *removeEntry(SymbolTable *scope, char *search) {
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; }
@ -177,10 +638,6 @@ 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; }
// uncomment the below main function along with the headers above for a simple
// standalone test of table and entry creation

View File

@ -3,6 +3,55 @@
#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 ListOfTable* prev;
@ -10,8 +59,10 @@ typedef struct ListOfTable {
} ListOfTable;
typedef struct TableNode {
char* theType;
// reference to the type entry that this is
struct TableNode *theType;
char *theName;
AdInfo *additionalinfo;
struct TableNode *next;
} TableNode;
@ -24,7 +75,6 @@ typedef struct SymbolTable {
} 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);
@ -36,6 +86,17 @@ 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);

View File

@ -1 +1 @@
daskmskdfm
1 1 700 "(***)"

View File

@ -0,0 +1,3 @@
1 1 700 "(*(**)"
1 7 603 "*"
1 8 502 ")"

View 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 ")"

View 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) *)"

View 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 "&"

View 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"

View 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"

View 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 "->"

View 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 "]"

View 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 "}"

View 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 "}"

View 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"

View 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"

View 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"

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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. */
%%