From 43ab94e9a2f18b0e40b441fedde5b4ce88046539 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 26 Oct 2009 20:26:29 -0400 Subject: Begin tokenizer. --- dimension/Makefile.am | 4 +- dimension/main.c | 48 +++++++++++++++++++-- dimension/tokenize.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ dimension/tokenize.h | 36 ++++++++++++++++ 4 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 dimension/tokenize.c create mode 100644 dimension/tokenize.h 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 . * *************************************************************************/ +#include "tokenize.h" #include "../libdimension/dimension.h" #include #include -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 * + * * + * 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 . * + *************************************************************************/ + +#include "tokenize.h" +#include +#include +#include + +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 * + * * + * 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 . * + *************************************************************************/ + +#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); -- cgit v1.2.3