Merge pull request #32 from UB-CSE443/Dev

Sprint 2 Final
This commit is contained in:
sabrina
2025-03-11 11:26:25 -04:00
committed by GitHub
39 changed files with 1536 additions and 26 deletions
+11
View File
@@ -0,0 +1,11 @@
*.tok
*.o
alpha
flex.h
grammar.tab.c
grammar.tab.h
.vscode
out
tmp
parser
*.save
+35
View File
@@ -0,0 +1,35 @@
* Dev
Sprint1-TokenLocationLogic-NoTask
Sprint1-TokenizeConstantsAndLiterals-FE-t#03
Sprint2-BlockHandlingGrammar-FE-t#34
Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask#
Sprint2-NewFormatPlusGrammar-FE-t#NoTask
Sprint2-PrintOutErrorTokenPositions-NoTask
Sprint2-Symbol_Table_Setup-FE-t#32
Token_Error_Logic-No_Task
main
remotes/origin/Dev
remotes/origin/HEAD -> origin/main
remotes/origin/Sprint1-BasicProgSetup-FE-t#06
remotes/origin/Sprint1-BasicProgSetupFix-t#06
remotes/origin/Sprint1-HelpInput-FE-t#18
remotes/origin/Sprint1-TokenLocationLogic-NoTask
remotes/origin/Sprint1-TokenizeConstantsAndLiterals-FE-t#03
remotes/origin/Sprint1-TokenizeID_MainFunction-FE-t#04
remotes/origin/Sprint1-TokenizeOperators-FE-t#08
remotes/origin/Sprint1-Type/Keywards-FE-t#07
remotes/origin/Sprint1-punctuation/grouping-FE-t#09
remotes/origin/Sprint2-AssignableAndMemory-FE-t#39
remotes/origin/Sprint2-BlockHandlingGrammar-FE-t#34
remotes/origin/Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask#
remotes/origin/Sprint2-CommandLineHandling-FE-t#33
remotes/origin/Sprint2-CompoundStmntGrmmr-FE-t#36
remotes/origin/Sprint2-FunctionDefinition-FE-t#38
remotes/origin/Sprint2-Infrastructure-FE-t#30
remotes/origin/Sprint2-NewFormatPlusGrammar-FE-t#NoTask
remotes/origin/Sprint2-PrintOutErrorTokenPositions-NoTask
remotes/origin/Sprint2-SymbolTableOperations-FE-t#29
remotes/origin/Sprint2-Symbol_Table_Setup-FE-t#32
remotes/origin/Sprint2-addingTests-t#00
remotes/origin/Token_Error_Logic-No_Task
remotes/origin/main
+59 -14
View File
@@ -1,14 +1,59 @@
# Basic Makefile example from flex documentation -- provides explicit rules
# Creates "myprogram" from "scan.l" and "myprogram.c"
#
#LEX=flex
#myprogram: scan.o myprogram.o
#$(CC) -o $@ $(LDFLAGS) $^
#myprogram.o: myprogram.c
#$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $^
#scan.o: scan.c
#$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $^
#scan.c: scan.l
#$(LEX) $(LFLAGS) -o $@ $^
#clean:
#$(RM) *.o scan.c
CC := gcc
FLEX := flex
LEX := src/lexicalStructure.lex
EXE := alpha
CFLAGS :=
YACC := bison
TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha)
TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha)
compiler: clean runner
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/
tmp/lex.yy.c: src/lexicalStructure.lex tmp/grammar.tab.c
$(FLEX) -o tmp/lex.yy.c $(LEX)
mv flex.h tmp/
tmp/runner.o: src/runner.c src/runner.h tmp/flex.h
$(CC) $(CFLAGS) -o tmp/runner.o -c src/runner.c
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: 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
rm -f lex.yy.c
rm -f $(EXE)
rm -f flex.h
rm -f *.tok
rm -f grammar.tab.c
rm -f grammar.tab.h
rm -f *.st
rm -rf out
rm -rf tmp
rm -f parser
+17
View File
@@ -0,0 +1,17 @@
# The Translators α Compiler
#### Members: Annie Slenker, Meyer Simon, Partho Bhattacharya, & Scarlett Kadan
## Lexical Analyzer
* **Undefined Behavior:**
* Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them
```
Input: *5variable*
Output: 2 14 301 "5"
1 1 101 "variable"
```
## Syntax Analyzer
* *Incomplete*
## Symbol Table
* *TODO: Create diagram.*
Executable
+27
View File
@@ -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
-12
View File
@@ -1,12 +0,0 @@
/* Lexical Analysis with Flex (2.6.0) We used some of the code from this manual */
/* so we placed the citation here. */
/* definitions */
%option noyywrap
%{
#include <typedefs.h>
%}
%%
//rules
%%
//user code
Executable
BIN
View File
Binary file not shown.
View File
+264
View File
@@ -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;
} */
+98
View File
@@ -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);yylval.words = strdup(yytext);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);yylval.words = strdup(yytext);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);yylval.words = strdup(yytext);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);yylval.words = strdup(yytext);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);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;}}
{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
View File
@@ -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;
top = 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;
}
+52
View File
@@ -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);
+198
View File
@@ -0,0 +1,198 @@
/* Symbol Table */
/* The Translators - Spring 2025 */
#include "symbol_table.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
char * typey = "type";
char * funy = "function";
SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) {
SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable));
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;
}
//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");
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;
}
TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode));
newEntry->theType = topDef->theName;
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;
}
}
//we use false for type defs and true for functions for parameter of typeOf
TableNode* Define(SymbolTable* table, bool typeOf, char* id) {
if(table ==NULL || table->Parent_Scope != NULL){
printf("No valid table given for header defs\n");
return NULL;
}
TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode));
//possible issues with referencing text instead of heap
if(typeOf == 0){
newEntry->theType = typey;
}
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;
}
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;
}
if ( entrie == NULL ) {
fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "",
current_scope, parant_scope, "", "Empty Scope");
}
for (; entrie != NULL; entrie = entrie->next) {
if (parant_scope == 0) {
fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n",
entrie->theName, current_scope, entrie->theType,
"Extra annotation");
} 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;
}
*/
+42
View File
@@ -0,0 +1,42 @@
#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);
View File
@@ -0,0 +1 @@
daskmskdfm
@@ -0,0 +1 @@
(***)
@@ -0,0 +1 @@
(*(**)*)
@@ -0,0 +1,7 @@
(*(**)*)
(***)
(******)(*\kpp*********)
((*((*))
(***)(*)
(* *)
(***)))))))*(*))))))))*))
+9
View File
@@ -0,0 +1,9 @@
(* hello *)
(* hello *)
(* I'd think this is a legal "string" that contains several \n \t
escaped characters, isn't it? *)
(* \ *)
(* *)
(*{COMMENT}+ *)
(* * *)
(* (hello) *)
+29
View File
@@ -0,0 +1,29 @@
while
While
whiLe
if
IF
If
iF
then
Then
theN
else
eLse
elSe
Else
type
Type
tyPe
function
Function
functioN
return
Return
returN
external
External
exteRnal
as
As
aS
+23
View File
@@ -0,0 +1,23 @@
+
-
*
/
\
%
<
>
=
:=
=:
:
=
!
&
|
.
relEASE
release
RELEASE
reserve
RESERVE
reSERVe
+6
View File
@@ -0,0 +1,6 @@
;
:
,
->
->>
-->
@@ -0,0 +1,42 @@
)
a)
)a
)*
*)
(* jellsls
well this seems to work
*)
(
a(
(a
(*
*(
{
a{
{a
{*
*{
}
a}
}a
}*
*}
[
a[
[a
[*
*[
]
a]
]a
]*
*]
@@ -0,0 +1,28 @@
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); (* see types.alpha reserve returns a value of type address,
which can be assigned to array and record variables
*)
w.x := 5;
w.y := 7;
result := bar1(w); (* pass w (a rec type value) to bar1 *)
result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)
return 0;
}
@@ -0,0 +1,26 @@
(* Type definitions *)
type string: 1 -> character
type int2int: integer -> integer
type string2int: string -> integer
(* Function prototypes
They use the above type definitions
*)
function square : int2int
function entry : string2int
(* Function definition
Functions must be declared before they are defined
*)
square(x) := {
return x * x;
}
(* Function definition
entry is the first function called
*)
entry(arg) := {
input = 7;
expected = 49;
actual := square(input);
rseult := expected = actual;
return 0;
[ integer: input; integer: expected; integer: actual; boolean: result; string: input ]
}
+5
View File
@@ -0,0 +1,5 @@
45
123
8392
40 40
200 50 21783
@@ -0,0 +1,47 @@
"this is a string" 721398 'g' '/n' (* should print 3 tokens before this *)
'
'
12893 "this is not a string (*one valid token before this*)
(* spacey comment here
over multiple lines
will it work? *) false
"
'''
'\'
false
(**)
'''
nullfalse
"nulltrue
null
'7'
true
'189
'\t'
'"'
'/'
'\n'
'\''
'\t'
'\\'
'n'
'\'
'fdsf'
(*/jnewjno2893u86^ Lots of random characters /n /t '") *)
'
'
' '
'''
"STRINGwithnotSPaces"
' '
'\ '
"J"
""
" "
\"\"
"{SCHAR}"
"SCHAR"
"[SCHAR]"
"FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?"
"I'd think this is a legal \"string\" that contains several \\n \t escaped characters, isn't it?"
nullLike
+10
View File
@@ -0,0 +1,10 @@
valid1
Valid2
_valid3
_valid_name_4
VALID
0Invalid
1invalid
"invalid
invalid=
String
+48
View File
@@ -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;
}
}
+74
View File
@@ -0,0 +1,74 @@
#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;
}
+41
View File
@@ -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;
}
+30
View File
@@ -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
+74
View File
@@ -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;
}
+1
View File
@@ -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; }
+4
View File
@@ -0,0 +1,4 @@
entry(arg) := {
[integer:x]
x := 3 + 2 * 8;
}
+5
View File
@@ -0,0 +1,5 @@
entry(arg) := {
[int : x]
return 0;
}