summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-10-26 20:26:29 -0400
committerTavian Barnes <tavianator@gmail.com>2009-10-26 20:26:29 -0400
commit43ab94e9a2f18b0e40b441fedde5b4ce88046539 (patch)
tree42e0d4d94e95e605af38f5e80e5c1f1606b7704d
parentbc16db8ce1e990dbfadcf6c08f68bd4cb2c445a5 (diff)
downloaddimension-43ab94e9a2f18b0e40b441fedde5b4ce88046539.tar.xz
Begin tokenizer.
-rw-r--r--dimension/Makefile.am4
-rw-r--r--dimension/main.c48
-rw-r--r--dimension/tokenize.c114
-rw-r--r--dimension/tokenize.h36
4 files changed, 197 insertions, 5 deletions
diff --git a/dimension/Makefile.am b/dimension/Makefile.am
index 818a6b3..099a81b 100644
--- a/dimension/Makefile.am
+++ b/dimension/Makefile.am
@@ -21,5 +21,7 @@ INCLUDES = -I$(top_srcdir)/libdimension
bin_PROGRAMS = dimension
-dimension_SOURCES = main.c
+dimension_SOURCES = main.c \
+ tokenize.c \
+ tokenize.h
dimension_LDADD = $(top_builddir)/libdimension/libdimension.la
diff --git a/dimension/main.c b/dimension/main.c
index 8f5aa9f..2ccadbf 100644
--- a/dimension/main.c
+++ b/dimension/main.c
@@ -17,16 +17,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
+#include "tokenize.h"
#include "../libdimension/dimension.h"
#include <stdlib.h>
#include <getopt.h>
-const char *output = NULL, *input = NULL;
-int tokenize = 0;
+static const char *output = NULL, *input = NULL;
+static int tokenize = 0;
int
main(int argc, char **argv) {
- /* Parse the command-line options */
+ dmnsn_array *tokens;
+ FILE *input_file, *output_file;
+
+ /*
+ * Parse the command-line options
+ */
static struct option long_options[] = {
{ "output", required_argument, NULL, 'o' },
@@ -78,12 +84,46 @@ main(int argc, char **argv) {
dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid extranious command line options.");
}
- if (!output) {
+ if (!output && !tokenize) {
dmnsn_error(DMNSN_SEVERITY_HIGH, "No output file specified.");
}
if (!input) {
dmnsn_error(DMNSN_SEVERITY_HIGH, "No input file specified.");
}
+ /* Open the input file */
+ input_file = fopen(input, "r");
+ if (!input_file) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't open input file.");
+ }
+
+ /* Tokenize the input file */
+ tokens = dmnsn_tokenize(input_file);
+ if (!tokens) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Error tokenizing input file.");
+ }
+
+ /* Debugging option - output the list of tokens as an S-expression */
+ if (tokenize) {
+ dmnsn_print_token_sexpr(stdout, tokens);
+ dmnsn_delete_tokens(tokens);
+ fclose(input_file);
+ return EXIT_SUCCESS;
+ }
+
+ /*
+ * Now we render the scene
+ */
+
+ /* Open the output file */
+ output_file = fopen(output, "wb");
+ if (!output_file) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't open output file.");
+ }
+
+ /* Clean up and exit! */
+ dmnsn_delete_tokens(tokens);
+ fclose(output_file);
+ fclose(input_file);
return EXIT_SUCCESS;
}
diff --git a/dimension/tokenize.c b/dimension/tokenize.c
new file mode 100644
index 0000000..6a9a723
--- /dev/null
+++ b/dimension/tokenize.c
@@ -0,0 +1,114 @@
+/*************************************************************************
+ * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of Dimension. *
+ * *
+ * Dimension is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the *
+ * Free Software Foundation; either version 3 of the License, or (at *
+ * your option) any later version. *
+ * *
+ * Dimension is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "tokenize.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+dmnsn_array *
+dmnsn_tokenize(FILE *file)
+{
+ char c;
+ dmnsn_token token;
+ dmnsn_array *tokens = dmnsn_new_array(sizeof(dmnsn_token));
+
+ while (!feof(file)) {
+ fread(&c, 1, 1, file);
+
+ if (isspace(c))
+ continue;
+
+ if (c == '{') {
+ token.type = DMNSN_LBRACE;
+ token.value = NULL;
+ dmnsn_array_push(tokens, &token);
+ } else if (c == '}') {
+ token.type = DMNSN_RBRACE;
+ token.value = NULL;
+ dmnsn_array_push(tokens, &token);
+ } else {
+ /* Invalid character */
+ dmnsn_delete_tokens(tokens);
+ return NULL;
+ }
+ }
+
+ return tokens;
+}
+
+void
+dmnsn_delete_tokens(dmnsn_array *tokens)
+{
+ dmnsn_token *token;
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(tokens); ++i) {
+ token = dmnsn_array_at(tokens, i);
+ free(token->value);
+ }
+ dmnsn_delete_array(tokens);
+}
+
+static const char *dmnsn_token_name(dmnsn_token_type token_type);
+
+static void
+dmnsn_print_token(FILE *file, dmnsn_token *token)
+{
+ if (token->value) {
+ fprintf(file, "(%s \"%s\")", dmnsn_token_name(token->type), token->value);
+ } else {
+ fprintf(file, "%s", dmnsn_token_name(token->type));
+ }
+}
+
+void
+dmnsn_print_token_sexpr(FILE *file, dmnsn_array *tokens)
+{
+ unsigned int i;
+ if (dmnsn_array_size(tokens) == 0) {
+ fprintf(file, "()");
+ } else {
+ fprintf(file, "(");
+ dmnsn_print_token(file, dmnsn_array_at(tokens, 0));
+
+ for (i = 1; i < dmnsn_array_size(tokens); ++i) {
+ fprintf(file, " ");
+ dmnsn_print_token(file, dmnsn_array_at(tokens, i));
+ }
+
+ fprintf(file, ")");
+ }
+
+ fprintf(file, "\n");
+}
+
+static const char *
+dmnsn_token_name(dmnsn_token_type token_type)
+{
+ switch (token_type) {
+ case DMNSN_LBRACE:
+ return "DMNSN_LBRACE";
+
+ case DMNSN_RBRACE:
+ return "DMNSN_RBRACE";
+
+ default:
+ return "UNRECOGNIZED-TOKEN";
+ }
+}
diff --git a/dimension/tokenize.h b/dimension/tokenize.h
new file mode 100644
index 0000000..3798d1e
--- /dev/null
+++ b/dimension/tokenize.h
@@ -0,0 +1,36 @@
+/*************************************************************************
+ * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> *
+ * *
+ * This file is part of Dimension. *
+ * *
+ * Dimension is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the *
+ * Free Software Foundation; either version 3 of the License, or (at *
+ * your option) any later version. *
+ * *
+ * Dimension is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "../libdimension/dimension.h"
+
+typedef enum {
+ DMNSN_LBRACE,
+ DMNSN_RBRACE
+} dmnsn_token_type;
+
+typedef struct dmnsn_token dmnsn_token;
+
+struct dmnsn_token {
+ dmnsn_token_type type;
+ char *value;
+};
+
+dmnsn_array *dmnsn_tokenize(FILE *file);
+void dmnsn_delete_tokens(dmnsn_array *tokens);
+void dmnsn_print_token_sexpr(FILE *file, dmnsn_array *tokens);