Merge pull request #29 from UB-CSE443/Sprint2-NewFormatPlusGrammar-FE-t#NoTask
Sprint2 new format plus grammar fe t#no task
This commit is contained in:
40 files changed
+1093
-546
No files matched your search
+3
-1
@@ -6,4 +6,6 @@ grammar.tab.c
|
||||
grammar.tab.h
|
||||
.vscode
|
||||
out
|
||||
src
|
||||
tmp
|
||||
parser
|
||||
*.save
|
||||
@@ -1,44 +1,49 @@
|
||||
CC := gcc
|
||||
FLEX := flex
|
||||
LEX := lexicalStructure.lex
|
||||
LEX := src/lexicalStructure.lex
|
||||
EXE := alpha
|
||||
CFLAGS :=
|
||||
YACC := bison
|
||||
|
||||
compiler: lex.yy.c runner.o runner
|
||||
TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha)
|
||||
TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha)
|
||||
|
||||
lex.yy.c: lexicalStructure.lex
|
||||
$(FLEX) -o lex.yy.c $(LEX)
|
||||
compiler: clean runner
|
||||
|
||||
runner.o: runner.c runner.h flex.h
|
||||
$(CC) $(CFLAGS) -o runner.o -c runner.c
|
||||
tmp/grammar.tab.c: src/grammar.y
|
||||
mkdir -p tmp
|
||||
$(YACC) -d src/grammar.y
|
||||
mv grammar.tab.c tmp/
|
||||
mv grammar.tab.h tmp/
|
||||
|
||||
symbol.o: symbol_table.c symbol_table.h
|
||||
$(CC) $(CFLAGS) -o symbol_table.o symbol_table.c
|
||||
tmp/lex.yy.c: src/lexicalStructure.lex tmp/grammar.tab.c
|
||||
$(FLEX) -o tmp/lex.yy.c $(LEX)
|
||||
mv flex.h tmp/
|
||||
|
||||
runner: lex.yy.c runner.o symbol_table.o
|
||||
$(CC) $(CFLAGS) -o $(EXE) runner.o lex.yy.c symbol_table.o
|
||||
tmp/runner.o: src/runner.c src/runner.h tmp/flex.h
|
||||
$(CC) $(CFLAGS) -o tmp/runner.o -c src/runner.c
|
||||
|
||||
bison: grammar.y
|
||||
bison -d grammar.y
|
||||
tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h
|
||||
$(CC) $(CFLAGS) -o tmp/symbol_table.o -c src/symbol_table.c
|
||||
|
||||
runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o
|
||||
$(CC) $(CFLAGS) -o $(EXE) tmp/runner.o tmp/grammar.tab.c tmp/lex.yy.c
|
||||
|
||||
debug: CFLAGS += -DDEBUG=1
|
||||
debug: clean compiler
|
||||
|
||||
test:
|
||||
./$(EXE) -tok ./tests/sprint1/test_comment_fix1.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_comment_fix2.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_comment_issues.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_comments.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_general_token.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_keywords.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_operators.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_other_punc.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_punc_grouping.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_real_alpha_file1.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_real_alpha_file2.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_simple_int.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_simple_literals.alpha
|
||||
./$(EXE) -tok ./tests/sprint1/test_variables.alpha
|
||||
test: test-s1 test-s2
|
||||
|
||||
test-s1:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);)
|
||||
./check.sh
|
||||
|
||||
test-s2:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) -tok $(test);)
|
||||
./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) $(test);)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
@@ -50,3 +55,5 @@ clean:
|
||||
rm -f grammar.tab.h
|
||||
rm -f *.st
|
||||
rm -rf out
|
||||
rm -rf tmp
|
||||
rm -f parser
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Diff-Check Tool #
|
||||
# Checks if outputed TOK = exp #
|
||||
# The Translators - Spring 2025 #
|
||||
|
||||
TOK_DIR="out"
|
||||
|
||||
if [[ ! -d "$TOK_DIR" ]]; then
|
||||
echo "Directory $TOK_DIR does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\n"
|
||||
for file in "$TOK_DIR"/*; do
|
||||
filename=$(basename -- "$file")
|
||||
filename="${filename%.*}"
|
||||
num=${filename:2:1}
|
||||
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"
|
||||
fi
|
||||
done
|
||||
@@ -1,64 +0,0 @@
|
||||
/* Syntax Analyzer with Bison (3.8.1) */
|
||||
/* (referenced Bison manual for file boilerplate [3.1]) */
|
||||
|
||||
// Prologue
|
||||
%{
|
||||
#include <stdio.h>
|
||||
%}
|
||||
|
||||
%token ID 101
|
||||
%token T_INTEGER 201
|
||||
%token T_ADDRESS 202
|
||||
%token T_BOOLEAN 203
|
||||
%token T_CHARACTER 204
|
||||
%token T_STRING 205
|
||||
%token C_INTEGER 301
|
||||
%token C_NULL 302
|
||||
%token C_CHARACTER 303
|
||||
%token C_STRING 304
|
||||
%token C_TRUE 305
|
||||
%token C_FALSE 306
|
||||
%token WHILE 401
|
||||
%token IF 402
|
||||
%token THEN 403
|
||||
%token ELSE 404
|
||||
%token TYPE 405
|
||||
%token FUNCTION 406
|
||||
%token RETURN 407
|
||||
%token EXTERNAL 408
|
||||
%token AS 409
|
||||
%token L_PAREN 501
|
||||
%token R_PAREN 502
|
||||
%token L_BRACKET 503
|
||||
%token R_BRACKET 504
|
||||
%token L_BRACE 505
|
||||
%token R_BRACE 506
|
||||
%token SEMI_COLON 507
|
||||
%token COLON 508
|
||||
%token COMMA 509
|
||||
%token ARROW 510
|
||||
%token ADD 601
|
||||
%token SUB_OR_NEG 602
|
||||
%token MUL 603
|
||||
%token DIV 604
|
||||
%token REM 605
|
||||
%token LESS_THAN 606
|
||||
%token EQUAL_TO 607
|
||||
%token ASSIGN 608
|
||||
%token NOT 609
|
||||
%token AND 610
|
||||
%token OR 611
|
||||
%token DOT 612
|
||||
%token RESERVE 613
|
||||
%token RELEASE 614
|
||||
%token COMMENT 700
|
||||
|
||||
%%
|
||||
DBLOCK: %empty;
|
||||
|
||||
FUNCTION_DECLARATION: FUNCTION ID COLON ID
|
||||
| EXTERNAL FUNCTION ID COLON ID
|
||||
;
|
||||
RECORD_DECLARATION: TYPE ID COLON DBLOCK;
|
||||
ARRAY_DECLARATION: ID ASSIGN RESERVE ID L_PAREN C_INTEGER R_PAREN;
|
||||
%%
|
||||
@@ -1,88 +0,0 @@
|
||||
/* Lexical Analysis with Flex (1.6.0) We used some of the code from this manual */
|
||||
/* so we placed the citation here. */
|
||||
/* definitions */
|
||||
|
||||
%option noyywrap
|
||||
%option header-file="flex.h"
|
||||
%{
|
||||
#include <stdbool.h>
|
||||
#include "typedefs.h"
|
||||
int line_number = 1, column_number = 1;
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
%}
|
||||
|
||||
STARCOM [^\*]|\*+[^\)\*]+
|
||||
PARENCOM [^\)]|[^\*\)]+\)+
|
||||
ID [A-Za-z_][0-9A-Za-z_]*
|
||||
DIGIT [0-9]
|
||||
CHAR \\n|\\t|\\'|[^'\n\t\\]|\\\\
|
||||
/* char can be a newline, tab, an escaped quote, or anything but a single quote, an actual line break, an actual tab, or a backslash by itself (to prevent confusion from escaped quote */
|
||||
SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
/* similar to above, a string Char (SCHAR) is the same as a CHAR except we cannot have double quotes instead of single quotes. Double quotes need to be escaped in Flex unlike single quotes based on documentation */
|
||||
|
||||
%%
|
||||
|
||||
"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {return T_INTEGER;}}
|
||||
"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {return T_ADDRESS;}}
|
||||
"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {return T_BOOLEAN;}}
|
||||
"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {return T_CHARACTER;}}
|
||||
|
||||
"while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {return WHILE;}}
|
||||
"if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {return IF;}}
|
||||
"then" {if(DEBUG) {printf( "THEN: %s (%d)\n", yytext, THEN);} else {return THEN;}}
|
||||
"else" {if(DEBUG) {printf( "ELSE: %s (%d)\n", yytext, ELSE);} else {return ELSE;}}
|
||||
"type" {if(DEBUG) {printf( "TYPE: %s (%d)\n", yytext, TYPE);} else {return TYPE;}}
|
||||
"function" {if(DEBUG) {printf( "FUNCTION: %s (%d)\n", yytext, FUNCTION);} else {return FUNCTION;}}
|
||||
"return" {if(DEBUG) {printf( "RETURN: %s (%d)\n", yytext, RETURN);} else {return RETURN;}}
|
||||
"external" {if(DEBUG) {printf( "EXTERNAL: %s (%d)\n", yytext, EXTERNAL);} else {return EXTERNAL;}}
|
||||
"as" {if(DEBUG) {printf( "AS: %s (%d)\n", yytext, AS);} else {return AS;}}
|
||||
|
||||
"release" {if(DEBUG) {printf( "RELEASE: %s (%d)\n", yytext, RELEASE);} else {return RELEASE;}}
|
||||
"reserve" {if(DEBUG) {printf( "RESERVE: %s (%d)\n", yytext, RESERVE);} else {return RESERVE;}}
|
||||
|
||||
"+" {if(DEBUG) {printf( "ADD: %s (%d)\n", yytext, ADD);} else {return ADD;}}
|
||||
"-" {if(DEBUG) {printf( "SUB_OR_NEG: %s (%d)\n", yytext, SUB_OR_NEG);} else {return SUB_OR_NEG;}}
|
||||
"*" {if(DEBUG) {printf( "MUL: %s (%d)\n", yytext, MUL);} else {return MUL;}}
|
||||
"/" {if(DEBUG) {printf( "DIV: %s (%d)\n", yytext, DIV);} else {return DIV;}}
|
||||
"%" {if(DEBUG) {printf( "REM: %s (%d)\n", yytext, REM);} else {return REM;}}
|
||||
"<" {if(DEBUG) {printf( "LESS_THAN: %s (%d)\n", yytext, LESS_THAN);} else {return LESS_THAN;}}
|
||||
"=" {if(DEBUG) {printf( "EQUAL_TO: %s (%d)\n", yytext, EQUAL_TO);} else {return EQUAL_TO;}}
|
||||
":=" {if(DEBUG) {printf( "ASSIGN: %s (%d)\n", yytext, ASSIGN);} else {return ASSIGN;}}
|
||||
"!" {if(DEBUG) {printf( "NOT: %s (%d)\n", yytext, NOT);} else {return NOT;}}
|
||||
"&" {if(DEBUG) {printf( "AND: %s (%d)\n", yytext, AND);} else {return AND;}}
|
||||
"|" {if(DEBUG) {printf( "OR: %s (%d)\n", yytext, OR);} else {return OR;}}
|
||||
"." {if(DEBUG) {printf( "DOT: %s (%d)\n", yytext, DOT);} else {return DOT;}}
|
||||
|
||||
";" {if(DEBUG) {printf( "SEMI_COLON: %s (%d)\n", yytext, SEMI_COLON);} else {return SEMI_COLON;}}
|
||||
":" {if(DEBUG) {printf( "COLON: %s (%d)\n", yytext, COLON);} else {return COLON;}}
|
||||
"," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {return COMMA;}}
|
||||
"->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {return ARROW;}}
|
||||
|
||||
{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {return C_INTEGER;}}
|
||||
'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {return C_CHARACTER;}}
|
||||
\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {return C_STRING;}}
|
||||
\(\*{STARCOM}*\*\)|\(\*{PARENCOM}*\*\) {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {return COMMENT;}}
|
||||
|
||||
"(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {return L_PAREN;}}
|
||||
")" {if(DEBUG) {printf( "R_PAREN: %s (%d)\n", yytext, R_PAREN);} else {return R_PAREN;}}
|
||||
|
||||
"[" {if(DEBUG) {printf( "L_BRACKET: %s (%d)\n", yytext, L_BRACKET);} else {return L_BRACKET;}}
|
||||
"]" {if(DEBUG) {printf( "R_BRACKET: %s (%d)\n", yytext, R_BRACKET);} else {return R_BRACKET;}}
|
||||
|
||||
"{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {return L_BRACE;}}
|
||||
"}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {return R_BRACE;}}
|
||||
|
||||
"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {return C_TRUE;}}
|
||||
"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {return C_FALSE;}}
|
||||
"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {return C_NULL;}}
|
||||
|
||||
{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {return ID;}}
|
||||
|
||||
\n {line_number++; column_number = 1;}
|
||||
\t {column_number++;}
|
||||
" " {column_number++;}
|
||||
. {column_number++; return 1999;}
|
||||
|
||||
%%
|
||||
@@ -1,176 +0,0 @@
|
||||
//#include "symbol_table.h"
|
||||
#include "runner.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "INVALID INPUT: Include a .alpha file or use -help for more inputs \n");
|
||||
return -1;
|
||||
} else if (argc == 2) {
|
||||
//can be either -help or .alpha file
|
||||
if (is_help(argv[1])) {
|
||||
return 0;
|
||||
} else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) {
|
||||
//run flex for now
|
||||
no_flag = SET_FLAG; //no argument but valid input
|
||||
alpha_file = fopen(argv[1], "r");
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "INVALID INPUT: Include a .alpha file or use -help for more inputs\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
//last input must be .alpha
|
||||
if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) {
|
||||
fprintf(stderr, "INVALID INPUT: Include a .alpha file at end of input or use -help for more inputs \n");
|
||||
return -1;
|
||||
} else {
|
||||
//now check that other args are valid (flags will not be null if flag is present)
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
alpha_file = fopen(argv[argc - 1], "r");
|
||||
}
|
||||
}
|
||||
return run(alpha_file);
|
||||
}
|
||||
|
||||
int check_flag(char *arg, char* alpha) {
|
||||
if (strcmp("-tok", arg) == 0) {
|
||||
if (tok_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-st", arg) == 0) {
|
||||
if (st_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int run(FILE *alpha) {
|
||||
int token;
|
||||
//check that file exists
|
||||
if (alpha == NULL) {
|
||||
fprintf(stderr, "INPUT FILE NOT FOUND\n");
|
||||
return -1;
|
||||
}
|
||||
yyin = alpha;
|
||||
while (0 != (token = yylex())) {
|
||||
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'){
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(token == 1999){
|
||||
printf("On line number %d and column number %d we have an invalid character:%s\n",line_number,column_number,yytext);
|
||||
}
|
||||
column_number += yyleng;
|
||||
}
|
||||
|
||||
if (st_flag != NULL) {
|
||||
//output symbol table, file pointer is
|
||||
//print_symbol_table(top,st_flag);
|
||||
}
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
|
||||
if (tok_flag != NULL) {
|
||||
fclose(tok_flag);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_help(char * input) {
|
||||
if (strcmp(input, "-help") == 0) {
|
||||
printf("%s", HELP);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int new_file(char *arg, char *alpha) {
|
||||
int type_len;
|
||||
const char *basename = alpha;
|
||||
const char *slash = strchr(alpha, '/');
|
||||
|
||||
while (slash != NULL) {
|
||||
basename = slash + 1;
|
||||
slash = strchr(basename, '/');
|
||||
}
|
||||
|
||||
mkdir("./out", 0777);
|
||||
|
||||
char *new_basename = calloc(strlen(basename) + 5, sizeof(char));
|
||||
strcpy(new_basename, "./out/");
|
||||
strcat(new_basename, basename);
|
||||
basename = new_basename;
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
type_len = TOK_LEN;
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
type_len = ST_LEN;
|
||||
} else {
|
||||
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));
|
||||
|
||||
//coy filename and add extension
|
||||
strncpy(file_name, basename, basename_len - ALPHA_OFFSET);
|
||||
strcat(file_name, ".");
|
||||
strcat(file_name, arg + 1);
|
||||
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
tok_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
st_flag = fopen(file_name, "w");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
return 0; //is alpha file
|
||||
}
|
||||
|
||||
void enter_scope(int line, int column){
|
||||
curr = CreateScope(curr, line, column);
|
||||
}
|
||||
void exit_scope() {
|
||||
if(curr->Parent_Scope == NULL){
|
||||
printf("Can't close top");
|
||||
return;
|
||||
}
|
||||
curr = curr->Parent_Scope;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#define ALPHA_OFFSET 6
|
||||
#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"
|
||||
//use to set flags for arg types
|
||||
#define SET_FLAG 1
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "flex.h"
|
||||
#include "typedefs.h"
|
||||
#include <stdbool.h>
|
||||
#include "symbol_table.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
extern int line_number, column_number;
|
||||
extern char *yytext;
|
||||
extern FILE *yyin;
|
||||
int arg;
|
||||
|
||||
SymbolTable * top;
|
||||
SymbolTable * curr;
|
||||
|
||||
// int main(int argc, char* argv[]);
|
||||
char *is_tok(int argc, char* argv[]);
|
||||
// int is_alpha_file(char *file, int file_len);
|
||||
void enter_scope(int, int);
|
||||
void exit_scope(void);
|
||||
|
||||
FILE *alpha_file;
|
||||
FILE *tok_flag = NULL;
|
||||
FILE *st_flag = NULL;
|
||||
int no_flag = 0;
|
||||
|
||||
int main(int argc, char* argv[]);
|
||||
int new_file(char *arg, char *alpha);
|
||||
int is_alpha_file(char *alpha, int file_len);
|
||||
bool is_help(char * input);
|
||||
int run(FILE*alpha);
|
||||
int check_flag(char * arg, char* alpha);
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/* Syntax Analyzer with Bison (3.8.2) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include "../src/symbol_table.c"
|
||||
#include <math.h>
|
||||
extern int yylex(void);
|
||||
void yyerror(const char *err);
|
||||
extern char* yytext;
|
||||
extern int yyleng;
|
||||
extern int yychar;
|
||||
extern SymbolTable * cur;
|
||||
//char* cur_value;
|
||||
//char* cur_type;
|
||||
int token_tracker;
|
||||
extern int line_number;
|
||||
extern int column_number;
|
||||
extern FILE * yyin;
|
||||
%}
|
||||
//%define api.location.type {location_t}
|
||||
%locations
|
||||
%union {
|
||||
int integ;
|
||||
char * words;
|
||||
}
|
||||
|
||||
|
||||
%type <words> id_or_types
|
||||
%type <words> types
|
||||
%token <words> ID 101
|
||||
%token <words> T_INTEGER 201
|
||||
%token <words> T_ADDRESS 202
|
||||
%token <words> T_BOOLEAN 203
|
||||
%token <words> T_CHARACTER 204
|
||||
%token <words> T_STRING 205
|
||||
%token <integ> C_INTEGER 301
|
||||
%token <words> C_NULL 302
|
||||
%token <words> C_CHARACTER 303
|
||||
%token <words> C_STRING 304
|
||||
%token <words> C_TRUE 305
|
||||
%token <words> C_FALSE 306
|
||||
%token WHILE 401
|
||||
%token IF 402
|
||||
%token THEN 403
|
||||
%token ELSE 404
|
||||
%token TYPE 405
|
||||
%token FUNCTION 406
|
||||
%token RETURN 407
|
||||
%token EXTERNAL 408
|
||||
%token AS 409
|
||||
%token L_PAREN 501
|
||||
%token R_PAREN 502
|
||||
%token L_BRACKET 503
|
||||
%token R_BRACKET 504
|
||||
%token L_BRACE 505
|
||||
%token R_BRACE 506
|
||||
%token SEMI_COLON 507
|
||||
%token COLON 508
|
||||
%token COMMA 509
|
||||
%token ARROW 510
|
||||
%token MUL 603
|
||||
%token DIV 604
|
||||
%token REM 605
|
||||
%token ADD 601
|
||||
%token LESS_THAN 606
|
||||
%token EQUAL_TO 607
|
||||
%token AND 610
|
||||
%token OR 611
|
||||
%token ASSIGN 608
|
||||
%token SUB_OR_NEG 602
|
||||
%token NOT 609
|
||||
%token DOT 612
|
||||
%token RESERVE 613
|
||||
%token RELEASE 614
|
||||
%token COMMENT 700
|
||||
|
||||
//precedence order
|
||||
%left ASSIGN
|
||||
%left OR
|
||||
%left AND
|
||||
%left EQUAL_TO
|
||||
%left LESS_THAN
|
||||
%left ADD SUB_OR_NEG
|
||||
%left MUL DIV REM
|
||||
%precedence NOT
|
||||
%precedence UMINUS
|
||||
%precedence DOT
|
||||
%precedence RESERVE RELEASE
|
||||
|
||||
|
||||
|
||||
%%
|
||||
|
||||
program:
|
||||
prototype_or_definition_list
|
||||
;
|
||||
|
||||
prototype_or_definition_list:
|
||||
prototype prototype_or_definition_list
|
||||
| definition prototype_or_definition_list
|
||||
| prototype
|
||||
| definition
|
||||
;
|
||||
|
||||
prototype:
|
||||
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
|
||||
|
||||
definition:
|
||||
TYPE ID COLON dblock
|
||||
| TYPE ID COLON constant ARROW ID
|
||||
//| function_declaration
|
||||
| TYPE ID COLON id_or_types ARROW id_or_types
|
||||
| ID parameter ASSIGN sblock
|
||||
;
|
||||
|
||||
//function_declaration:
|
||||
// FUNCTION ID COLON ID
|
||||
//| EXTERNAL FUNCTION ID COLON ID
|
||||
//;
|
||||
|
||||
parameter:
|
||||
L_PAREN ID R_PAREN
|
||||
| AS L_PAREN idlist R_PAREN
|
||||
;
|
||||
|
||||
idlist:
|
||||
ID COMMA idlist
|
||||
| ID
|
||||
;
|
||||
|
||||
sblock:
|
||||
L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE
|
||||
| L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE
|
||||
;
|
||||
|
||||
dblock:
|
||||
L_BRACKET declaration_list R_BRACKET;
|
||||
|
||||
declaration_list:
|
||||
declaration SEMI_COLON declaration_list
|
||||
| declaration
|
||||
;
|
||||
|
||||
declaration:
|
||||
id_or_types COLON ID {CreateEntry(cur,$<words>1,$<words>3); }
|
||||
;
|
||||
|
||||
id_or_types:
|
||||
ID {printf("string of id in id_or_type is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| types {printf("string of type in id_or_type is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
;
|
||||
|
||||
statement_list:
|
||||
compound_statement statement_list
|
||||
| compound_statement
|
||||
| simple_statement SEMI_COLON statement_list
|
||||
| simple_statement SEMI_COLON
|
||||
;
|
||||
|
||||
compound_statement:
|
||||
WHILE L_PAREN expression R_PAREN sblock
|
||||
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
|
||||
| sblock //{printf("seen a compound statement rule\n");}
|
||||
;
|
||||
|
||||
simple_statement:
|
||||
assignable ASSIGN expression
|
||||
| RETURN expression
|
||||
;
|
||||
|
||||
assignable:
|
||||
ID
|
||||
| assignable ablock
|
||||
| assignable rec_op ID
|
||||
;
|
||||
|
||||
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");}
|
||||
| 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
|
||||
;
|
||||
|
||||
|
||||
ablock:
|
||||
L_PAREN argument_list R_PAREN
|
||||
;
|
||||
|
||||
argument_list:
|
||||
expression COMMA argument_list
|
||||
| expression
|
||||
;
|
||||
|
||||
|
||||
memOp:
|
||||
RESERVE {printf("reserve expression\n");}
|
||||
| RELEASE {printf("release expression\n");}
|
||||
;
|
||||
|
||||
|
||||
constant:
|
||||
C_STRING
|
||||
| C_INTEGER
|
||||
| C_NULL
|
||||
| C_CHARACTER
|
||||
| C_TRUE
|
||||
| C_FALSE
|
||||
;
|
||||
|
||||
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;}
|
||||
| T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
| T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(const char *err) {
|
||||
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column);
|
||||
}
|
||||
/*
|
||||
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;
|
||||
} */
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Lexical Analyzer with Flex (1.6.0) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
%option noyywrap
|
||||
%option header-file="flex.h"
|
||||
%option yylineno
|
||||
%{
|
||||
#include <stdbool.h>
|
||||
#include "../tmp/grammar.tab.h"
|
||||
#include "../src/symbol_table.h"
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
extern SymbolTable * cur;
|
||||
extern FILE* tok_flag;
|
||||
extern void incr(int lnum,int cnum, int tok);
|
||||
extern void print_tok(int tok);
|
||||
|
||||
int line_number = 1, column_number = 1;
|
||||
int yycolumn = 1;
|
||||
#define YY_USER_ACTION { \
|
||||
yylloc.first_line = yylineno; \
|
||||
yylloc.last_line = yylineno; \
|
||||
yylloc.first_column = yycolumn; \
|
||||
yylloc.last_column = yycolumn + yyleng - 1; \
|
||||
yycolumn += yyleng; }
|
||||
%}
|
||||
|
||||
STARCOM [^\*]|\*+[^\)\*]+
|
||||
PARENCOM [^\)]|[^\*\)]+\)+
|
||||
COMMENT \(\*{STARCOM}*\*\)|\(\*{PARENCOM}*\*\)
|
||||
ID [A-Za-z_][0-9A-Za-z_]*
|
||||
DIGIT [0-9]
|
||||
CHAR \\n|\\t|\\'|[^'\n\t\\]|\\\\
|
||||
SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
|
||||
%%
|
||||
|
||||
"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);return T_INTEGER;}}
|
||||
"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);return T_ADDRESS;}}
|
||||
"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);return T_BOOLEAN;}}
|
||||
"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);return T_CHARACTER;}}
|
||||
|
||||
"while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}}
|
||||
"if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}}
|
||||
"then" {if(DEBUG) {printf( "THEN: %s (%d)\n", yytext, THEN);} else {if(tok_flag != NULL){print_tok(THEN);}incr(line_number,column_number,THEN);return THEN;}}
|
||||
"else" {if(DEBUG) {printf( "ELSE: %s (%d)\n", yytext, ELSE);} else {if(tok_flag != NULL){print_tok(ELSE);}incr(line_number,column_number,ELSE);return ELSE;}}
|
||||
"type" {if(DEBUG) {printf( "TYPE: %s (%d)\n", yytext, TYPE);} else {if(tok_flag != NULL){print_tok(TYPE);}incr(line_number,column_number,TYPE);return TYPE;}}
|
||||
"function" {if(DEBUG) {printf( "FUNCTION: %s (%d)\n", yytext, FUNCTION);} else {if(tok_flag != NULL){print_tok(FUNCTION);}incr(line_number,column_number,FUNCTION);return FUNCTION;}}
|
||||
"return" {if(DEBUG) {printf( "RETURN: %s (%d)\n", yytext, RETURN);} else {if(tok_flag != NULL){print_tok(RETURN);}incr(line_number,column_number,RETURN);return RETURN;}}
|
||||
"external" {if(DEBUG) {printf( "EXTERNAL: %s (%d)\n", yytext, EXTERNAL);} else {if(tok_flag != NULL){print_tok(EXTERNAL);}incr(line_number,column_number,EXTERNAL);return EXTERNAL;}}
|
||||
"as" {if(DEBUG) {printf( "AS: %s (%d)\n", yytext, AS);} else {if(tok_flag != NULL){print_tok(AS);}incr(line_number,column_number,AS);return AS;}}
|
||||
|
||||
"release" {if(DEBUG) {printf( "RELEASE: %s (%d)\n", yytext, RELEASE);} else {if(tok_flag != NULL){print_tok(RELEASE);}incr(line_number,column_number,RELEASE);return RELEASE;}}
|
||||
"reserve" {if(DEBUG) {printf( "RESERVE: %s (%d)\n", yytext, RESERVE);} else {if(tok_flag != NULL){print_tok(RESERVE);}incr(line_number,column_number,RESERVE);return RESERVE;}}
|
||||
|
||||
"+" {if(DEBUG) {printf( "ADD: %s (%d)\n", yytext, ADD);} else {if(tok_flag != NULL){print_tok(ADD);}incr(line_number,column_number,ADD);return ADD;}}
|
||||
"-" {if(DEBUG) {printf( "SUB_OR_NEG: %s (%d)\n", yytext, SUB_OR_NEG);} else {if(tok_flag != NULL){print_tok(SUB_OR_NEG);}incr(line_number,column_number,SUB_OR_NEG);return SUB_OR_NEG;}}
|
||||
"*" {if(DEBUG) {printf( "MUL: %s (%d)\n", yytext, MUL);} else {if(tok_flag != NULL){print_tok(MUL);}incr(line_number,column_number,MUL);return MUL;}}
|
||||
"/" {if(DEBUG) {printf( "DIV: %s (%d)\n", yytext, DIV);} else {if(tok_flag != NULL){print_tok(DIV);}incr(line_number,column_number,DIV);return DIV;}}
|
||||
"%" {if(DEBUG) {printf( "REM: %s (%d)\n", yytext, REM);} else {if(tok_flag != NULL){print_tok(REM);}incr(line_number,column_number,REM);return REM;}}
|
||||
"<" {if(DEBUG) {printf( "LESS_THAN: %s (%d)\n", yytext, LESS_THAN);} else {if(tok_flag != NULL){print_tok(LESS_THAN);}incr(line_number,column_number,LESS_THAN);return LESS_THAN;}}
|
||||
"=" {if(DEBUG) {printf( "EQUAL_TO: %s (%d)\n", yytext, EQUAL_TO);} else {if(tok_flag != NULL){print_tok(EQUAL_TO);}incr(line_number,column_number,EQUAL_TO);return EQUAL_TO;}}
|
||||
":=" {if(DEBUG) {printf( "ASSIGN: %s (%d)\n", yytext, ASSIGN);} else {if(tok_flag != NULL){print_tok(ASSIGN);}incr(line_number,column_number,ASSIGN);return ASSIGN;}}
|
||||
"!" {if(DEBUG) {printf( "NOT: %s (%d)\n", yytext, NOT);} else {if(tok_flag != NULL){print_tok(NOT);}incr(line_number,column_number,NOT);return NOT;}}
|
||||
"&" {if(DEBUG) {printf( "AND: %s (%d)\n", yytext, AND);} else {if(tok_flag != NULL){print_tok(AND);}incr(line_number,column_number,AND);return AND;}}
|
||||
"|" {if(DEBUG) {printf( "OR: %s (%d)\n", yytext, OR);} else {if(tok_flag != NULL){print_tok(OR);}incr(line_number,column_number,OR);return OR;}}
|
||||
"." {if(DEBUG) {printf( "DOT: %s (%d)\n", yytext, DOT);} else {if(tok_flag != NULL){print_tok(DOT);}incr(line_number,column_number,DOT);return DOT;}}
|
||||
|
||||
";" {if(DEBUG) {printf( "SEMI_COLON: %s (%d)\n", yytext, SEMI_COLON);} else {if(tok_flag != NULL){print_tok(SEMI_COLON);}incr(line_number,column_number,SEMI_COLON);return SEMI_COLON;}}
|
||||
":" {if(DEBUG) {printf( "COLON: %s (%d)\n", yytext, COLON);} else {if(tok_flag != NULL){print_tok(COLON);}incr(line_number,column_number,COLON);return COLON;}}
|
||||
"," {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;}}
|
||||
{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;}}
|
||||
")" {if(DEBUG) {printf( "R_PAREN: %s (%d)\n", yytext, R_PAREN);} else {if(tok_flag != NULL){print_tok(R_PAREN);}incr(line_number,column_number,R_PAREN);return R_PAREN;}}
|
||||
"[" {if(DEBUG) {printf( "L_BRACKET: %s (%d)\n", yytext, L_BRACKET);} else {if(tok_flag != NULL){print_tok(L_BRACKET);}incr(line_number,column_number,L_BRACKET);return L_BRACKET;}}
|
||||
"]" {if(DEBUG) {printf( "R_BRACKET: %s (%d)\n", yytext, R_BRACKET);} else {if(tok_flag != NULL){print_tok(R_BRACKET);}incr(line_number,column_number,R_BRACKET);return R_BRACKET;}}
|
||||
"{" {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);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);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);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;}}
|
||||
|
||||
\n {yycolumn=1;incr(line_number,column_number,0);}
|
||||
\t {incr(line_number,column_number,0);}
|
||||
" " {incr(line_number,column_number,0);}
|
||||
. {incr(line_number,column_number,0);}
|
||||
|
||||
%%
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/* Runner File - Compiles alpha Compiler */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "runner.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (argc == 2) {
|
||||
if (is_help(argv[1])) {
|
||||
return 0;
|
||||
} else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) {
|
||||
no_flag = SET_FLAG;
|
||||
alpha_file = fopen(argv[1], "r");
|
||||
} else {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
alpha_file = fopen(argv[argc - 1], "r");
|
||||
}
|
||||
}
|
||||
return run(alpha_file);
|
||||
}
|
||||
|
||||
int check_flag(char *arg, char *alpha) {
|
||||
if (strcmp("-tok", arg) == 0) {
|
||||
if (tok_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-st", arg) == 0) {
|
||||
if (st_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
int run(FILE *alpha) {
|
||||
int token;
|
||||
cur = CreateScope(NULL, 1, 1);
|
||||
|
||||
// If file is not found
|
||||
if (alpha == NULL) {
|
||||
fprintf(stderr, "INPUT FILE NOT FOUND\n");
|
||||
return -1;
|
||||
}
|
||||
yyin = 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 (token == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (token == 1999) {
|
||||
printf(
|
||||
"On line number %d and column number %d we have an invalid "
|
||||
"character:%s\n",
|
||||
line_number, column_number, yytext);
|
||||
}
|
||||
column_number += yyleng; */
|
||||
}
|
||||
fclose(tok_flag);
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (st_flag != NULL) {
|
||||
// output symbol table, file pointer is
|
||||
// print_symbol_table(top,st_flag);
|
||||
}
|
||||
|
||||
yyparse();
|
||||
FILE *f = fdopen(1, "w");
|
||||
print_symbol_table(getAncestor(cur), f);
|
||||
fclose(f);
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_help(char *input) {
|
||||
if (strcmp(input, "-help") == 0) {
|
||||
printf("%s", HELP);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int new_file(char *arg, char *alpha) {
|
||||
int type_len;
|
||||
const char *basename = alpha;
|
||||
const char *slash = strchr(alpha, '/');
|
||||
|
||||
while (slash != NULL) {
|
||||
basename = slash + 1;
|
||||
slash = strchr(basename, '/');
|
||||
}
|
||||
|
||||
mkdir("./out", 0777);
|
||||
|
||||
char *new_basename = calloc(strlen(basename) + 5, sizeof(char));
|
||||
strcpy(new_basename, "./out/");
|
||||
strcat(new_basename, basename);
|
||||
basename = new_basename;
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
type_len = TOK_LEN;
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
type_len = ST_LEN;
|
||||
} else {
|
||||
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));
|
||||
|
||||
// coy filename and add extension
|
||||
strncpy(file_name, basename, basename_len - ALPHA_OFFSET);
|
||||
strcat(file_name, ".");
|
||||
strcat(file_name, arg + 1);
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
tok_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
st_flag = fopen(file_name, "w");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
return 0; // is alpha file
|
||||
}
|
||||
|
||||
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");
|
||||
return;
|
||||
}
|
||||
cur = cur->Parent_Scope;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/* Runner File - Compiles alpha Compiler */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#define ALPHA_OFFSET 6
|
||||
#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"
|
||||
#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"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../tmp/flex.h"
|
||||
#include "symbol_table.h"
|
||||
//#include "typedefs.h"
|
||||
#include "../tmp/grammar.tab.h"
|
||||
|
||||
extern int line_number, column_number;
|
||||
extern char *yytext;
|
||||
extern FILE *yyin;
|
||||
int arg;
|
||||
|
||||
SymbolTable *top;
|
||||
SymbolTable *cur;
|
||||
|
||||
// int main(int argc, char* argv[]);
|
||||
char *is_tok(int argc, char *argv[]);
|
||||
// int is_alpha_file(char *file, int file_len);
|
||||
void enter_scope(int, int);
|
||||
void exit_scope(void);
|
||||
|
||||
FILE *alpha_file;
|
||||
FILE *tok_flag = NULL;
|
||||
FILE *st_flag = NULL;
|
||||
int no_flag = 0;
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
int new_file(char *arg, char *alpha);
|
||||
int is_alpha_file(char *alpha, int file_len);
|
||||
bool is_help(char *input);
|
||||
int run(FILE *alpha);
|
||||
int check_flag(char *arg, char *alpha);
|
||||
@@ -0,0 +1,148 @@
|
||||
/* Symbol Table */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "symbol_table.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
table->Children_Scope = NULL;
|
||||
table->entries = NULL;
|
||||
if (ParentScope != NULL) {
|
||||
if (ParentScope->Children_Scope == NULL) {
|
||||
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));
|
||||
// newEntry->prev = NULL;
|
||||
newEntry->table = table;
|
||||
ListOfTable* oldEntry = ParentScope->Children_Scope;
|
||||
ParentScope->Children_Scope = newEntry;
|
||||
newEntry->next = oldEntry;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) {
|
||||
TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode));
|
||||
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* table_lookup(SymbolTable* table, char* x) {
|
||||
TableNode* entrie = table->entries;
|
||||
for (; entrie != NULL; entrie = entrie->next) {
|
||||
if (!strcmp(entrie->theName, x)) {
|
||||
return entrie;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
TableNode* look_up(SymbolTable* table, char* x) {
|
||||
if (table == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
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) {
|
||||
if (table->Parent_Scope == NULL) {
|
||||
fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE",
|
||||
"PARENT", "TYPE", "Extra annotation");
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
current_scope = 1001;
|
||||
}
|
||||
|
||||
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");
|
||||
} else {
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName,
|
||||
current_scope, parant_scope, entrie->theType, "Extra annotation");
|
||||
}
|
||||
}
|
||||
if (table->Children_Scope != NULL) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
SymbolTable* getAncestor(SymbolTable* table) {
|
||||
if (table->Parent_Scope == NULL) {
|
||||
// if table has no parent, return itself
|
||||
return table;
|
||||
} else {
|
||||
// call function recursively to grab ancestor
|
||||
return getAncestor(table->Parent_Scope);
|
||||
}
|
||||
}
|
||||
|
||||
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; }
|
||||
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
|
||||
|
||||
/*
|
||||
int main(){
|
||||
char* String = "STRING";
|
||||
char* X = "X";
|
||||
SymbolTable* Second = CreateScope(NULL, 2,2);
|
||||
printf("Line number is %d, Column number of scope is
|
||||
%d\n",Second->Line_Number,Second->Column_Number); TableNode* First_Entry =
|
||||
CreateEntry(Second,String,X);
|
||||
|
||||
printf("The type of the first entry is %s\n",First_Entry->theType);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct ListOfTable {
|
||||
struct SymbolTable* table;
|
||||
// struct ListOfTable* prev;
|
||||
struct ListOfTable* next;
|
||||
|
||||
} ListOfTable;
|
||||
|
||||
typedef struct TableNode {
|
||||
char* theType;
|
||||
char* theName;
|
||||
struct TableNode* next;
|
||||
} TableNode;
|
||||
|
||||
typedef struct SymbolTable {
|
||||
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* 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);
|
||||
File renamed without changes.
-117
@@ -1,117 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "symbol_table.h"
|
||||
|
||||
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;
|
||||
table->Children_Scope = NULL;
|
||||
table->entries = NULL;
|
||||
if(ParentScope != NULL){
|
||||
if(ParentScope->Children_Scope == NULL){
|
||||
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));
|
||||
//newEntry->prev = NULL;
|
||||
newEntry->table= table;
|
||||
ListOfTable* oldEntry = ParentScope->Children_Scope;
|
||||
ParentScope->Children_Scope = newEntry;
|
||||
newEntry->next = oldEntry;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id){
|
||||
TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode));
|
||||
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 * table_lookup(SymbolTable * table, char * x){
|
||||
TableNode * entrie = table->entries;
|
||||
for(; entrie != NULL; entrie = entrie->next){
|
||||
if (!strcmp(entrie->theName, x)){
|
||||
return entrie;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
TableNode * look_up(SymbolTable * table, char * x){
|
||||
if(table == NULL){
|
||||
return NULL;
|
||||
}
|
||||
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){
|
||||
if(table->Parent_Scope == NULL){
|
||||
fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation");
|
||||
}
|
||||
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;
|
||||
} else {
|
||||
current_scope = 1001;
|
||||
}
|
||||
|
||||
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");
|
||||
} else {
|
||||
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n",
|
||||
entrie->theName, current_scope, parant_scope,
|
||||
entrie->theType, "Extra annotation");
|
||||
}
|
||||
}
|
||||
if (table->Children_Scope != NULL){
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
//uncomment the below main function along with the headers above for a simple standalone test of table and entry creation
|
||||
|
||||
/*
|
||||
int main(){
|
||||
char* String = "STRING";
|
||||
char* X = "X";
|
||||
SymbolTable* Second = CreateScope(NULL, 2,2);
|
||||
printf("Line number is %d, Column number of scope is %d\n",Second->Line_Number,Second->Column_Number);
|
||||
TableNode* First_Entry = CreateEntry(Second,String,X);
|
||||
|
||||
printf("The type of the first entry is %s\n",First_Entry->theType);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
@@ -1,32 +0,0 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct ListOfTable{
|
||||
struct SymbolTable* table;
|
||||
//struct ListOfTable* prev;
|
||||
struct ListOfTable* next;
|
||||
|
||||
}ListOfTable;
|
||||
|
||||
typedef struct TableNode{
|
||||
char* theType;
|
||||
char* theName;
|
||||
struct TableNode* next;
|
||||
}TableNode;
|
||||
|
||||
typedef struct SymbolTable{
|
||||
TableNode* entries;
|
||||
struct SymbolTable* Parent_Scope;
|
||||
struct ListOfTable* Children_Scope;
|
||||
int Line_Number;
|
||||
int Column_Number;
|
||||
}SymbolTable;
|
||||
|
||||
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id);
|
||||
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);
|
||||
@@ -0,0 +1 @@
|
||||
daskmskdfm
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,48 @@
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,41 @@
|
||||
%{
|
||||
#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. */
|
||||
%%
|
||||
@@ -0,0 +1,15 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
x := 3 + 2 * 8;
|
||||
x := 3 - 2 / 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 % 2 * 8;
|
||||
x := 3 + 2 - 8;
|
||||
arr2 := 1 * reserve x;
|
||||
arr2 := release x;
|
||||
b2 := 3 < 2;
|
||||
b1 := 1 = 2;
|
||||
b2 := !(3 < 2);
|
||||
b1 := 6<7 & 7=7;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
(* At compiler start-up your program should create symbol table entries for the four primitive types:
|
||||
Boolean (1 byte)
|
||||
character (1 byte)
|
||||
integer (4 bytes)
|
||||
address (8 bytes)
|
||||
You should #include this file at the start of your alpha file.
|
||||
Some useful types are defined below.
|
||||
*)
|
||||
type string: 1 -> character
|
||||
type BooleanXBoolean: [Boolean: x, y]
|
||||
type characterXcharacter: [character: x, y]
|
||||
type integerXinteger: [integer: x, y]
|
||||
|
||||
type Boolean2Boolean: Boolean -> Boolean
|
||||
type integer2integer: integer -> integer
|
||||
type character2integer: character -> integer
|
||||
type Boolean2integer: Boolean -> integer
|
||||
type string2integer: string -> integer
|
||||
type integerXinteger2integer: integerXinteger -> integer
|
||||
type integerXinteger2Boolean: integerXinteger -> Boolean
|
||||
type characterXcharacter2Boolean: characterXcharacter -> Boolean
|
||||
type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean
|
||||
type integer2address: integer -> address
|
||||
type address2integer: address -> integer
|
||||
external function printInteger: integer2integer
|
||||
external function printCharacter: character2integer
|
||||
external function printBoolean: Boolean2integer
|
||||
external function reserve: integer2address
|
||||
external function release: address2integer
|
||||
function entry: string2integer
|
||||
@@ -0,0 +1,74 @@
|
||||
type rec: [integer: x; integer: y]
|
||||
type T1: integer -> integer
|
||||
type T2: rec -> integer
|
||||
|
||||
type llnode: [llnode: prev; integer: val; llnode: next]
|
||||
type list: integer -> llnode
|
||||
|
||||
function foo : T1
|
||||
function bar1 : T2
|
||||
function bar2 : T2
|
||||
function make_list : list
|
||||
make_list(a) := {
|
||||
[integer:orig_a; address: ret; address: curr; address: temp]
|
||||
if (a < 0 | a = 0) then {
|
||||
return null;
|
||||
} else {
|
||||
ret := reserve llnode;
|
||||
ret.prev := null;
|
||||
ret.next := null;
|
||||
ret.val := a;
|
||||
while (0 < a) {
|
||||
temp := reserve llnode;
|
||||
temp.prev := null;
|
||||
temp.next := null;
|
||||
temp.val := val;
|
||||
if (a = orig_a) then {
|
||||
ret.next := temp;
|
||||
temp.prev := ret;
|
||||
curr := temp;
|
||||
} else {
|
||||
curr.next := temp;
|
||||
temp.prev := curr;
|
||||
curr := temp;
|
||||
}
|
||||
a := a - 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foo(x) := {
|
||||
return x * x;
|
||||
}
|
||||
bar1(a) := {
|
||||
return a.x * a.y;
|
||||
}
|
||||
|
||||
bar2 as (r,s) := {
|
||||
if (r < s) then {
|
||||
while (!(r < s)) {
|
||||
r := r + 1;
|
||||
}
|
||||
} else {
|
||||
[integer: x]
|
||||
x := 0;
|
||||
while (x < 10) {
|
||||
r := r + s;
|
||||
}
|
||||
}
|
||||
return r * s;
|
||||
}
|
||||
entry(arg) := {
|
||||
[ integer: result ; rec: w; llnode: li]
|
||||
li := make_list(6);
|
||||
result := foo(5);
|
||||
w := reserve w;
|
||||
w.x := 5;
|
||||
w.y := 7;
|
||||
result := bar1(w);
|
||||
result := bar2(5,7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; }
|
||||
@@ -0,0 +1,4 @@
|
||||
entry(arg) := {
|
||||
[integer:x]
|
||||
x := 3 + 2 * 8;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "library.alpha"
|
||||
entry(arg) := {
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user