From: Michael D. Lowis Date: Fri, 10 Oct 2014 01:39:42 +0000 (-0400) Subject: Added prettyprinting module X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=1e9cca08a9a0ed0eb3fbfa124ff3808e1753240a;p=proto%2Fsclpl.git Added prettyprinting module --- diff --git a/source/sclpl/lexer.c b/source/sclpl/lexer.c index 19780d5..3881279 100644 --- a/source/sclpl/lexer.c +++ b/source/sclpl/lexer.c @@ -51,8 +51,6 @@ lex_tok_t* lexer_read(lexer_t* p_lexer) { char* text = scanner_read(p_lexer->scanner); if (NULL != text) { p_tok = lexer_make_token(text); - //if (NULL != p_tok) - // printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok)); free(text); } return p_tok; @@ -66,7 +64,7 @@ static lex_tok_t* lexer_make_token(char* text) { lex_tok_t* p_tok = NULL; if ((0 == strcmp(text,"end") || (text[0] == ';'))) { p_tok = lex_tok_new(T_END, NULL); - } else if (lexer_oneof("()[];,'\"", text[0])) { + } else if (lexer_oneof("()[]{};,'\"", text[0])) { p_tok = lexer_punc(text); } else if (text[0] == '\\') { p_tok = lexer_char(text); @@ -86,14 +84,16 @@ static lex_tok_t* lexer_punc(char* text) { lex_tok_t* p_tok = NULL; switch (text[0]) { - case '(': p_tok = lex_tok_new(T_LPAR, NULL); break; - case ')': p_tok = lex_tok_new(T_RPAR, NULL); break; - case '{': p_tok = lex_tok_new(T_LBRACE, NULL); break; - case '}': p_tok = lex_tok_new(T_RBRACE, NULL); break; - case '[': p_tok = lex_tok_new(T_LBRACK, NULL); break; - case ']': p_tok = lex_tok_new(T_RBRACK, NULL); break; - case ';': p_tok = lex_tok_new(T_END, NULL); break; - case ',': p_tok = lex_tok_new(T_COMMA, NULL); break; + case '(': p_tok = lex_tok_new(T_LPAR, NULL); break; + case ')': p_tok = lex_tok_new(T_RPAR, NULL); break; + case '{': p_tok = lex_tok_new(T_LBRACE, NULL); break; + case '}': p_tok = lex_tok_new(T_RBRACE, NULL); break; + case '[': p_tok = lex_tok_new(T_LBRACK, NULL); break; + case ']': p_tok = lex_tok_new(T_RBRACK, NULL); break; + case ';': p_tok = lex_tok_new(T_END, NULL); break; + case ',': p_tok = lex_tok_new(T_COMMA, NULL); break; + case '\'': p_tok = lex_tok_new(T_SQUOTE, NULL); break; + case '"': p_tok = lex_tok_new(T_DQUOTE, NULL); break; } return p_tok; } @@ -166,27 +166,6 @@ static lex_tok_t* lexer_var(char* text) return lex_tok_new(T_VAR, lexer_dup(text)); } -char* lexer_tok_type_str(lex_tok_t* p_tok) { - switch(p_tok->type) { - case T_END: return "T_END"; - case T_STRING: return "T_STRING"; - case T_CHAR: return "T_CHAR"; - case T_INT: return "T_INT"; - case T_FLOAT: return "T_FLOAT"; - case T_BOOL: return "T_BOOL"; - case T_LBRACE: return "T_LBRACE"; - case T_RBRACE: return "T_RBRACE"; - case T_LBRACK: return "T_LBRACK"; - case T_RBRACK: return "T_RBRACK"; - case T_LPAR: return "T_LPAR"; - case T_RPAR: return "T_RPAR"; - case T_COMMA: return "T_COMMA"; - case T_VAR: return "T_VAR"; - case T_END_FILE: return "T_END_FILE"; - default: return NULL; - } -} - static bool lexer_oneof(const char* class, char c) { bool ret = false; size_t sz = strlen(class); diff --git a/source/sclpl/lexer.h b/source/sclpl/lexer.h index 8e06e98..5fb0ea2 100644 --- a/source/sclpl/lexer.h +++ b/source/sclpl/lexer.h @@ -17,8 +17,8 @@ typedef struct { } lexer_t; typedef enum { - T_END, T_STRING, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_LBRACE, T_RBRACE, - T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_VAR, T_END_FILE + T_VAR, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK, + T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_END_FILE } lex_tok_type_t; typedef struct { @@ -37,8 +37,6 @@ lex_tok_t* lexer_read(lexer_t* p_lexer); void lexer_skipline(lexer_t* p_lexer); -char* lexer_tok_type_str(lex_tok_t* p_tok); - char* lexer_dup(const char* p_old); #endif /* LEXER_H */ diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 5f0a839..b8ec5ab 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -29,8 +29,7 @@ void print_indent(int depth) { void print_tree(tree_t* p_tree, int depth) { print_indent(depth); if (p_tree->tag == ATOM) { - lex_tok_t* p_tok = p_tree->ptr.tok; - printf("\n", lexer_tok_type_str(p_tok)); + pprint_token(stdout, p_tree->ptr.tok); } else { puts("(tree"); vec_t* p_vec = p_tree->ptr.vec; @@ -84,7 +83,7 @@ static int emit_tokens(void) { lexer_t* p_lexer = lexer_new(NULL, stdin); lex_tok_t* token; while(NULL != (token = lexer_read(p_lexer))) { - printf("\n", lexer_tok_type_str(token)); + pprint_token(stdout, token); mem_release(token); } mem_release(p_lexer); diff --git a/source/sclpl/pprint.c b/source/sclpl/pprint.c new file mode 100644 index 0000000..2e1b6b8 --- /dev/null +++ b/source/sclpl/pprint.c @@ -0,0 +1,64 @@ +/** + @file prettyprint.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include "pprint.h" + +static const char* token_type_to_string(lex_tok_type_t type) { + switch(type) { + case T_STRING: return "T_STRING"; + case T_CHAR: return "T_CHAR"; + case T_INT: return "T_INT"; + case T_FLOAT: return "T_FLOAT"; + case T_BOOL: return "T_BOOL"; + case T_LBRACE: return "T_LBRACE"; + case T_RBRACE: return "T_RBRACE"; + case T_LBRACK: return "T_LBRACK"; + case T_RBRACK: return "T_RBRACK"; + case T_LPAR: return "T_LPAR"; + case T_RPAR: return "T_RPAR"; + case T_COMMA: return "T_COMMA"; + case T_VAR: return "T_VAR"; + case T_END: return "T_END"; + case T_SQUOTE: return "T_SQUOTE"; + case T_DQUOTE: return "T_DQUOTE"; + case T_END_FILE: return "T_END_FILE"; + default: return "???"; + } +} + +void pprint_token_type(FILE* file, lex_tok_t* token) { + fprintf(file, "%s", token_type_to_string(token->type)); +} + +void pprint_token_value(FILE* file, lex_tok_t* token) { + void* value = token->value; + switch(token->type) { + case T_STRING: fprintf(file, "'%s'", ((char*)value)); break; + case T_CHAR: fprintf(file, "\\%c", ((char)value)); break; + case T_INT: fprintf(file, "%d", *((long int*)value)); break; + case T_FLOAT: fprintf(file, "%f", *((double*)value)); break; + case T_BOOL: fprintf(file, "%b", ((bool)value)); break; + case T_VAR: fprintf(file, "%s", ((char*)value)); break; + default: fprintf(file, "???"); break; + } +} + +void pprint_token(FILE* file, lex_tok_t* token) +{ + pprint_token_type(file, token); + if (token->type < T_LBRACE) { + fprintf(file, ":"); + pprint_token_value(file, token); + } + fprintf(file, "\n"); +} + + +void pprint_tree(FILE* file, tree_t* tree) +{ + +} + diff --git a/source/sclpl/pprint.h b/source/sclpl/pprint.h new file mode 100644 index 0000000..a669982 --- /dev/null +++ b/source/sclpl/pprint.h @@ -0,0 +1,21 @@ +/** + @file pprint.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef PPRINT_H +#define PPRINT_H + +#include "parser.h" +#include "lexer.h" + +void pprint_token_type(FILE* file, lex_tok_t* token); + +void pprint_token_value(FILE* file, lex_tok_t* token); + +void pprint_token(FILE* file, lex_tok_t* token); + +void pprint_tree(FILE* file, tree_t* tree); + +#endif /* PPRINT_H */ diff --git a/spec/lexer_spec.rb b/spec/lexer_spec.rb index 0146519..95d192a 100644 --- a/spec/lexer_spec.rb +++ b/spec/lexer_spec.rb @@ -3,13 +3,14 @@ require 'open3' def lexer(input) out, err, status = Open3.capture3('./build/bin/sclpl-test', '--tokens', :stdin_data => input) raise "Lexer command returned non-zero status" unless status.success? - raise "Lexer produced error messages" unless err == "" + raise err unless err == "" out.gsub(//,'\1').split end describe "lexer" do it "should recognize punctuation" do - expect(lexer('[](){};\'",')).to eq( - ["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_VAR", "T_VAR", "T_END"]) + expect(lexer('[](){}\'",;')).to eq( + ["T_LBRACK", "T_RBRACK", "T_LPAR", "T_RPAR", "T_LBRACE", "T_RBRACE", "T_SQUOTE", "T_DQUOTE", "T_COMMA", "T_END"]) end end + diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index 1c86aff..9539ef5 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -29,6 +29,7 @@ end describe "parser" do it "should parse a definition" do - expect(parser('def foo 123;')).to eq([ ['T_VAR', 'T_VAR', 'T_INT'] ]) + expect(parser('def foo 123;')).to eq([ + ['T_VAR:def', 'T_VAR:foo', 'T_INT:123'] ]) end end