summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2015-12-02 00:18:08 +0800
committerTing-Wei Lan <lantw44@gmail.com>2015-12-02 00:18:08 +0800
commitf2a04b9f3810d1c19f8359bf3f1dbbe38bf07097 (patch)
tree240f3b2b7dc52ba28da0829c977d4643282157b2
parent15d78a2151c63a45adfad9dc954f79eba9207dab (diff)
downloadcompiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar.gz
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar.bz2
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar.lz
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar.xz
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.tar.zst
compiler2015-f2a04b9f3810d1c19f8359bf3f1dbbe38bf07097.zip
Drop line_number and prog global variables
All important states should be stored in the local struct allocated in main function.
-rw-r--r--Makefile.am2
-rw-r--r--src/ast.c3
-rw-r--r--src/lexer.l27
-rw-r--r--src/main.c19
-rw-r--r--src/parser.y22
-rw-r--r--src/state.c20
-rw-r--r--src/state.h21
7 files changed, 80 insertions, 34 deletions
diff --git a/Makefile.am b/Makefile.am
index 3a4e879..7738266 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,6 +16,8 @@ parser_SOURCES = \
src/draw.c \
src/ast.h \
src/ast.c \
+ src/state.h \
+ src/state.c \
src/symbol-table.h \
src/symbol-table.c \
$(NULL)
diff --git a/src/ast.c b/src/ast.c
index eb3ac54..c1e9b12 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -9,8 +9,6 @@
#include <stdlib.h>
-extern int line_number;
-
AST_NODE *Allocate(AST_TYPE type)
{
AST_NODE *temp;
@@ -22,7 +20,6 @@ AST_NODE *Allocate(AST_TYPE type)
temp->parent = NULL;
// Notice that leftmostSibling is not initialized as NULL
temp->leftmostSibling = temp;
- temp->linenumber = line_number;
return temp;
}
diff --git a/src/lexer.l b/src/lexer.l
index 1c7d940..92aa645 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -8,15 +8,15 @@
#include "ast.h"
#include "common.h"
-#include "libparser_a-parser.h"
+#include "state.h"
#include "symbol-table.h"
+#include "libparser_a-parser.h"
+
#include <assert.h>
#include <stdlib.h>
#include <string.h>
-int line_number = 1;
-
#define YYSTYPE CCMMC_PARSER_STYPE
%}
@@ -80,10 +80,11 @@ ERROR .
if (strcmp(yytext, reserved[i]) == 0)
return reserved_token[i];
if (i == SIZEOF_ARRAY(reserved)) {
- CcmmcSymbol *ptr;
- ptr = ccmmc_symbol_table_lookup(yytext);
+ CcmmcSymbol *ptr = ccmmc_symbol_table_lookup(yytext);
+ CcmmcState *state = yyextra;
if (ptr == NULL)
- ccmmc_symbol_table_insert_id(yytext, line_number);
+ ccmmc_symbol_table_insert_id(
+ yytext, state->line_number);
else
ptr->counter++;
}
@@ -120,9 +121,10 @@ ERROR .
return CONST;
}
{COMMENT} {
+ CcmmcState *state = yyextra;
for (size_t i = 0; yytext[i] != '\0'; i++)
if (yytext[i] == '\n')
- line_number++;
+ state->line_number++;
}
{OP_ASSIGN} return OP_ASSIGN;
{OP_OR} return OP_OR;
@@ -139,8 +141,10 @@ ERROR .
{OP_NE} return OP_NE;
{OP_EQ} return OP_EQ;
-{NEWLINE} line_number++;
-
+{NEWLINE} {
+ CcmmcState *state = yyextra;
+ state->line_number++;
+ }
{DL_LPAREN} return DL_LPAREN;
{DL_RPAREN} return DL_RPAREN;
{DL_LBRACK} return DL_LBRACK;
@@ -152,8 +156,9 @@ ERROR .
{DL_DOT} return DL_DOT;
{ERROR} {
- fprintf(stderr, "%d: error: undefined character `%s'\n",
- line_number, yytext);
+ CcmmcState *state = yyextra;
+ fprintf(stderr, "%zu: error: undefined character `%s'\n",
+ state->line_number, yytext);
exit(1);
}
diff --git a/src/main.c b/src/main.c
index cc52b13..77cfcc7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,6 +6,8 @@ typedef void* yyscan_t;
#include "ast.h"
#include "common.h"
+#include "state.h"
+
#include "libparser_a-parser.h"
#include <errno.h>
@@ -15,10 +17,7 @@ typedef void* yyscan_t;
#include <string.h>
-extern FILE *yyin;
-extern AST_NODE *prog;
-
-extern int ccmmc_parser_lex_init(yyscan_t *scanner);
+extern int ccmmc_parser_lex_init_extra(void *extra, yyscan_t *scanner);
extern int ccmmc_parser_lex_destroy(yyscan_t *scanner);
extern int ccmmc_parser_set_in(FILE *source_handle, yyscan_t scanner);
@@ -43,10 +42,14 @@ int main (int argc, char **argv)
exit(1);
}
+ CcmmcState state_struct;
+ CcmmcState *state = &state_struct;
+ ccmmc_state_init(state);
+
yyscan_t scanner;
- ccmmc_parser_lex_init(&scanner);
+ ccmmc_parser_lex_init_extra(state, &scanner);
ccmmc_parser_set_in(source_handle, scanner);
- switch (ccmmc_parser_parse(scanner)) {
+ switch (ccmmc_parser_parse(scanner, state)) {
case 1:
fprintf(stderr, "%s: failed because of invalid input\n", name);
exit(1);
@@ -58,8 +61,10 @@ int main (int argc, char **argv)
}
ccmmc_parser_lex_destroy(scanner);
+ printGV(state->ast, NULL);
+
+ ccmmc_state_fini(state);
fclose(source_handle);
- printGV(prog, NULL);
return 0;
}
diff --git a/src/parser.y b/src/parser.y
index d90aaa7..b9c3a06 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -1,7 +1,7 @@
%define api.prefix {ccmmc_parser_}
%define api.pure full
%lex-param {yyscan_t scanner}
-%parse-param {yyscan_t scanner}
+%parse-param {yyscan_t scanner} {CcmmcState *state}
%{
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -10,15 +10,11 @@
typedef void* yyscan_t;
#include "ast.h"
+#include "state.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
-AST_NODE *prog;
-
-extern int line_number;
-extern int g_anyErrorOccur;
%}
%union{
@@ -28,9 +24,9 @@ extern int g_anyErrorOccur;
};
%{
-extern char *ccmmc_parser_get_text(yyscan_t scanner);
extern int ccmmc_parser_lex(CCMMC_PARSER_STYPE *yylval, yyscan_t scanner);
-static void ccmmc_parser_error(yyscan_t scanner, const char *mesg);
+extern char *ccmmc_parser_get_text(yyscan_t scanner);
+static void ccmmc_parser_error(yyscan_t scanner, CcmmcState *state, const char *mesg);
%}
%token <lexeme>ID
@@ -92,11 +88,11 @@ program : global_decl_list
{
$$=Allocate(PROGRAM_NODE);
makeChild($$,$1);
- prog=$$;
+ state->ast=$$;
}
|
{
- $$=Allocate(PROGRAM_NODE); prog=$$;
+ $$=Allocate(PROGRAM_NODE); state->ast=$$;
}
;
@@ -694,10 +690,10 @@ dim_list : dim_list DL_LBRACK expr DL_RBRACK
%%
-static void ccmmc_parser_error(yyscan_t scanner, const char *mesg)
+static void ccmmc_parser_error(yyscan_t scanner, CcmmcState *state, const char *mesg)
{
- fprintf(stderr, "Error found in Line \t%d\tnext token: \t%s\n",
- line_number, ccmmc_parser_get_text(scanner));
+ fprintf(stderr, "Error found in Line \t%zu\tnext token: \t%s\n",
+ state->line_number, ccmmc_parser_get_text(scanner));
exit(1);
}
diff --git a/src/state.c b/src/state.c
new file mode 100644
index 0000000..a4e5080
--- /dev/null
+++ b/src/state.c
@@ -0,0 +1,20 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "state.h"
+
+
+void ccmmc_state_init (CcmmcState *state)
+{
+ state->ast = NULL;
+ state->line_number = 1;
+ state->any_error = false;
+}
+
+void ccmmc_state_fini (CcmmcState *state)
+{
+ if (state->ast != NULL) {
+ // TODO: Free the AST
+ }
+}
diff --git a/src/state.h b/src/state.h
new file mode 100644
index 0000000..11f4ad1
--- /dev/null
+++ b/src/state.h
@@ -0,0 +1,21 @@
+#ifndef CCMMC_HEADER_STATE_H
+#endif
+
+#include "ast.h"
+#include "symbol-table.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+
+// All states of the compiler instance
+typedef struct CcmmcState_struct {
+ AST_NODE *ast;
+ size_t line_number;
+ bool any_error;
+} CcmmcState;
+
+void ccmmc_state_init (CcmmcState *state);
+void ccmmc_state_fini (CcmmcState *state);
+
+// vim: set sw=4 ts=4 sts=4 et:
+#define CCMMC_HEADER_STATE_H