From a0c24cda8b41254c97fe6017523779ec7e6abe6b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Tue, 2 Jul 2019 19:02:17 -0400 Subject: Initial Commit --- assign.txt | 55 ++++++++++++++ pc.c | 121 +++++++++++++++++++++++++++++++ pc.h | 5 ++ pc.l | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pc.y | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 643 insertions(+) create mode 100644 assign.txt create mode 100644 pc.c create mode 100644 pc.h create mode 100644 pc.l create mode 100644 pc.y diff --git a/assign.txt b/assign.txt new file mode 100644 index 0000000..9a886cb --- /dev/null +++ b/assign.txt @@ -0,0 +1,55 @@ +Project: DRAGON +=============== + +- Arrange an online demo of your compiler during Finals week (15min). + +- Send a self-contained compressed tar source of your compiler by + email. Your compiler must run on the ITL machines. + +- Submit a hardcopy of your compiler documentation: design document, + user manual, testing report, status report (limitations, caveats, or + bugs), and a "dragon" haiku. Indicate clearly in your report an + extra feature that is unique to your compiler. + +CHECK LIST +---------- +(1.0) Lexical Analysis + a. Line numbering + b. Two styles of comments + c. (optional) Scientific notation + +(1.5) Syntax Analysis: grammar adjustments + a. Unlimited nesting of subprograms + b. Array access on both sides of assignment + c. Allow for statements. + d. (optional) Another loop construct + e. (optional) Multidimensional arrays + f. (optional) Records and pointers + +(2.0) Symbol Table + a. Memory-leak handler + b. (optional) Statistical analysis of hashpjw + +(2.5) Syntax Tree (Intermediate Code Generation) + a. Visual print + b. Memory-leak handler + +(3.0) Semantic Analysis & Type Checking + a. Check list + b. Error reporting + c. (optional) Error recovery + +(4.0) Code Generation + a. Input/Output statements + b. Simple expressions (arithmetic and relational): gencode + c. Statements (assignment, conditional, loop) + d. Nonlocal names: base frame pointer (static scope parent) + e. Recursive routines (example: GCD program) + f. Complex expressions (register spilling) + g. (optional) Arrays (L-value, R-value, parameters, nonlocal) + h. (optional) Floating-point support + +Extra Trails (under construction) +- Lambda or Objects. +- Code generator for IA64 or SPARC (RISC architecture). +- Code optimization. diff --git a/pc.c b/pc.c new file mode 100644 index 0000000..19a7767 --- /dev/null +++ b/pc.c @@ -0,0 +1,121 @@ +#include +#include +#include + +char* pretty_type(t) +int t; +{ + if (t == ARRAY) { + return "ARRAY"; + } else if (t == INT - ARRAY) { + return "ARRAY of INT"; + } else if (t == INT - ARRAY) { + return "ARRAY of INT"; + } else if (t == INT) { + return "INT"; + } else if (t == REAL) { + return "REAL"; + } else if (t == BOOL) { + return "BOOL"; + } else if (t == -1) { + return "NO TYPE"; + } else { + return "Unknown type"; + } +} + +void debug_print(d, y) +int d; +union YYSTYPE* y; +{ +#ifdef DEBUG + if (d == PROG){ + fprintf(stderr, "[PROG]"); + } else if (d == VAR){ + fprintf(stderr, "[VAR]"); + } else if (d == PROC){ + fprintf(stderr, "[PROC]"); + } else if (d == FUNC){ + fprintf(stderr, "[FUNC]"); + } else if (d == BEG){ + fprintf(stderr, "[BEG]"); + } else if (d == END){ + fprintf(stderr, "[END]"); + } else if (d == ARRAY){ + fprintf(stderr, "[ARRAY]"); + } else if (d == OF){ + fprintf(stderr, "[OF]"); + } else if (d == INT){ + fprintf(stderr, "[INT]"); + } else if (d == REAL){ + fprintf(stderr, "[REAL]"); + } else if (d == IF){ + fprintf(stderr, "[IF]"); + } else if (d == THEN){ + fprintf(stderr, "[THEN]"); + } else if (d == ELSE){ + fprintf(stderr, "[ELSE]"); + } else if (d == WHILE){ + fprintf(stderr, "[WHILE]"); + } else if (d == DO){ + fprintf(stderr, "[DO]"); + } else if (d == NOT){ + fprintf(stderr, "[NOT]"); + } else if (d == DOTS){ + fprintf(stderr, "[ .. ]"); + } else if (d == ASSIGNOP){ + fprintf(stderr, "[ASSIGN]"); + } else if (d == RELOP){ + fprintf(stderr, "[RELOP:"); + if (y->opval == EQ){ + fprintf(stderr, "EQ"); + } else if (y->opval == NE){ + fprintf(stderr, "NE"); + } else if (y->opval == LT){ + fprintf(stderr, "LT"); + } else if (y->opval == LE){ + fprintf(stderr, "LE"); + } else if (y->opval == GT){ + fprintf(stderr, "GT"); + } else if (y->opval == GE){ + fprintf(stderr, "GE"); + } else if (y->opval == ADD){ + fprintf(stderr, "ADD"); + } else if (y->opval == SUB){ + fprintf(stderr, "SUB"); + } else if (y->opval == OR){ + fprintf(stderr, "OR"); + } else if (y->opval == MUL){ + fprintf(stderr, "MUL"); + } else if (y->opval == DIV){ + fprintf(stderr, "DIV"); + } else if (y->opval == AND){ + fprintf(stderr, "AND"); + } + fprintf(stderr,"]"); + } else if (d == INUM) { + fprintf(stderr, "[INUM: %d]", y->ival); + } else if (d == RNUM) { + fprintf(stderr, "[INUM: %f]", y->rval); + } else if (d == ID) { + fprintf(stderr, "[ID: %s]", y->sval); + } else if (d == '\n') { + fprintf(stderr, "\n"); + } else { + fprintf(stderr, "{%c}", d); + } + fprintf(stderr, " "); +#endif + return; +} + +int yyerror(msg) +char* msg; +{ + fprintf(stderr, "\nError, line %d: %s\n", line_num, msg); +#ifdef DEBUG + fprintf(stderr, "%s\n", yytext); + exit(1); +#endif + return 0; +} diff --git a/pc.h b/pc.h new file mode 100644 index 0000000..009e3ff --- /dev/null +++ b/pc.h @@ -0,0 +1,5 @@ +char* pretty_type(int); + +void debug_print(int, union YYSTYPE*); + +int yyerror(char*); diff --git a/pc.l b/pc.l new file mode 100644 index 0000000..4c8ac40 --- /dev/null +++ b/pc.l @@ -0,0 +1,220 @@ +%{ + +#include "pc.h" +#include "y.tab.h" + +int line_num=1; + +%} + +whitespace [ \t]+ +number [0-9]+ +id [A-Za-z][A-Za-z0-9_]* + +%x COMMENT + +%% + +. {} +\n {} + +^[ \t]*"{" {BEGIN COMMENT;} + "}" {BEGIN INITIAL;} + +^[ \t]*"(*" {BEGIN COMMENT;} +"*)" {BEGIN INITIAL;} + + +{whitespace} ; + +"program" { + debug_print(PROG, NULL); + return PROG; +} + +"var" { + debug_print(VAR, NULL); + return VAR; +} + +"procedure" { + debug_print(PROC, NULL); + s = push_scope(s); + return PROC; +} + +"function" { + debug_print(FUNC, NULL); + s = push_scope(s); + return FUNC; +} + +"begin" { + debug_print(BEG, NULL); + return BEG; +} + +"end" { + debug_print(END, NULL); + return END; +} + +"array" { + debug_print(ARRAY, NULL); + return ARRAY; +} + +"of" { + debug_print(OF, NULL); + return OF; +} + +"integer" { + debug_print(INT, NULL); + return INT; +} + +"real" { + debug_print(REAL, NULL); + return REAL; +} + +"if" { + debug_print(IF, NULL); + return IF; +} + +"then" { + debug_print(THEN, NULL); + return THEN; +} + +"else" { + debug_print(ELSE, NULL); + return ELSE; +} + +"while" { + debug_print(WHILE, NULL); + return WHILE; +} + +"do" { + debug_print(DO, NULL); + return DO; +} + +"not" { + debug_print(NOT, NULL); + return NOT; +} + +".." { + debug_print(DOTS, NULL); + return DOTS; +} + +":=" { + debug_print(ASSIGNOP, NULL); + return ASSIGNOP; +} + +"=" { + yylval.opval = EQ; + debug_print(RELOP, &yylval); + return RELOP; +} + +"<>" { + yylval.opval = NE; + debug_print(RELOP, &yylval); + return RELOP; +} + +"<" { + yylval.opval = LT; + debug_print(RELOP, &yylval); + return RELOP; +} + +"<=" { + yylval.opval = LE; + debug_print(RELOP, &yylval); + return RELOP; +} + +">" { + yylval.opval = GT; + debug_print(RELOP, &yylval); + return RELOP; +} + +">=" { + yylval.opval = GE; + debug_print(RELOP, &yylval); + return RELOP; +} + +"+" { + yylval.opval = ADD; + debug_print(RELOP, &yylval); + return ADDOP; +} + +"-" { + yylval.opval = SUB; + debug_print(RELOP, &yylval); + return ADDOP; +} + +"or" { + yylval.opval = OR; + debug_print(RELOP, &yylval); + return ADDOP; +} + +"*" { + yylval.opval = MUL; + debug_print(RELOP, &yylval); + return MULOP; +} + +"/" { + yylval.opval = DIV; + debug_print(RELOP, &yylval); + return MULOP; +} + +"and" { + yylval.opval = AND; + debug_print(RELOP, &yylval); + return MULOP; +} + +{number} { + yylval.ival = atoi(yytext); + debug_print(INUM, &yylval); + return INUM; +} + +{number}"."{number} { + yylval.rval = atof(yytext); + debug_print(RNUM, &yylval); + return RNUM; +} + +{id} { + yylval.sval = strdup(yytext); + debug_print(ID, &yylval); + return ID; +} + +\n { + debug_print('\n', NULL); + ++line_num; +} + +. { + debug_print(yytext[0], NULL); + return yytext[0]; +} diff --git a/pc.y b/pc.y new file mode 100644 index 0000000..80d786b --- /dev/null +++ b/pc.y @@ -0,0 +1,242 @@ +%{ + +#include "pc.h" +#include "y.tab.h" +#include "sem_check.h" + +%} + +%union { + int ival; + float rval; + char *sval; + int opval; + struct parse_tree *tval; +} + +%token PROG +%token VAR +%token PROC FUNC +%token BEG END + +%token ADDOP +%token MULOP +%token RELOP + +%token ADD SUB +%token MUL DIV + +%token NOT +%token AND OR + +%token EQ NE +%token LT LE +%token GT GE + +%token INUM +%token RNUM + +%token INT REAL +%token BOOL + +%token ARRAY OF +%token DOTS + +%token IF ELSE THEN +%token WHILE DO + +%token FCALL PCALL +%token ACCESS + +%token LIST + +%% + +program + :PROG ID '(' id_list ')' ';' + var_declarations + sub-prog declarations + compound_statemnt + '.' + { + } +; + +id_list + :ID + { + } + |id_list ',' ID + { + } +; + +var_declarations + :var_declarations VAR id_list ':' type ';' + { + } + |/*empty*/ +; + +type + :standard_type + { + } + |ARRAY '[' INUM DOTS INUM ']' OF standard_type + { + } +; + +standard_type + :INT + { + } + |REAL + { + } +; + +sub-prog_declarations + :sub-prog_declarations sub-prog_declaration ';' + { + } + |/*empty*/ +; +sub-prog_declaration + :sub-prog_head + declarations + sub-prog_declarations + compound_statument + { + } +; + +sub-prog_head + :FUNC ID arguments ':' standard_type ';' + { + } + |PROC ID arguments ';' + { + } +; + +arguments + :id_list ':' type + { + } + |param_list ';' id_list ':' type + { + } +; + +compound_statement + :BEG optional_statments END + { + } +; + +optional_statements + : statement_list + { + } + |/*empty*/ + { + } +; + +statement_list + :statement + { + } + |statement_list ';' statement + { + } +; +statement + : var ASSIGNOP expression + { + } + |proc_statement + { + } + |compound_statement + { + } + |IF expression THEN statement ELSE statement + { + } + |WHILE expression DO statement + { + } +; + +var + :ID + { + } + |ID '[' expression ']' + { + } +; + +proc_statement + :ID + { + } + |ID '(' expression_list ')' + { + } +; + +expression_list + :expression + { + } + |expression_list ',' expression + { + } +; + +expression + :simple_expression + { + } + |simple_expression RELOP simple_expression + { + } +; + +term + :factor + { + } + |term MULOP factor + { + } +; + +factor + :ID + { + } + |ID '[' expression ']' + { + } + |ID '(' expression_list ')' + { + } + |INUM + { + } + |RNUM + { + } + | '(' expression ')' + { + } + |NOT factor + { + } +; + +%% -- cgit v1.1