]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
tweaked tree building mechanism
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 28 Sep 2014 23:02:27 +0000 (19:02 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 28 Sep 2014 23:02:27 +0000 (19:02 -0400)
Rakefile
source/sclpl/grammar.c
source/sclpl/main.c
source/sclpl/parser.c
source/sclpl/parser.h

index a8db85613aea0ee73505317f3f8bf6582e44aa9f..89c7d610746441e9a92358118bdfc90429022e36 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -10,7 +10,7 @@ end
 # Define the compiler environment
 base_env = BuildEnv.new(echo: :command) do |env|
   env.build_dir('source','build/obj/source')
-  env.set_toolset(:gcc)
+  env.set_toolset(:clang)
   env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra'] #, '-Werror']
   env["CPPPATH"] += ['modules/libopts/source'] + Dir['modules/libcds/source/**/']
 end
index 2de905b3a3160f3f3f5590a766a1f3c3eac220fb..535863d70c629153712cd03038f99e8425a91764 100644 (file)
@@ -20,12 +20,15 @@ void grammar_toplevel(parser_t* p_parser)
 
 void grammar_import(parser_t* p_parser)
 {
+    size_t mark = parser_mark(p_parser);
     parser_expect(p_parser, T_VAR);
     parser_expect(p_parser, T_END);
+    parser_reduce(p_parser, mark);
 }
 
 void grammar_definition(parser_t* p_parser)
 {
+    size_t mark = parser_mark(p_parser);
     parser_expect(p_parser,T_VAR);
     if (parser_peek(p_parser)->type == T_LPAR) {
         grammar_fn_stmnt(p_parser);
@@ -33,6 +36,7 @@ void grammar_definition(parser_t* p_parser)
         grammar_expression(p_parser);
         parser_expect(p_parser,T_END);
     }
+    parser_reduce(p_parser, mark);
 }
 
 void grammar_expression(parser_t* p_parser)
@@ -74,6 +78,7 @@ void grammar_literal(parser_t* p_parser)
 
 void grammar_arglist(parser_t* p_parser)
 {
+    size_t mark = parser_mark(p_parser);
     parser_expect(p_parser, T_LPAR);
     while(parser_peek(p_parser)->type != T_RPAR) {
         grammar_expression(p_parser);
@@ -81,28 +86,35 @@ void grammar_arglist(parser_t* p_parser)
             parser_expect(p_parser, T_COMMA);
     }
     parser_expect(p_parser, T_RPAR);
+    parser_reduce(p_parser, mark);
 }
 
 void grammar_if_stmnt(parser_t* p_parser)
 {
+    size_t mark = parser_mark(p_parser);
     grammar_expression(p_parser);
     grammar_expression(p_parser);
     parser_expect_str(p_parser,T_VAR,"else");
     grammar_expression(p_parser);
     parser_expect(p_parser,T_END);
+    parser_reduce(p_parser, mark);
 }
 
 void grammar_fn_stmnt(parser_t* p_parser)
 {
+    size_t mark1 = parser_mark(p_parser);
     parser_expect(p_parser, T_LPAR);
+    size_t mark2 = parser_mark(p_parser);
     while(parser_peek(p_parser)->type != T_RPAR) {
         parser_expect(p_parser, T_VAR);
         if(parser_peek(p_parser)->type != T_RPAR)
             parser_expect(p_parser, T_COMMA);
     }
     parser_expect(p_parser, T_RPAR);
+    parser_reduce(p_parser, mark2);
     while(parser_peek(p_parser)->type != T_END) {
         grammar_expression(p_parser);
     }
     parser_expect(p_parser, T_END);
+    parser_reduce(p_parser, mark1);
 }
index 8a053611abfc7b2f7f1fc54e202441a5101ab28e..2dc49040838b6d51b9da8209443647cc5b6681a4 100644 (file)
@@ -13,6 +13,28 @@ OptionConfig_T Options_Config[] = {
 
 /* SCLPL Parser
  *****************************************************************************/
+
+void print_subtree(tree_t* p_tree, int depth);
+
+void print_tree(vec_t* p_vec, int depth);
+
+void print_subtree(tree_t* p_tree, int depth) {
+    for(int i = 0; i < (4 * depth); i++) printf("%c", ' ');
+    if (p_tree->tag == ATOM) {
+        puts("ATOM");
+    } else {
+        puts("TREE");
+        print_tree(p_tree->ptr.vec, depth+1);
+    }
+}
+
+void print_tree(vec_t* p_vec, int depth) {
+    for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
+        tree_t* p_tree = vec_at(p_vec, idx);
+        print_subtree(p_tree, depth);
+    }
+}
+
 /* TODO:
 
     * Formalize grammar for parser
@@ -27,6 +49,8 @@ int main(int argc, char **argv) {
     parser_t* p_parser = parser_new(":> ", stdin);
     while(!parser_eof(p_parser)) {
         grammar_toplevel(p_parser);
+        print_tree(p_parser->p_tok_buf, 0);
+        vec_clear(p_parser->p_tok_buf);
         puts("OK.");
     }
     mem_release(p_parser);
index 804284a9e29f837cdc9ddc0c773a901643129026..c359e02d5343351549051c1c7b926c3a1ec3f4ef 100644 (file)
@@ -26,6 +26,17 @@ parser_t* parser_new(char* p_prompt, FILE* input)
     return p_parser;
 }
 
+static void parser_tree_free(void* p_obj) {
+    mem_release(((tree_t*)p_obj)->ptr.tok);
+}
+
+static tree_t* parser_tree_new(tree_tag_t tag, void* p_obj) {
+    tree_t* p_tree = (tree_t*)mem_allocate(sizeof(tree_t), &parser_tree_free);
+    p_tree->tag     = tag;
+    p_tree->ptr.tok = (lex_tok_t*)p_obj;
+    return p_tree;
+}
+
 void parser_fetch(parser_t* p_parser)
 {
     p_parser->p_tok = lexer_read(p_parser->p_lexer);
@@ -55,7 +66,7 @@ bool parser_accept(parser_t* p_parser, lex_tok_type_t type)
 {
     bool ret = false;
     if (parser_peek(p_parser)->type == type) {
-        vec_push_back(p_parser->p_tok_buf, p_parser->p_tok);
+        vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
         p_parser->p_tok = NULL;
         ret = true;
     }
@@ -66,7 +77,7 @@ bool parser_accept_str(parser_t* p_parser, lex_tok_type_t type, const char* p_te
 {
     bool ret = false;
     if ((parser_peek(p_parser)->type == type) && (0 == strcmp((char*)(p_parser->p_tok->value), p_text))) {
-        vec_push_back(p_parser->p_tok_buf, p_parser->p_tok);
+        vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
         p_parser->p_tok = NULL;
         ret = true;
     }
@@ -94,3 +105,22 @@ bool parser_expect_str(parser_t* p_parser, lex_tok_type_t type, const char* p_te
     }
     return ret;
 }
+
+size_t parser_mark(parser_t* p_parser)
+{
+    return (vec_size(p_parser->p_tok_buf) - 1);
+}
+
+void parser_reduce(parser_t* p_parser, size_t mark)
+{
+    vec_t* p_buf  = p_parser->p_tok_buf;
+    vec_t* p_form = vec_new(0);
+    for(size_t idx = mark; idx < vec_size(p_buf); idx++) {
+        tree_tag_t tag = ((tree_t*)vec_at(p_buf, idx))->tag;
+        tree_t* p_tree = parser_tree_new(tag, mem_retain(vec_at(p_buf, idx)));
+        vec_push_back(p_form, p_tree);
+    }
+    vec_erase(p_parser->p_tok_buf, mark, vec_size(p_parser->p_tok_buf)-1);
+    vec_push_back(p_parser->p_tok_buf, parser_tree_new(TREE, p_form));
+}
+
index b427d7f8a688daf873f2184b7718d2ad055fbc7f..573354232a645c2859f15c1c7703a757c007986a 100644 (file)
 #include "lexer.h"
 #include "vec.h"
 
+typedef enum { ATOM, TREE } tree_tag_t;
+
+typedef struct {
+    tree_tag_t tag;
+    union {
+        lex_tok_t* tok;
+        vec_t* vec;
+    } ptr;
+} tree_t;
+
 typedef struct {
     lexer_t* p_lexer;
     lex_tok_t* p_tok;
@@ -34,4 +44,8 @@ bool parser_expect(parser_t* p_parser, lex_tok_type_t type);
 
 bool parser_expect_str(parser_t* p_parser, lex_tok_type_t type, const char* p_text);
 
+size_t parser_mark(parser_t* p_parser);
+
+void parser_reduce(parser_t* p_parser, size_t mark);
+
 #endif /* PARSER_H */