summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkugwa <kugwa2000@gmail.com>2015-11-11 19:06:01 +0800
committerkugwa <kugwa2000@gmail.com>2015-11-11 19:06:01 +0800
commit62d9753dac503b34bb27635faf96a395d465f54d (patch)
tree62c06eaa6e0a06fdad263b27fc0843bd2af7d46d
parent97c3aabffdc7ed612d322dd839f9ae4ab76efc6a (diff)
downloadcompiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar.gz
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar.bz2
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar.lz
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar.xz
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.tar.zst
compiler2015-62d9753dac503b34bb27635faf96a395d465f54d.zip
Merge TA's codes to ours
Delete tmp funtion used in HW2. Move AST functions into ast.c. CONST_INT, CONST_FLOAT, and CONST_STRING all return CONST.
-rw-r--r--Makefile.am31
-rw-r--r--configure.ac3
-rw-r--r--src/ast.c114
-rw-r--r--src/ast.h179
-rw-r--r--src/lexer.l110
-rw-r--r--src/main.c36
-rw-r--r--src/parser.y580
-rw-r--r--src/symbol-table.c27
-rw-r--r--src/symbol-table.h1
9 files changed, 937 insertions, 144 deletions
diff --git a/Makefile.am b/Makefile.am
index 8ff35f6..53844b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,29 +4,33 @@ NULL =
EXTRA_DIST = autogen.sh Makefile.simple
-bin_PROGRAMS = scanner
-noinst_LIBRARIES = liblexer.a
+bin_PROGRAMS = parser
+noinst_LIBRARIES = libparser.a
AM_CPPFLAGS = -I$(top_srcdir)/src
-scanner_CFLAGS = $(WARN_CFLAGS)
-scanner_SOURCES = \
- lexer.h \
+parser_CFLAGS = $(WARN_CFLAGS)
+parser_SOURCES = \
src/main.c \
+ src/ast.h \
+ src/ast.c \
src/symbol-table.h \
src/symbol-table.c \
$(NULL)
-scanner_LDADD = \
- liblexer.a \
+parser_LDADD = \
+ libparser.a \
$(NULL)
-liblexer_a_LFLAGS = --header-file=lexer.h
-liblexer_a_SOURCES = \
+libparser_a_YFLAGS = -d
+libparser_a_SOURCES = \
src/lexer.l \
+ src/parser.y \
$(NULL)
-lexer.h: src/liblexer_a-lexer.c
-BUILT_SOURCES = lexer.h
+src/lexer.o:
+ @touch src/lexer.o
+
+BUILT_SOURCES = src/lexer.c
submit_dir_name = hw
submit_tarball_prefix = b01902054_b01902062
@@ -34,8 +38,9 @@ submit: dist
tar -zxf $(DIST_ARCHIVES)
mv $(distdir) $(submit_dir_name)
cp -a $(submit_dir_name)/Makefile.simple $(submit_dir_name)/Makefile
- rm $(submit_dir_name)/src/liblexer_a-lexer.c
- rm $(submit_dir_name)/lexer.h
+ rm $(submit_dir_name)/src/lexer.c
+ rm $(submit_dir_name)/src/libparser_a-parser.h
+ rm $(submit_dir_name)/src/libparser_a-parser.c
ver=`git rev-list HEAD | wc -l` && tar -jpcf \
$(submit_tarball_prefix)_ver$$ver.tar.bz2 $(submit_dir_name)
rm -rf $(submit_dir_name)
diff --git a/configure.ac b/configure.ac
index a303ded..f25a3fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,8 @@ AM_SILENT_RULES([yes])
AC_PROG_CC
AC_PROG_CC_STDC
AC_PROG_RANLIB
-AM_PROG_LEX
+AC_PROG_LEX
+AC_PROG_YACC
# Checks for warning flags.
AX_IS_RELEASE([git-directory])
diff --git a/src/ast.c b/src/ast.c
new file mode 100644
index 0000000..7c35744
--- /dev/null
+++ b/src/ast.c
@@ -0,0 +1,114 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ast.h"
+
+extern int line_number;
+
+AST_NODE *Allocate(AST_TYPE type)
+{
+ AST_NODE *temp;
+ temp = (AST_NODE*)malloc(sizeof(struct AST_NODE));
+ temp->nodeType = type;
+ temp->dataType = NONE_TYPE;
+ temp->child = NULL;
+ temp->rightSibling = NULL;
+ temp->parent = NULL;
+ // Notice that leftmostSibling is not initialized as NULL
+ temp->leftmostSibling = temp;
+ temp->linenumber = line_number;
+ return temp;
+}
+
+AST_NODE* makeSibling(AST_NODE *a, AST_NODE *b)
+{
+ while (a->rightSibling) {
+ a = a->rightSibling;
+ }
+ if (b == NULL) {
+ return a;
+ }
+ b = b->leftmostSibling;
+ a->rightSibling = b;
+
+ b->leftmostSibling = a->leftmostSibling;
+ b->parent = a->parent;
+ while (b->rightSibling) {
+ b = b->rightSibling;
+ b->leftmostSibling = a->leftmostSibling;
+ b->parent = a->parent;
+ }
+ return b;
+}
+
+AST_NODE* makeChild(AST_NODE *parent, AST_NODE *child)
+{
+ if (child == NULL) {
+ return parent;
+ }
+ if (parent->child) {
+ makeSibling(parent->child, child);
+ } else {
+ child = child->leftmostSibling;
+ parent->child = child;
+ while (child) {
+ child->parent = parent;
+ child = child->rightSibling;
+ }
+ }
+ return parent;
+}
+
+AST_NODE* makeFamily(AST_NODE *parent, int childrenCount, ...)
+{
+ va_list childrenList;
+ va_start(childrenList, childrenCount);
+ AST_NODE* child = va_arg(childrenList, AST_NODE*);
+ makeChild(parent, child);
+ AST_NODE* tmp = child;
+ int index = 1;
+ for (index = 1; index < childrenCount; ++index) {
+ child = va_arg(childrenList, AST_NODE*);
+ tmp = makeSibling(tmp, child);
+ }
+ va_end(childrenList);
+ return parent;
+}
+
+AST_NODE* makeIDNode(char *lexeme, IDENTIFIER_KIND idKind)
+{
+ AST_NODE* identifier = Allocate(IDENTIFIER_NODE);
+ identifier->semantic_value.identifierSemanticValue.identifierName = lexeme;
+ identifier->semantic_value.identifierSemanticValue.kind = idKind;
+ identifier->semantic_value.identifierSemanticValue.symbolTableEntry = NULL;
+ return identifier;
+}
+
+AST_NODE* makeStmtNode(STMT_KIND stmtKind)
+{
+ AST_NODE* stmtNode = Allocate(STMT_NODE);
+ stmtNode->semantic_value.stmtSemanticValue.kind = stmtKind;
+ return stmtNode;
+}
+
+AST_NODE* makeDeclNode(DECL_KIND declKind)
+{
+ AST_NODE* declNode = Allocate(DECLARATION_NODE);
+ declNode->semantic_value.declSemanticValue.kind = declKind;
+ return declNode;
+}
+
+AST_NODE* makeExprNode(EXPR_KIND exprKind, int operationEnumValue)
+{
+ AST_NODE* exprNode = Allocate(EXPR_NODE);
+ exprNode->semantic_value.exprSemanticValue.isConstEval = 0;
+ exprNode->semantic_value.exprSemanticValue.kind = exprKind;
+ if (exprKind == BINARY_OPERATION) {
+ exprNode->semantic_value.exprSemanticValue.op.binaryOp = operationEnumValue;
+ } else if (exprKind == UNARY_OPERATION) {
+ exprNode->semantic_value.exprSemanticValue.op.unaryOp = operationEnumValue;
+ } else {
+ printf("Error in AST_NODE* makeExprNode(EXPR_KIND exprKind, int operationEnumValue)\n");
+ }
+ return exprNode;
+}
diff --git a/src/ast.h b/src/ast.h
new file mode 100644
index 0000000..ada37f4
--- /dev/null
+++ b/src/ast.h
@@ -0,0 +1,179 @@
+#ifndef CCMMC_HEADER_AST_H
+#define CCMMC_HEADER_AST_H
+
+#define MAX_ARRAY_DIMENSION 7
+
+typedef enum DATA_TYPE
+{
+ INT_TYPE,
+ FLOAT_TYPE,
+ VOID_TYPE,
+ INT_PTR_TYPE,//for parameter passing
+ FLOAT_PTR_TYPE,//for parameter passing
+ CONST_STRING_TYPE,//for "const string"
+ NONE_TYPE,//for nodes like PROGRAM_NODE which has no type
+ ERROR_TYPE
+} DATA_TYPE;
+
+typedef enum IDENTIFIER_KIND
+{
+ NORMAL_ID, //function Name, uninitialized scalar variable
+ ARRAY_ID, //ID_NODE->child = dim
+ WITH_INIT_ID, //ID_NODE->child = initial value
+} IDENTIFIER_KIND;
+
+typedef enum BINARY_OPERATOR
+{
+ BINARY_OP_ADD,
+ BINARY_OP_SUB,
+ BINARY_OP_MUL,
+ BINARY_OP_DIV,
+ BINARY_OP_EQ,
+ BINARY_OP_GE,
+ BINARY_OP_LE,
+ BINARY_OP_NE,
+ BINARY_OP_GT,
+ BINARY_OP_LT,
+ BINARY_OP_AND,
+ BINARY_OP_OR
+} BINARY_OPERATOR;
+
+typedef enum UNARY_OPERATOR
+{
+ UNARY_OP_POSITIVE,
+ UNARY_OP_NEGATIVE,
+ UNARY_OP_LOGICAL_NEGATION
+} UNARY_OPERATOR;
+
+//C_type= type of constant ex: 1, 3.3, "const string"
+//do not modify, or lexer might break
+typedef enum C_type {INTEGERC,FLOATC,STRINGC} C_type;
+
+typedef enum STMT_KIND
+{
+ WHILE_STMT,
+ FOR_STMT,
+ ASSIGN_STMT, //TODO:for simpler implementation, assign_expr also uses this
+ IF_STMT,
+ FUNCTION_CALL_STMT,
+ RETURN_STMT,
+} STMT_KIND;
+
+typedef enum EXPR_KIND
+{
+ BINARY_OPERATION,
+ UNARY_OPERATION
+} EXPR_KIND;
+
+typedef enum DECL_KIND
+{
+ VARIABLE_DECL,
+ TYPE_DECL,
+ FUNCTION_DECL,
+ FUNCTION_PARAMETER_DECL
+} DECL_KIND;
+
+typedef enum AST_TYPE
+{
+ PROGRAM_NODE,
+ DECLARATION_NODE,
+ IDENTIFIER_NODE,
+ PARAM_LIST_NODE,
+ NUL_NODE,
+ BLOCK_NODE,
+ VARIABLE_DECL_LIST_NODE,
+ STMT_LIST_NODE,
+ STMT_NODE,
+ EXPR_NODE,
+ CONST_VALUE_NODE, //ex:1, 2, "constant string"
+ NONEMPTY_ASSIGN_EXPR_LIST_NODE,
+ NONEMPTY_RELOP_EXPR_LIST_NODE
+} AST_TYPE;
+
+//*************************
+// AST_NODE's semantic value
+//*************************
+
+typedef struct STMTSemanticValue
+{
+ STMT_KIND kind;
+} STMTSemanticValue;
+
+typedef struct EXPRSemanticValue
+{
+ EXPR_KIND kind;
+
+ int isConstEval;
+
+ union
+ {
+ int iValue;
+ float fValue;
+ } constEvalValue;
+
+ union
+ {
+ BINARY_OPERATOR binaryOp;
+ UNARY_OPERATOR unaryOp;
+ } op;
+} EXPRSemanticValue;
+
+typedef struct DECLSemanticValue
+{
+ DECL_KIND kind;
+} DECLSemanticValue;
+
+struct SymbolAttribute;
+
+typedef struct IdentifierSemanticValue
+{
+ char *identifierName;
+ struct SymbolTableEntry *symbolTableEntry;
+ IDENTIFIER_KIND kind;
+} IdentifierSemanticValue;
+
+typedef struct TypeSpecSemanticValue
+{
+ char *typeName;
+} TypeSpecSemanticValue;
+
+//don't modify or lexer may break
+typedef struct CON_Type{
+ C_type const_type;
+ union {
+ int intval;
+ double fval;
+ char *sc; }
+ const_u;
+} CON_Type;
+
+
+struct AST_NODE {
+ struct AST_NODE *child;
+ struct AST_NODE *parent;
+ struct AST_NODE *rightSibling;
+ struct AST_NODE *leftmostSibling;
+ AST_TYPE nodeType;
+ DATA_TYPE dataType;
+ int linenumber;
+ union {
+ IdentifierSemanticValue identifierSemanticValue;
+ STMTSemanticValue stmtSemanticValue;
+ DECLSemanticValue declSemanticValue;
+ EXPRSemanticValue exprSemanticValue;
+ CON_Type *const1;
+ } semantic_value;
+};
+typedef struct AST_NODE AST_NODE;
+
+AST_NODE *Allocate(AST_TYPE type);
+AST_NODE* makeSibling(AST_NODE *a, AST_NODE *b);
+AST_NODE* makeChild(AST_NODE *parent, AST_NODE *child);
+AST_NODE* makeFamily(AST_NODE *parent, int childrenCount, ...);
+AST_NODE* makeIDNode(char *lexeme, IDENTIFIER_KIND idKind);
+AST_NODE* makeStmtNode(STMT_KIND stmtKind);
+AST_NODE* makeDeclNode(DECL_KIND declKind);
+AST_NODE* makeExprNode(EXPR_KIND exprKind, int operationEnumValue);
+void semanticAnalysis(AST_NODE *root);
+
+#endif
diff --git a/src/lexer.l b/src/lexer.l
index 07e3dbd..b15668d 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -7,50 +7,7 @@
#define SIZE_OF_ARR(x) (sizeof(x)/sizeof(x[0]))
-static int line_number = 1;
-
-/* You need to define for all tokens in C--, here are some examples */
-typedef enum CcmmcToken_enum {
- CCMMC_TOKEN_ID = 1,
- CCMMC_TOKEN_CONST_INT,
- CCMMC_TOKEN_CONST_FLOAT,
- CCMMC_TOKEN_CONST_STRING,
- CCMMC_TOKEN_COMMENT,
- CCMMC_TOKEN_OP_ASSIGN,
- CCMMC_TOKEN_OP_OR,
- CCMMC_TOKEN_OP_AND,
- CCMMC_TOKEN_OP_NOT,
- CCMMC_TOKEN_OP_ADD,
- CCMMC_TOKEN_OP_SUB,
- CCMMC_TOKEN_OP_MUL,
- CCMMC_TOKEN_OP_DIV,
- CCMMC_TOKEN_OP_GT,
- CCMMC_TOKEN_OP_LT,
- CCMMC_TOKEN_OP_GE,
- CCMMC_TOKEN_OP_LE,
- CCMMC_TOKEN_OP_NE,
- CCMMC_TOKEN_OP_EQ,
- CCMMC_TOKEN_DL_LPAREN,
- CCMMC_TOKEN_DL_RPAREN,
- CCMMC_TOKEN_DL_LBRACK,
- CCMMC_TOKEN_DL_RBRACK,
- CCMMC_TOKEN_DL_LBRACE,
- CCMMC_TOKEN_DL_RBRACE,
- CCMMC_TOKEN_DL_COMMA,
- CCMMC_TOKEN_DL_SEMICOL,
- CCMMC_TOKEN_DL_DOT,
- CCMMC_TOKEN_NEWLINE,
- CCMMC_TOKEN_RETURN,
- CCMMC_TOKEN_TYPEDEF,
- CCMMC_TOKEN_IF,
- CCMMC_TOKEN_ELSE,
- CCMMC_TOKEN_INT,
- CCMMC_TOKEN_FLOAT,
- CCMMC_TOKEN_FOR,
- CCMMC_TOKEN_VOID,
- CCMMC_TOKEN_WHILE,
- CCMMC_TOKEN_ERROR = 100
-} CcmmcToken;
+int line_number = 1;
%}
letter [A-Za-z]
@@ -102,15 +59,8 @@ ERROR .
int i;
char *reserved[] = {"return", "typedef", "if", "else",
"int", "float", "for", "void", "while"};
- CcmmcToken reserved_token[] = {CCMMC_TOKEN_RETURN,
- CCMMC_TOKEN_TYPEDEF,
- CCMMC_TOKEN_IF,
- CCMMC_TOKEN_ELSE,
- CCMMC_TOKEN_INT,
- CCMMC_TOKEN_FLOAT,
- CCMMC_TOKEN_FOR,
- CCMMC_TOKEN_VOID,
- CCMMC_TOKEN_WHILE};
+ enum yytokentype reserved_token[] = {RETURN, TYPEDEF,
+ IF, ELSE, INT, FLOAT, FOR, VOID, WHILE};
static_assert(
SIZE_OF_ARR(reserved) == SIZE_OF_ARR(reserved_token),
"Reserved words array and reserved tokens array "
@@ -127,11 +77,11 @@ ERROR .
else
ptr->counter++;
}
- return CCMMC_TOKEN_ID;
+ return ID;
}
-{CONST_INT} return CCMMC_TOKEN_CONST_INT;
-{CONST_FLOAT} return CCMMC_TOKEN_CONST_FLOAT;
-{CONST_STRING} return CCMMC_TOKEN_CONST_STRING;
+{CONST_INT} return CONST; //TODO
+{CONST_FLOAT} return CONST;
+{CONST_STRING} return CONST;
{COMMENT} {
int i;
@@ -139,32 +89,32 @@ ERROR .
if (yytext[i] == '\n')
line_number++;
}
-{OP_ASSIGN} return CCMMC_TOKEN_OP_ASSIGN;
-{OP_OR} return CCMMC_TOKEN_OP_OR;
-{OP_AND} return CCMMC_TOKEN_OP_AND;
-{OP_NOT} return CCMMC_TOKEN_OP_NOT;
-{OP_ADD} return CCMMC_TOKEN_OP_ADD;
-{OP_SUB} return CCMMC_TOKEN_OP_SUB;
-{OP_MUL} return CCMMC_TOKEN_OP_MUL;
-{OP_DIV} return CCMMC_TOKEN_OP_DIV;
-{OP_GT} return CCMMC_TOKEN_OP_GT;
-{OP_LT} return CCMMC_TOKEN_OP_LT;
-{OP_GE} return CCMMC_TOKEN_OP_GE;
-{OP_LE} return CCMMC_TOKEN_OP_LE;
-{OP_NE} return CCMMC_TOKEN_OP_NE;
-{OP_EQ} return CCMMC_TOKEN_OP_EQ;
+{OP_ASSIGN} return OP_ASSIGN;
+{OP_OR} return OP_OR;
+{OP_AND} return OP_AND;
+{OP_NOT} return OP_NOT;
+{OP_ADD} return OP_ADD;
+{OP_SUB} return OP_SUB;
+{OP_MUL} return OP_MUL;
+{OP_DIV} return OP_DIV;
+{OP_GT} return OP_GT;
+{OP_LT} return OP_LT;
+{OP_GE} return OP_GE;
+{OP_LE} return OP_LE;
+{OP_NE} return OP_NE;
+{OP_EQ} return OP_EQ;
{NEWLINE} line_number++;
-{DL_LPAREN} return CCMMC_TOKEN_DL_LPAREN;
-{DL_RPAREN} return CCMMC_TOKEN_DL_RPAREN;
-{DL_LBRACK} return CCMMC_TOKEN_DL_LBRACK;
-{DL_RBRACK} return CCMMC_TOKEN_DL_RBRACK;
-{DL_LBRACE} return CCMMC_TOKEN_DL_RBRACE;
-{DL_RBRACE} return CCMMC_TOKEN_DL_LBRACE;
-{DL_COMMA} return CCMMC_TOKEN_DL_COMMA;
-{DL_SEMICOL} return CCMMC_TOKEN_DL_SEMICOL;
-{DL_DOT} return CCMMC_TOKEN_DL_DOT;
+{DL_LPAREN} return DL_LPAREN;
+{DL_RPAREN} return DL_RPAREN;
+{DL_LBRACK} return DL_LBRACK;
+{DL_RBRACK} return DL_RBRACK;
+{DL_LBRACE} return DL_LBRACE;
+{DL_RBRACE} return DL_RBRACE;
+{DL_COMMA} return DL_COMMA;
+{DL_SEMICOL} return DL_SEMICOL;
+{DL_DOT} return DL_DOT;
{ERROR} {
fprintf(stderr, "%d: error: undefined character `%s'\n",
diff --git a/src/main.c b/src/main.c
index 49f3b8d..0421e94 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,30 +1,22 @@
#include <stdio.h>
#include <stdlib.h>
-#include "lexer.h"
-#include "symbol-table.h"
+#include "ast.h"
+#include "src/libparser_a-parser.h"
-static int id_compare(const void *a, const void *b) {
- const CcmmcSymbol *aa = *(const CcmmcSymbol**)a;
- const CcmmcSymbol *bb = *(const CcmmcSymbol**)b;
- return strcmp(aa->lexeme, bb->lexeme);
-}
-
-int main(int argc, char **argv) {
- if (argc > 1)
- yyin = fopen(argv[1], "r");
- else
- yyin = stdin;
- yylex();
-
- int len;
- CcmmcSymbol **id_list = ccmmc_symbol_table_tmp(&len);
- qsort(id_list, len, sizeof(CcmmcSymbol*), id_compare);
+extern FILE *yyin;
- puts("Frequency of identifiers:");
- for (int i = 0; i < len; i++) {
- printf("%-15s %d\n", id_list[i]->lexeme, id_list[i]->counter);
+int main (int argc, char **argv)
+{
+ if (argc != 2) {
+ fputs("usage: parser [source file]\n", stderr);
+ exit(1);
}
-
+ yyin = fopen(argv[1],"r");
+ if (yyin == NULL) {
+ fputs("Error opening source file.\n", stderr);
+ exit(1);
+ }
+ yyparse();
return 0;
}
diff --git a/src/parser.y b/src/parser.y
new file mode 100644
index 0000000..47dbff4
--- /dev/null
+++ b/src/parser.y
@@ -0,0 +1,580 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ast.h"
+
+AST_NODE *prog;
+
+extern int g_anyErrorOccur;
+%}
+
+%union{
+ char *lexeme;
+ CON_Type *const1;
+ AST_NODE *node;
+};
+
+%token <lexeme>ID
+%token <const1>CONST
+%token VOID
+%token INT
+%token FLOAT
+%token IF
+%token ELSE
+%token WHILE
+%token FOR
+%token TYPEDEF
+%token OP_ASSIGN
+%token OP_OR
+%token OP_AND
+%token OP_NOT
+%token OP_EQ
+%token OP_NE
+%token OP_GT
+%token OP_LT
+%token OP_GE
+%token OP_LE
+%token OP_ADD
+%token OP_SUB
+%token OP_MUL
+%token OP_DIV
+%token DL_LPAREN
+%token DL_RPAREN
+%token DL_LBRACK
+%token DL_RBRACK
+%token DL_LBRACE
+%token DL_RBRACE
+%token DL_COMMA
+%token DL_SEMICOL
+%token DL_DOT
+%token ERROR
+%token RETURN
+
+%{
+#include "lexer.c"
+
+int yyerror (char *mesg)
+{
+ fprintf(stderr, "Error found in Line \t%d\tnext token: \t%s\n",
+ line_number, yytext);
+ exit(1);
+}
+%}
+
+%type <node> program global_decl_list global_decl function_decl block stmt_list
+%type <node> decl_list decl var_decl type init_id_list init_id stmt relop_expr
+%type <node> relop_term relop_factor expr term factor var_ref param_list param
+%type <node> dim_fn expr_null id_list dim_decl cexpr mcexpr cfactor
+%type <node> assign_expr_list test assign_expr rel_op relop_expr_list
+%type <node> nonempty_relop_expr_list add_op mul_op dim_list type_decl
+%type <node> nonempty_assign_expr_list
+
+%start program
+
+%%
+
+/* ==== Grammar Section ==== */
+
+/* Productions */ /* Semantic actions */
+program : global_decl_list { $$=Allocate(PROGRAM_NODE); makeChild($$,$1); prog=$$;}
+ | { $$=Allocate(PROGRAM_NODE); prog=$$;}
+ ;
+
+global_decl_list: global_decl_list global_decl
+ {
+ $$ = makeSibling($1, $2);
+ }
+ | global_decl
+ {
+ $$ = $1;
+ }
+ ;
+
+global_decl : decl_list function_decl
+ {
+ $$ = makeSibling(makeChild(Allocate(VARIABLE_DECL_LIST_NODE), $1), $2);
+ }
+ | function_decl
+ {
+ $$ = $1;
+ }
+ ;
+
+function_decl : type ID DL_LPAREN param_list DL_RPAREN DL_LBRACE block DL_RBRACE
+ {
+ $$ = makeDeclNode(FUNCTION_DECL);
+ AST_NODE* parameterList = Allocate(PARAM_LIST_NODE);
+ makeChild(parameterList, $4);
+ makeFamily($$, 4, $1, makeIDNode($2, NORMAL_ID), parameterList, $7);
+ }
+ | VOID ID DL_LPAREN param_list DL_RPAREN DL_LBRACE block DL_RBRACE
+ {
+ /*TODO*/
+ }
+ | type ID DL_LPAREN DL_RPAREN DL_LBRACE block DL_RBRACE
+ {
+ $$ = makeDeclNode(FUNCTION_DECL);
+ AST_NODE* emptyParameterList = Allocate(PARAM_LIST_NODE);
+ makeFamily($$, 4, $1, makeIDNode($2, NORMAL_ID), emptyParameterList, $6);
+ }
+ | VOID ID DL_LPAREN DL_RPAREN DL_LBRACE block DL_RBRACE
+ {
+ /*TODO*/
+ }
+ ;
+
+param_list : param_list DL_COMMA param
+ {
+ $$ = makeSibling($1, $3);
+ }
+ | param
+ {
+ /*TODO*/
+ }
+ ;
+
+param : type ID
+ {
+ $$ = makeDeclNode(FUNCTION_PARAMETER_DECL);
+ makeFamily($$, 2, $1, makeIDNode($2, NORMAL_ID));
+ }
+ | type ID dim_fn
+ {
+ /*TODO*/
+ }
+ ;
+dim_fn : DL_LBRACK expr_null DL_RBRACK
+ {
+ $$ = $2;
+ }
+ | dim_fn DL_LBRACK expr DL_RBRACK
+ {
+ $$ = makeSibling($1, $3);
+ }
+ ;
+
+expr_null :expr
+ {
+ /*TODO*/
+ }
+ |
+ {
+ $$ = Allocate(NUL_NODE);
+ }
+ ;
+
+block : decl_list stmt_list
+ {
+ /*TODO*/
+ }
+ | stmt_list
+ {
+ $$ = Allocate(BLOCK_NODE);
+ makeChild($$, makeChild(Allocate(STMT_LIST_NODE), $1));
+ }
+ | decl_list
+ {
+ $$ = Allocate(BLOCK_NODE);
+ makeChild($$, makeChild(Allocate(VARIABLE_DECL_LIST_NODE), $1));
+ }
+ | {
+ /*TODO*/
+ }
+ ;
+
+decl_list : decl_list decl
+ {
+ /*TODO*/
+ }
+ | decl
+ {
+ /*TODO*/
+ }
+ ;
+
+decl : type_decl
+ {
+ $$ = $1;
+ }
+ | var_decl
+ {
+ $$ = $1;
+ }
+ ;
+
+type_decl : TYPEDEF type id_list DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ | TYPEDEF VOID id_list DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ ;
+
+var_decl : type init_id_list DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ | ID id_list DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ ;
+
+type : INT
+ {
+ $$ = makeIDNode("int", NORMAL_ID);
+ }
+ | FLOAT
+ {
+ $$ = makeIDNode("float", NORMAL_ID);
+ }
+ ;
+
+id_list : ID
+ {
+ $$ = makeIDNode($1, NORMAL_ID);
+ }
+ | id_list DL_COMMA ID
+ {
+ /*TODO*/
+ }
+ | id_list DL_COMMA ID dim_decl
+ {
+ /*TODO*/
+ }
+ | ID dim_decl
+ {
+ /*TODO*/
+ }
+ ;
+dim_decl : DL_LBRACK cexpr DL_RBRACK
+ {
+ /*TODO*/
+ }
+ /*TODO: Try if you can define a recursive production rule
+ | .......
+ */
+ ;
+cexpr : cexpr OP_ADD mcexpr
+ {
+ $$ = makeExprNode(BINARY_OPERATION, BINARY_OP_ADD);
+ makeFamily($$, 2, $1, $3);
+ } /* This is for array declarations */
+ | cexpr OP_SUB mcexpr
+ {
+ /*TODO*/
+ }
+ | mcexpr
+ {
+ /*TODO*/
+ }
+ ;
+mcexpr : mcexpr OP_MUL cfactor
+ {
+ /*TODO*/
+ }
+ | mcexpr OP_DIV cfactor
+ {
+ /*TODO*/
+ }
+ | cfactor
+ {
+ /*TODO*/
+ }
+ ;
+
+cfactor: CONST
+ {
+ /*TODO*/
+ }
+ | DL_LPAREN cexpr DL_RPAREN
+ {
+ /*TODO*/
+ }
+ ;
+
+init_id_list : init_id
+ {
+ /*TODO*/
+ }
+ | init_id_list DL_COMMA init_id
+ {
+ /*TODO*/
+ }
+ ;
+
+init_id : ID
+ {
+ $$ = makeIDNode($1, NORMAL_ID);
+ }
+ | ID dim_decl
+ {
+ /*TODO*/
+ }
+ | ID OP_ASSIGN relop_expr
+ {
+ /*TODO*/
+ }
+ ;
+
+stmt_list : stmt_list stmt
+ {
+ /*TODO*/
+ }
+ | stmt
+ {
+ /*TODO*/
+ }
+ ;
+
+
+
+stmt : DL_LBRACE block DL_RBRACE
+ {
+ /*TODO*/
+ }
+ /*TODO: | While Statement */
+ | FOR DL_LPAREN assign_expr_list DL_SEMICOL relop_expr_list DL_SEMICOL assign_expr_list DL_RPAREN stmt
+ {
+ /*TODO*/
+ }
+ | var_ref OP_ASSIGN relop_expr DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ /*TODO: | If Statement */
+ /*TODO: | If then else */
+ /*TODO: | function call */
+ | DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ | RETURN DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ | RETURN relop_expr DL_SEMICOL
+ {
+ /*TODO*/
+ }
+ ;
+
+assign_expr_list : nonempty_assign_expr_list
+ {
+ /*TODO*/
+ }
+ |
+ {
+ $$ = Allocate(NUL_NODE);
+ }
+ ;
+
+nonempty_assign_expr_list : nonempty_assign_expr_list DL_COMMA assign_expr
+ {
+ /*TODO*/
+ }
+ | assign_expr
+ {
+ /*TODO*/
+ }
+ ;
+
+test : assign_expr
+ {
+ $$ = $1;
+ }
+ ;
+
+assign_expr : ID OP_ASSIGN relop_expr
+ {
+ /*TODO*/
+ }
+ | relop_expr
+ {
+ /*TODO*/
+ }
+ ;
+
+relop_expr : relop_term
+ {
+ $$ = $1;
+ }
+ | relop_expr OP_OR relop_term
+ {
+ $$ = makeExprNode(BINARY_OPERATION, BINARY_OP_OR);
+ makeFamily($$, 2, $1, $3);
+ }
+ ;
+
+relop_term : relop_factor
+ {
+ /*TODO*/
+ }
+ | relop_term OP_AND relop_factor
+ {
+ /*TODO*/
+ }
+ ;
+
+relop_factor : expr
+ {
+ /*TODO*/
+ }
+ | expr rel_op expr
+ {
+ /*TODO*/
+ }
+ ;
+
+rel_op : OP_EQ
+ {
+ /*TODO*/
+ }
+ | OP_GE
+ {
+ /*TODO*/
+ }
+ | OP_LE
+ {
+ /*TODO*/
+ }
+ | OP_NE
+ {
+ /*TODO*/
+ }
+ | OP_GT
+ {
+ /*TODO*/
+ }
+ | OP_LT
+ {
+ /*TODO*/
+ }
+ ;
+
+
+relop_expr_list : nonempty_relop_expr_list
+ {
+ /*TODO*/
+ }
+ |
+ {
+ $$ = Allocate(NUL_NODE);
+ }
+ ;
+
+nonempty_relop_expr_list : nonempty_relop_expr_list DL_COMMA relop_expr
+ {
+ /*TODO*/
+ }
+ | relop_expr
+ {
+ /*TODO*/
+ }
+ ;
+
+expr : expr add_op term
+ {
+ /*TODO*/
+ }
+ | term
+ {
+ /*TODO*/
+ }
+ ;
+
+add_op : OP_ADD
+ {
+ $$ = makeExprNode(BINARY_OPERATION, BINARY_OP_ADD);
+ }
+ | OP_SUB
+ {
+ $$ = makeExprNode(BINARY_OPERATION, BINARY_OP_SUB);
+ }
+ ;
+
+term : term mul_op factor
+ {
+ /*TODO*/
+ }
+ | factor
+ {
+ /*TODO*/
+ }
+ ;
+
+mul_op : OP_MUL
+ {
+ /*TODO*/
+ }
+ | OP_DIV
+ {
+ /*TODO*/
+ }
+ ;
+
+factor : DL_LPAREN relop_expr DL_RPAREN
+ {
+ /*TODO*/
+ }
+ /*TODO: | -(<relop_expr>) e.g. -(4) */
+ | OP_NOT DL_LPAREN relop_expr DL_RPAREN
+ {
+ /*TODO*/
+ }
+ | CONST
+ {
+ $$ = Allocate(CONST_VALUE_NODE);
+ $$->semantic_value.const1=$1;
+ }
+ /*TODO: | -<constant> e.g. -4 */
+ | OP_NOT CONST
+ {
+ /*TODO*/
+ }
+ | ID DL_LPAREN relop_expr_list DL_RPAREN
+ {
+ /*TODO*/
+ }
+ /*TODO: | -<function call> e.g. -f(4) */
+ | OP_NOT ID DL_LPAREN relop_expr_list DL_RPAREN
+ {
+ /*TODO*/
+ }
+ | var_ref
+ {
+ /*TODO*/
+ }
+ /*TODO: | -<var_ref> e.g. -var */
+ | OP_NOT var_ref
+ {
+ /*TODO*/
+ }
+ ;
+
+var_ref : ID
+ {
+ /*TODO*/
+ }
+ | ID dim_list
+ {
+ /*TODO*/
+ }
+ ;
+
+
+dim_list : dim_list DL_LBRACK expr DL_RBRACK
+ {
+ /*TODO*/
+ }
+ | DL_LBRACK expr DL_RBRACK
+ {
+ /*TODO*/
+ }
+ ;
+
+%%
+
diff --git a/src/symbol-table.c b/src/symbol-table.c
index 08a1859..090bdbe 100644
--- a/src/symbol-table.c
+++ b/src/symbol-table.c
@@ -82,31 +82,4 @@ void ccmmc_symbol_table_print(void) {
}
}
-CcmmcSymbol **ccmmc_symbol_table_tmp(int *len) {
- int cnt = 0;
- for (int i = 0; i < TABLE_SIZE; i++)
- {
- CcmmcSymbol *symptr = hash_table[i];
- while (symptr != NULL)
- {
- cnt++;
- symptr = symptr->front;
- }
- }
-
- CcmmcSymbol **tp = malloc(sizeof(CcmmcSymbol*)*cnt);
- cnt = 0;
- for (int i = 0; i < TABLE_SIZE; i++)
- {
- CcmmcSymbol *symptr = hash_table[i];
- while (symptr != NULL)
- {
- tp[cnt++] = symptr;
- symptr = symptr->front;
- }
- }
- *len = cnt;
- return tp;
-}
-
// vim: set sw=4 ts=4 sts=4 et:
diff --git a/src/symbol-table.h b/src/symbol-table.h
index b1e5a3f..2afd1b0 100644
--- a/src/symbol-table.h
+++ b/src/symbol-table.h
@@ -13,7 +13,6 @@ CcmmcSymbol *ccmmc_symbol_table_lookup (char *name);
void ccmmc_symbol_table_insert_id (char *name,
int line_number);
void ccmmc_symbol_table_print (void);
-CcmmcSymbol **ccmmc_symbol_table_tmp (int *len);
#endif
// vim: set sw=4 ts=4 sts=4 et: