aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assign.txt55
-rw-r--r--pc.c121
-rw-r--r--pc.h5
-rw-r--r--pc.l220
-rw-r--r--pc.y242
5 files changed, 643 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+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
+
+%%
+
+<COMMENT>. {}
+<COMMENT>\n {}
+
+^[ \t]*"{" {BEGIN COMMENT;}
+<COMMENT> "}" {BEGIN INITIAL;}
+
+^[ \t]*"(*" {BEGIN COMMENT;}
+<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 <opval> ADDOP
+%token <opval> MULOP
+%token <opval> RELOP
+
+%token ADD SUB
+%token MUL DIV
+
+%token NOT
+%token AND OR
+
+%token EQ NE
+%token LT LE
+%token GT GE
+
+%token <ival> INUM
+%token <rval> 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
+ {
+ }
+;
+
+%%