From 15535792241478e78d28f85c3f6a22a25e304de1 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 19 Aug 2014 16:34:13 -0400 Subject: [PATCH] Reworked parser and translation layer --- Gemfile.lock | 1 + Rakefile | 11 +++-- source/sclpl/ast.h | 1 + source/sclpl/grammar.c | 70 +++++++++++++------------- source/sclpl/grammar.y | 4 +- source/sclpl/main.c | 108 +++++++++++++++++++++++++++++++---------- 6 files changed, 131 insertions(+), 64 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b932f82..7b3953a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ GEM PLATFORMS ruby + x86-mingw32 DEPENDENCIES rake diff --git a/Rakefile b/Rakefile index 8175ae2..894833d 100644 --- a/Rakefile +++ b/Rakefile @@ -8,6 +8,11 @@ rescue Bundler::BundlerError => e raise LoadError.new("Unable to Bundler.setup(): You probably need to run `bundle install`: #{e.message}") end require 'rscons' +require 'rbconfig' + +def windows? + RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/ +end #------------------------------------------------------------------------------ # Clang Toolchain Targets @@ -18,7 +23,7 @@ CLANG_BIN_NAME = 'clang' CLANG_SRC_DIR = 'source/vendor/llvm-3.4.2' CLANG_CMAKE_GENERATOR = ENV['CMAKE_GENERATOR'] || "Unix Makefiles" CLANG_CMAKE_OPTS = [ '-DCMAKE_BUILD_TYPE=Release' ] -CLANG_MAKE_CMD = 'make' +CLANG_MAKE_CMD = windows? ? 'nmake' : 'make' file "#{CLANG_BUILD_DIR}/Makefile" => FileList["#{CLANG_SRC_DIR}/cmake/**/*"] do FileUtils.mkdir_p(CLANG_BUILD_DIR) @@ -34,7 +39,7 @@ file "#{CLANG_BIN_DIR}/#{CLANG_BIN_NAME}" => ["#{CLANG_BUILD_DIR}/Makefile"] + F end task :clang => ["#{CLANG_BIN_DIR}/#{CLANG_BIN_NAME}"] do - ENV['PATH'].unshift(CLANG_BIN_DIR) + ENV['PATH'] = "#{CLANG_BIN_DIR}#{windows? ? ';':':'}#{ENV['PATH']}" end #------------------------------------------------------------------------------ @@ -70,7 +75,7 @@ end task :default => [:build] desc "Build all targets" -task :build => [:sclpl] +task :build => [:clang, :sclpl] desc "Build the sclpl compiler and interpreter" task :sclpl => ['source/sclpl/grammar.c'] do diff --git a/source/sclpl/ast.h b/source/sclpl/ast.h index 0e124f7..12f11c6 100644 --- a/source/sclpl/ast.h +++ b/source/sclpl/ast.h @@ -13,6 +13,7 @@ typedef enum { BOOLEAN, INTEGER, + FLOAT, CHARACTER, STRING, SEXPR, diff --git a/source/sclpl/grammar.c b/source/sclpl/grammar.c index 3b1f391..0e5dc93 100644 --- a/source/sclpl/grammar.c +++ b/source/sclpl/grammar.c @@ -1,34 +1,36 @@ -const char Grammar[] = -"" -"replexpr : /[^\\n]*\\n/ ;" -"" -"expr : | | ;" -"" -"sexpr : '(' ( )* ')' ;" -"" -"qexpr : ('\\'' | '`' | ',') ;" -"" -"atom : | | | | | | ;" -"" -"int : /[-+]?[0-9]+/ ;" -"" -"float : /[-+]?[0-9]+\\.[0-9]+/ ;" -"" -"radixnum : \"0b\" /[0-1]+/" -" | \"0o\" /[0-7]+/" -" | \"0d\" /[0-9]+/" -" | \"0x\" /[0-9a-fA-F]+/" -" ;" -"" -"ch : '\\\\' (\"space\"|\"newline\"|\"return\"|\"tab\"|\"vtab\")" -" | '\\\\' /./" -" ;" -"" -"str : '\"' /[^\"]*/ '\"' ;" -"" -"bool : \"True\" | \"False\" ;" -"" -"var : /[^() \\t\\r\\n#`'\"]+/ ;" -"" -"ws : '#' /[^\\n]*\\n/ | /[ \\t\\r\\n]*/ ;" -; +const char Grammar[] = +"" +"program : /^/ /$/ ;" +"" +"replexpr : /[^\\n]*\\n/ ;" +"" +"expr : | | | | | | | | ;" +"" +"sexpr : '(' ( )* ')' ;" +"" +"qexpr : ('\\'' | '`' | ',') ;" +"" +"atom : | | | | | | ;" +"" +"int : /[-+]?[0-9]+/ ;" +"" +"float : /[-+]?[0-9]+\\.[0-9]+/ ;" +"" +"radixnum : \"0b\" /[0-1]+/" +" | \"0o\" /[0-7]+/" +" | \"0d\" /[0-9]+/" +" | \"0x\" /[0-9a-fA-F]+/" +" ;" +"" +"ch : '\\\\' (\"space\"|\"newline\"|\"return\"|\"tab\"|\"vtab\")" +" | '\\\\' /./" +" ;" +"" +"str : '\"' /[^\"]*/ '\"' ;" +"" +"bool : \"True\" | \"False\" ;" +"" +"var : /[^() \\t\\r\\n#`'\"]+/ ;" +"" +"ws : '#' /[^\\n]*\\n/ | /[ \\t\\r\\n]*/ ;" +; diff --git a/source/sclpl/grammar.y b/source/sclpl/grammar.y index 2d1bc6e..3ed52d9 100644 --- a/source/sclpl/grammar.y +++ b/source/sclpl/grammar.y @@ -1,7 +1,9 @@ +program : /^/ /$/ ; + replexpr : /[^\n]*\n/ ; -expr : | | ; +expr : | | | | | | | | ; sexpr : '(' ( )* ')' ; diff --git a/source/sclpl/main.c b/source/sclpl/main.c index 71535b8..a739c37 100644 --- a/source/sclpl/main.c +++ b/source/sclpl/main.c @@ -1,39 +1,93 @@ #include "mpc.h" #include "ast.h" #include +#include /* SCLPL Parser *****************************************************************************/ /* Grammar is auto generated into 'source/grammar.c' */ extern const char Grammar[]; +static ast_t* read_sexpr(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_qexpr(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_char(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_string(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_var(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_bool(const mpc_ast_t* t) { + (void)t; + return NULL; +} + +static ast_t* read_float(const mpc_ast_t* t) { + double* p_dbl = (double*)malloc(sizeof(double)); + ast_t* p_ast = ast_new(FLOAT, p_dbl); + ast_set_pos(p_ast, "", t->state.row, t->state.col); + errno = 0; + *p_dbl = strtod(t->contents, NULL); + assert(errno == 0); + return p_ast; +} + +static ast_t* read_int(const mpc_ast_t* t, int base) { + long* p_int = (long*)malloc(sizeof(long)); + printf("reading int with base: %d\n", base); + ast_t* p_ast = ast_new(INTEGER, p_int); + ast_set_pos(p_ast, "", t->state.row, t->state.col); + errno = 0; + *p_int = strtol(t->contents, NULL, base); + assert(errno == 0); + return p_ast; +} + +static int read_radix(const mpc_ast_t* t) { + switch( t->children[0]->contents[1] ) { + case 'b': return 2; + case 'o': return 8; + case 'd': return 10; + case 'x': return 16; + default: return 10; + } +} + ast_t* format_expr_ast(mpc_ast_t* expr) { - ast_t* p_ast = ast_new(UNKNOWN,NULL); - ast_set_pos(p_ast, "", expr->state.row, expr->state.col); + ast_t* p_ast = NULL; /* Handle the current node */ - if (0 == strcmp("expr|atom|num|regex", expr->tag)) { - puts("parsing integer/float"); - } else if (0 == strcmp("num|>", expr->tag)) { - puts("parsing radix literal"); - } else if (0 == strcmp("str|>", expr->tag)) { - puts("parsing string literal"); + if (0 == strcmp("sexpr|>", expr->tag)) { + } else if (0 == strcmp("qexpr|>", expr->tag)) { + } else if (0 == strcmp("radixnum|>", expr->tag)) { + p_ast = read_int(expr->children[1], read_radix(expr)); + printf("int: %d\n", *((long*)p_ast->value)); + } else if (0 == strcmp("expr|float|regex", expr->tag)) { + p_ast = read_float(expr); + printf("double: %f\n", *((double*)p_ast->value)); + } else if (0 == strcmp("expr|int|regex", expr->tag)) { + p_ast = read_int(expr,10); + printf("int: %d\n", *((long*)p_ast->value)); } else if (0 == strcmp("ch|>", expr->tag)) { - puts("parsing char literal"); - } else if (0 == strcmp("expr|atom|var|regex", expr->tag)) { - puts("parsing variable"); - } else if (0 == strcmp("expr|atom|bool|string", expr->tag)) { - puts("parsing boolean"); - } else if (0 == strcmp("expr|>", expr->tag)) { - ast_set_type(p_ast, SEXPR); - /* Handle the current node's children */ - for (int i = 0; i < expr->children_num; i++) { - mpc_ast_t* child = expr->children[i]; - if ((0 != strncmp(child->tag,"ws",2)) && - (0 != strncmp(child->tag,"char",4))) { - ast_add_child(p_ast, format_expr_ast(expr->children[i])); - } - } + } else if (0 == strcmp("str|>", expr->tag)) { + } else if (0 == strcmp("expr|bool|str", expr->tag)) { + } else if (0 == strcmp("expr|var|regex", expr->tag)) { } else { printf("unknown tag: '%s'\n", expr->tag); free(p_ast->pos); @@ -50,14 +104,16 @@ int main(int argc, char **argv) { mpc_parser_t* SExpr = mpc_new("sexpr"); mpc_parser_t* QExpr = mpc_new("qexpr"); mpc_parser_t* Atom = mpc_new("atom"); - mpc_parser_t* Num = mpc_new("num"); + mpc_parser_t* Int = mpc_new("int"); + mpc_parser_t* Float = mpc_new("float"); + mpc_parser_t* Radix = mpc_new("radixnum"); mpc_parser_t* Char = mpc_new("ch"); mpc_parser_t* String = mpc_new("str"); mpc_parser_t* Bool = mpc_new("bool"); mpc_parser_t* Var = mpc_new("var"); mpc_parser_t* WS = mpc_new("ws"); mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE, Grammar, - ReplExpr, Expr, SExpr, QExpr, Atom, Num, Char, String, Bool, Var, WS, NULL); + ReplExpr, Expr, SExpr, QExpr, Atom, Int, Float, Radix, Char, String, Bool, Var, WS, NULL); while(!feof(stdin)) { mpc_result_t r; printf(":> "); @@ -72,6 +128,6 @@ int main(int argc, char **argv) { while('\n' != fgetc(stdin)){} } } - mpc_cleanup(11, ReplExpr, Expr, SExpr, QExpr, Atom, Num, Char, String, Bool, Var, WS); + mpc_cleanup(13, ReplExpr, Expr, SExpr, QExpr, Atom, Int, Float, Radix, Char, String, Bool, Var, WS); return 0; } -- 2.49.0