diff options
-rw-r--r-- | Makefile.am | 31 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/ast.c | 114 | ||||
-rw-r--r-- | src/ast.h | 179 | ||||
-rw-r--r-- | src/lexer.l | 110 | ||||
-rw-r--r-- | src/main.c | 36 | ||||
-rw-r--r-- | src/parser.y | 580 | ||||
-rw-r--r-- | src/symbol-table.c | 27 | ||||
-rw-r--r-- | src/symbol-table.h | 1 |
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", @@ -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: |