]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Added prettyprinting module
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 10 Oct 2014 01:39:42 +0000 (21:39 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 10 Oct 2014 01:39:42 +0000 (21:39 -0400)
source/sclpl/lexer.c
source/sclpl/lexer.h
source/sclpl/main.c
source/sclpl/pprint.c [new file with mode: 0644]
source/sclpl/pprint.h [new file with mode: 0644]
spec/lexer_spec.rb
spec/parser_spec.rb

index 19780d55c5d332ad664361e6a732fd20af6262c3..3881279e8ee782ca89b1b8355d5914650e9af5e1 100644 (file)
@@ -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);
index 8e06e986884226610ff6bc69b8260cc24d257b92..5fb0ea20a2b034bf3edece2da1d6cd15808f189b 100644 (file)
@@ -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 */
index 5f0a839f662a150840d90ec6ef814719eee83611..b8ec5abe6f27c32245fd23d5fdbc01bf902562dc 100644 (file)
@@ -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("<tok %s>\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("<tok %s>\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 (file)
index 0000000..2e1b6b8
--- /dev/null
@@ -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 (file)
index 0000000..a669982
--- /dev/null
@@ -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 */
index 01465198942e9629cd1b54f333eb3c07a52fe231..95d192a43f855b6351ea2ef0b057c7a73bdb23f7 100644 (file)
@@ -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(/<tok (T_[A-Z]+)>/,'\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
+
index 1c86affb7f20c050c80bfbe71aa5839bfbc0e9ef..9539ef52fae9d587b154bdc168a38a30219d33e6 100644 (file)
@@ -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