diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-10-26 20:26:29 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-10-26 20:26:29 -0400 |
commit | 43ab94e9a2f18b0e40b441fedde5b4ce88046539 (patch) | |
tree | 42e0d4d94e95e605af38f5e80e5c1f1606b7704d | |
parent | bc16db8ce1e990dbfadcf6c08f68bd4cb2c445a5 (diff) | |
download | dimension-43ab94e9a2f18b0e40b441fedde5b4ce88046539.tar.xz |
Begin tokenizer.
-rw-r--r-- | dimension/Makefile.am | 4 | ||||
-rw-r--r-- | dimension/main.c | 48 | ||||
-rw-r--r-- | dimension/tokenize.c | 114 | ||||
-rw-r--r-- | dimension/tokenize.h | 36 |
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); |