summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkugwa <kugwa2000@gmail.com>2015-11-12 18:15:03 +0800
committerkugwa <kugwa2000@gmail.com>2015-11-12 18:15:03 +0800
commit78c69f70e278147e9934c2439e2cb7fb1d3d5e09 (patch)
tree38b3cb666b2f2b7b41d4d31c4fe5faf20dc0503d
parent0fe228754fcdaaa32840080cd32d2d4657b90258 (diff)
downloadcompiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar.gz
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar.bz2
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar.lz
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar.xz
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.tar.zst
compiler2015-78c69f70e278147e9934c2439e2cb7fb1d3d5e09.zip
main() prints the parse tree
-rw-r--r--Makefile.am1
-rw-r--r--src/draw.c201
-rw-r--r--src/main.c2
3 files changed, 204 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 53844b2..967eaac 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,6 +12,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src
parser_CFLAGS = $(WARN_CFLAGS)
parser_SOURCES = \
src/main.c \
+ src/draw.c \
src/ast.h \
src/ast.c \
src/symbol-table.h \
diff --git a/src/draw.c b/src/draw.c
new file mode 100644
index 0000000..adcf55b
--- /dev/null
+++ b/src/draw.c
@@ -0,0 +1,201 @@
+/* 2015/10 functions to support printGV() */
+
+#include "ast.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+char *AST_TYPE_string[] = {"PROGRAM", "GLOBAL_DECL_LIST", "GLOBAL_DECL", "DECL_LIST", "FUNCTION_DECL", "PARAM_LIST", "PARAM", "DIM_FN", "DIMFN1", "EXPR_NULL", "BLOCK", "DECL", "TYPE_DECL", "VAR_DECL",
+ "TYPE", "STRUCT_TYPE", "DEF_LIST", "DEF", "OPT_TAG", "TAG", "ID_LIST", "DIM_DECL", "CEXPR", "MCEXPR", "CFACTOR", "INIT_ID_LIST", "INIT_ID", "STMT_LIST", "STMT", "ASSIGN_EXPR_LIST",
+ "NONEMPTY_ASSIGN_EXPR_LIST", "TEST", "ASSIGN_EXPR", "RELOP_EXPR", "RELOP_TERM", "RELOP_FACTOR", "REL_OP", "RELOP_EXPR_LIST", "NONEMPTY_RELOP_EXPR_LIST", "EXPR", "ADD_OP", "TERM",
+ "MUL_OP", "FACTOR", "VAR_REF", "DIM", "STRUCT_TAIL", "NUL","ID_value", "CONST_value"};
+
+int printGVNode(FILE *fp, AST_NODE* node, int count);
+
+char *printLabelString(FILE *fp, AST_NODE *astNode)
+{
+ char *binaryOpString[] = {
+ "+",
+ "-",
+ "*",
+ "/",
+ "==",
+ ">=",
+ "<=",
+ "!=",
+ ">",
+ "<",
+ "&&",
+ "||"
+ };
+ char *unaryOpString[] = {
+ "+",
+ "-",
+ "!"
+ };
+// fprintf(fp, "%d ", astNode->linenumber);
+ switch (astNode->nodeType) {
+ case PROGRAM_NODE:
+ fprintf(fp, "PROGRAM_NODE");
+ break;
+ case DECLARATION_NODE:
+ fprintf(fp, "DECLARATION_NODE ");
+ switch (astNode->semantic_value.declSemanticValue.kind) {
+ case VARIABLE_DECL:
+ fprintf(fp, "VARIABLE_DECL");
+ break;
+ case TYPE_DECL:
+ fprintf(fp, "TYPE_DECL");
+ break;
+ case FUNCTION_DECL:
+ fprintf(fp, "FUNCTION_DECL");
+ break;
+ case FUNCTION_PARAMETER_DECL:
+ fprintf(fp, "FUNCTION_PARAMETER_DECL");
+ break;
+ }
+ break;
+ case IDENTIFIER_NODE:
+ fprintf(fp, "IDENTIFIER_NODE ");
+ fprintf(fp, "%s ", astNode->semantic_value.identifierSemanticValue.identifierName);
+ switch (astNode->semantic_value.identifierSemanticValue.kind) {
+ case NORMAL_ID:
+ fprintf(fp, "NORMAL_ID");
+ break;
+ case ARRAY_ID:
+ fprintf(fp, "ARRAY_ID");
+ break;
+ case WITH_INIT_ID:
+ fprintf(fp, "WITH_INIT_ID");
+ break;
+ }
+ break;
+ case PARAM_LIST_NODE:
+ fprintf(fp, "PARAM_LIST_NODE");
+ break;
+ case NUL_NODE:
+ fprintf(fp, "NUL_NODE");
+ break;
+ case BLOCK_NODE:
+ fprintf(fp, "BLOCK_NODE");
+ break;
+ case VARIABLE_DECL_LIST_NODE:
+ fprintf(fp, "VARIABLE_DECL_LIST_NODE");
+ break;
+ case STMT_LIST_NODE:
+ fprintf(fp, "STMT_LIST_NODE");
+ break;
+ case STMT_NODE:
+ fprintf(fp, "STMT_NODE ");
+ switch (astNode->semantic_value.stmtSemanticValue.kind) {
+ case WHILE_STMT:
+ fprintf(fp, "WHILE_STMT");
+ break;
+ case FOR_STMT:
+ fprintf(fp, "FOR_STMT");
+ break;
+ case ASSIGN_STMT:
+ fprintf(fp, "ASSIGN_STMT");
+ break;
+ case IF_STMT:
+ fprintf(fp, "IF_STMT");
+ break;
+ case FUNCTION_CALL_STMT:
+ fprintf(fp, "FUNCTION_CALL_STMT");
+ break;
+ case RETURN_STMT:
+ fprintf(fp, "RETURN_STMT");
+ break;
+ }
+ break;
+ case EXPR_NODE:
+ fprintf(fp, "EXPR_NODE ");
+ switch (astNode->semantic_value.exprSemanticValue.kind) {
+ case BINARY_OPERATION:
+ fprintf(fp, "%s", binaryOpString[astNode->semantic_value.exprSemanticValue.op.binaryOp]);
+ break;
+ case UNARY_OPERATION:
+ fprintf(fp, "%s", unaryOpString[astNode->semantic_value.exprSemanticValue.op.unaryOp]);
+ break;
+ }
+ break;
+ case CONST_VALUE_NODE:
+ fprintf(fp, "CONST_VALUE_NODE ");
+ switch (astNode->semantic_value.const1->const_type) {
+ case INTEGERC:
+ fprintf(fp, "%d", astNode->semantic_value.const1->const_u.intval);
+ break;
+ case FLOATC:
+ fprintf(fp, "%f", astNode->semantic_value.const1->const_u.fval);
+ break;
+ case STRINGC:
+ astNode->semantic_value.const1->const_u.sc[strlen(astNode->semantic_value.const1->const_u.sc) - 1] = 0;
+ fprintf(fp, "\\\"%s\\\"", astNode->semantic_value.const1->const_u.sc + 1);
+ astNode->semantic_value.const1->const_u.sc[strlen(astNode->semantic_value.const1->const_u.sc)] = '"';
+ astNode->semantic_value.const1->const_u.sc[strlen(astNode->semantic_value.const1->const_u.sc) + 1] = 0;
+ break;
+ }
+ break;
+ case NONEMPTY_ASSIGN_EXPR_LIST_NODE:
+ fprintf(fp, "NONEMPTY_ASSIGN_EXPR_LIST_NODE");
+ break;
+ case NONEMPTY_RELOP_EXPR_LIST_NODE:
+ fprintf(fp, "NONEMPTY_RELOP_EXPR_LIST_NODE");
+ break;
+ default:
+ fprintf(fp, "default case in char *getLabelString(AST_TYPE astType)");
+ break;
+ }
+}
+
+void printGV(AST_NODE *root, char* fileName)
+{
+ if (fileName == NULL) {
+ fileName = "AST_Graph.gv";
+ }
+ FILE *fp;
+ fp = fopen(fileName, "w");
+ if (!fp) {
+ printf("Cannot open file \"%s\"\n", fileName);
+ return;
+ }
+ fprintf(fp , "Digraph AST\n");
+ fprintf(fp , "{\n");
+ fprintf(fp , "label = \"%s\"\n", fileName);
+
+ int nodeCount = 0;
+ printGVNode(fp, root, nodeCount);
+
+ fprintf(fp , "}\n");
+ fclose(fp);
+}
+
+// count: the (unused) id number to be used
+// return: then next unused id number
+int printGVNode(FILE *fp, AST_NODE* node, int count)
+{
+ if (node == NULL) {
+ return count;
+ }
+
+ int currentNodeCount = count;
+ fprintf(fp, "node%d [label =\"", count);
+ printLabelString(fp, node);
+ fprintf(fp, "\"]\n");
+ ++count;
+ int countAfterCheckChildren = count;
+ if (node->child) {
+ countAfterCheckChildren = printGVNode(fp, node->child, count);
+ fprintf(fp, "node%d -> node%d [style = bold]\n", currentNodeCount, count);
+ }
+
+ int countAfterCheckSibling = countAfterCheckChildren;
+ if (node->rightSibling) {
+ countAfterCheckSibling = printGVNode(fp, node->rightSibling, countAfterCheckChildren);
+ fprintf(fp, "node%d -> node%d [style = dashed]\n", currentNodeCount, countAfterCheckChildren);
+ }
+
+ return countAfterCheckSibling;
+}
+
diff --git a/src/main.c b/src/main.c
index 0421e94..4b46032 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,6 +4,7 @@
#include "src/libparser_a-parser.h"
extern FILE *yyin;
+extern AST_NODE *prog;
int main (int argc, char **argv)
{
@@ -17,6 +18,7 @@ int main (int argc, char **argv)
exit(1);
}
yyparse();
+ printGV(prog, NULL);
return 0;
}