summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bnf/ast_types.hpp22
-rw-r--r--bnf/common.hpp21
-rw-r--r--bnf/main.cpp155
-rw-r--r--bnf/rust.y63
-rw-r--r--bnf/rust_expr.y.h4
-rw-r--r--bnf/rust_expr.y_tree.h8
6 files changed, 178 insertions, 95 deletions
diff --git a/bnf/ast_types.hpp b/bnf/ast_types.hpp
index cef70bc5..daa71b89 100644
--- a/bnf/ast_types.hpp
+++ b/bnf/ast_types.hpp
@@ -115,6 +115,7 @@ public:
class Item
{
bool m_is_pub;
+protected:
AttrList m_attrs;
public:
Item():
@@ -148,7 +149,11 @@ class Module:
bool m_is_extern;
::std::string m_name;
ItemList m_items;
+
+ ::std::vector<::std::string> m_mod_path;
+ ::std::string m_filename, m_base_dir;
public:
+ Module(Module&&) = default;
Module(::std::string name):
m_is_extern(true),
m_name(name)
@@ -158,15 +163,32 @@ public:
m_is_extern(false),
m_items( ::std::move(items) )
{}
+ Module& operator=(Module&& x) {
+ assert(m_is_extern);
+ assert(x.m_name == "");
+ m_items = ::std::move(x.m_items);
+ this->add_attrs( ::std::move(x.m_attrs) );
+ }
bool is_external() const { return m_is_extern; }
const ::std::string& name() const { return m_name; }
+ const ::std::string& filename() const { return m_filename; }
+ const ::std::string& base_dir() const { return m_base_dir; }
+ const ::std::vector<::std::string>& mod_path() const { return m_mod_path; }
void set_name(::std::string name) {
assert(m_name == "");
m_name = name;
}
+ void set_mod_path(::std::vector<::std::string> mod_path) {
+ m_mod_path = ::std::move(mod_path);
+ }
+ void set_paths(::std::string filename, ::std::string base_dir) {
+ m_filename = filename;
+ m_base_dir = base_dir;
+ }
+
ItemList& items() {
return m_items;
}
diff --git a/bnf/common.hpp b/bnf/common.hpp
new file mode 100644
index 00000000..2a74a7ba
--- /dev/null
+++ b/bnf/common.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+namespace std {
+
+template <typename T>
+inline ::std::ostream& operator<<(::std::ostream& os, const ::std::vector<T>& v) {
+ if( v.size() > 0 )
+ {
+ bool is_first = true;
+ for( const auto& i : v )
+ {
+ if(!is_first)
+ os << ", ";
+ is_first = false;
+ os << i;
+ }
+ }
+ return os;
+}
+
+};
diff --git a/bnf/main.cpp b/bnf/main.cpp
index f88eb21f..020ff0f6 100644
--- a/bnf/main.cpp
+++ b/bnf/main.cpp
@@ -1,52 +1,56 @@
#include <stdio.h>
#include <string.h>
+#include <iostream>
#include "lex.hpp"
+#include "common.hpp"
extern FILE* yyin;
::std::string get_dir_path(const ::std::string& input) {
auto pos = input.rfind("/");
if( pos == ::std::string::npos) {
- return "";
+ return "./";
}
else {
return ::std::string( input, 0, input.rfind("/") + 1 );
}
}
-int main(int argc, char *argv[]) {
- const char *base_filename;
- if(argc < 2 || strcmp(argv[1], "-") == 0) {
- yyin = stdin;
- base_filename = "-";
- }
- else {
- base_filename = argv[1];
- yyin = fopen(argv[1], "r");
+::std::unique_ptr<Module> parse_module_file(::std::string filename, ::std::string base_path)
+{
+ ::std::cout << "filename = " << filename << ", base_path = " << base_path << ";" << ::std::endl;
+
+ if( filename != "-" ) {
+ yyin = fopen(filename.c_str(), "r");
if( !yyin ) {
- fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", argv[1], strerror(errno));
- return 1;
+ fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", filename.c_str(), strerror(errno));
+ exit(1);
}
}
- yylineno = 1;
- yydebug = (getenv("BNFDEBUG") != NULL);
-
- ParserContext context(base_filename);
- if( context.filename != "-" ) {
- context.base_path = get_dir_path(context.filename);
- }
+ ParserContext context( ::std::move(filename) );
+ context.base_path = ::std::move(base_path);
+
+ yylineno = 1;
int rv = yyparse(context);
- fclose(yyin);
+ if( yyin != stdin ) {
+ fclose(yyin);
+ }
if( rv != 0 ) {
- return rv;
+ exit(1);
}
-
+
assert( context.output_module.get() );
- auto& mod = *context.output_module;
- printf("output module = %p\n", &mod);
+ //context.output_module->set_paths( ::std::move(context.filename), ::std::move(context.base_path) );
+ return ::std::move(context.output_module);
+}
+
+void post_process_module(Module& mod, const ::std::string& mod_filename, const ::std::string& mod_dir_path)
+{
+ ::std::cout << "mod = ["<<mod.mod_path()<<"], mod_filename = " << mod_filename << ", mod_dir_path = " << mod_dir_path << ";" << ::std::endl;
- for(auto& item : mod.items()) {
+ for(auto& item : mod.items())
+ {
Module* opt_submod = dynamic_cast<Module*>(item.get());
if( !opt_submod ) continue;
Module& submod = *opt_submod;
@@ -54,49 +58,78 @@ int main(int argc, char *argv[]) {
if( ! submod.is_external() ) {
// - inline modules can be ignored.. for now
- continue ;
- }
- ::std::string filename;
- ::std::string base_path;
- if( context.filename == "-" ) {
- return 1;
- }
- else if( submod.attrs().has("path") ) {
- filename = get_dir_path(context.filename) + submod.attrs().get_first("path").string();
- base_path = get_dir_path(filename);
- }
- else if( context.base_path == "" ) {
- return 1;
+ if( mod_dir_path != "" ) {
+ submod.set_paths( mod_filename, mod_dir_path + submod.name() + "/" );
+ }
}
- else {
- filename = context.base_path + submod.name() + ".rs";
- base_path = "";
- yyin = fopen( filename.c_str(), "r" );
- if( !yyin ) {
- printf("> '%s' not found\n", filename.c_str());
- base_path = context.base_path + submod.name() + "/";
- filename = base_path + "mod.rs";
+ else
+ {
+ ::std::string filename;
+ ::std::string base_path;
+ if( mod_filename == "-" ) {
+ fprintf(stderr, "ERROR: Referencing 'mod %s;' from stdin\n", submod.name().c_str());
+ exit(1);
+ }
+ else if( submod.attrs().has("path") ) {
+ filename = get_dir_path(mod_filename) + submod.attrs().get_first("path").string();
+ base_path = get_dir_path(filename);
+ }
+ else if( mod_dir_path == "" ) {
+ fprintf(stderr, "ERROR: Referencing 'mod %s;' from non-controlling file\n", submod.name().c_str());
+ exit(1);
}
else {
- fclose(yyin);
+ filename = mod_dir_path + submod.name() + ".rs";
+ base_path = "";
+ yyin = fopen( filename.c_str(), "r" );
+ if( !yyin ) {
+ printf("> '%s' not found\n", filename.c_str());
+ base_path = mod_dir_path + submod.name() + "/";
+ filename = base_path + "mod.rs";
+ }
+ else {
+ fclose(yyin);
+ }
}
- }
- assert(filename.size() > 0);
- yyin = fopen( filename.c_str(), "r" );
- if( !yyin ) {
- printf("> '%s' not found\n", filename.c_str());
- return 1;
+
+ assert(filename.size() > 0);
+ submod = ::std::move( *parse_module_file(filename, base_path) );
+ submod.set_paths( filename, base_path );
}
- ParserContext new_context(filename);
- yylineno = 1;
- int rv = yyparse(new_context);
- fclose(yyin);
- if( rv != 0 ) {
- return rv;
- }
- submod = ::std::move( *new_context.output_module );
+ auto mp = mod.mod_path();
+ mp.push_back(submod.name());
+ submod.set_mod_path(::std::move(mp));
+ }
+
+ for(auto& item : mod.items())
+ {
+ Module* opt_submod = dynamic_cast<Module*>(item.get());
+ if( !opt_submod ) continue;
+ Module& submod = *opt_submod;
+
+ const ::std::string& submod_fname = submod.filename();
+ const ::std::string& submod_dir = submod.base_dir();
+ post_process_module(submod, submod_fname, submod_dir);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ ::std::string base_filename;
+ if(argc < 2 || strcmp(argv[1], "-") == 0) {
+ yyin = stdin;
+ base_filename = "-";
}
+ else {
+ base_filename = argv[1];
+ }
+ yydebug = (getenv("BNFDEBUG") != NULL);
+
+ ::std::string base_path = (base_filename == "-" ? ::std::string("") : get_dir_path(base_filename));
+ auto mod = parse_module_file(base_filename, base_path);
+ printf("output module = %p\n", &*mod);
+
+ post_process_module(*mod, base_filename, base_path);
return 0;
}
diff --git a/bnf/rust.y b/bnf/rust.y
index 7e460fd0..20b81dec 100644
--- a/bnf/rust.y
+++ b/bnf/rust.y
@@ -73,19 +73,19 @@
%{
// TODO: Replace this with a C++-safe printf
-/*static inline*/ void bnf_trace(const char* fmt, ...) {
- fprintf(stderr, "\x1b[32m""TRACE: ");
+/*static inline*/ void bnf_trace(const ParserContext& context, const char* fmt, ...) {
+ fprintf(stderr, "\x1b[32m""TRACE:%s:%i: ", context.filename.c_str(), yylineno);
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\x1b[0m\n");
}
-/*static inline*/ void bnf_trace(const char* fmt, const ::std::string* s) {
- bnf_trace(fmt, s->c_str(), '0');
+/*static inline*/ void bnf_trace(const ParserContext& context, const char* fmt, const ::std::string* s) {
+ bnf_trace(context, fmt, s->c_str(), '0');
}
-/*static inline*/ void bnf_trace(const char* fmt, const ::std::string& s) {
- bnf_trace(fmt, s.c_str(), '0');
+/*static inline*/ void bnf_trace(const ParserContext& context, const char* fmt, const ::std::string& s) {
+ bnf_trace(context, fmt, s.c_str(), '0');
}
%}
@@ -121,8 +121,8 @@ super_attrs
;
opt_pub
- : /* mt */ { $$ = false; bnf_trace("private"); }
- | RWD_pub { $$ = true; bnf_trace("public"); }
+ : /* mt */ { $$ = false; bnf_trace(context, "private"); }
+ | RWD_pub { $$ = true; bnf_trace(context, "public"); }
;
opt_comma: | ',';
opt_semicolon: | ';';
@@ -208,14 +208,14 @@ extern_item
module_def
: IDENT '{' module_root '}' { $3->set_name( consume($1) ); $$ = new Module(consume($3)); }
- | IDENT ';' { bnf_trace("mod %s;", $1); $$ = new Module( consume($1) ); }
+ | IDENT ';' { bnf_trace(context, "mod %s;", $1); $$ = new Module( consume($1) ); }
;
/* --- Function --- */
-fn_def: fn_def_hdr code { bnf_trace("function defined"); };
-fn_def_hdr: IDENT generic_def '(' fn_def_args ')' fn_def_ret where_clause { $$ = new Fn(); bnf_trace("function '%s'", *$1); };
+fn_def: fn_def_hdr code { bnf_trace(context, "function defined"); };
+fn_def_hdr: IDENT generic_def '(' fn_def_args ')' fn_def_ret where_clause { $$ = new Fn(); bnf_trace(context, "function '%s'", *$1); };
-fn_def_hdr_PROTO: IDENT generic_def '(' fn_def_args_PROTO ')' fn_def_ret where_clause { $$ = new Fn(); bnf_trace("function '%s'", *$1); };
+fn_def_hdr_PROTO: IDENT generic_def '(' fn_def_args_PROTO ')' fn_def_ret where_clause { $$ = new Fn(); bnf_trace(context, "function '%s'", *$1); };
fn_def_ret
: /* -> () */
@@ -267,6 +267,7 @@ use_def
| DOUBLECOLON use_path use_def_tail { $$ = new UseSet(/* TODO */); }
| use_path use_def_tail { $$ = new UseSet(/* TODO */); }
| '{' use_picks '}' ';' { $$ = new UseSet( Path(Path::TagAbs()), consume($2) ); }
+ | DOUBLECOLON '{' use_picks '}' ';' { $$ = new UseSet( Path(Path::TagAbs()), consume($3) ); }
;
use_def_tail
: RWD_as IDENT ';' { $$ = new UseItems(UseItems::TagRename(), consume($2) ); }
@@ -296,9 +297,9 @@ const_value
/* --- Struct --- */
struct_def
- : IDENT generic_def where_clause ';' { $$ = new Struct(); bnf_trace("unit-like struct"); }
- | IDENT generic_def '(' tuple_struct_def_items opt_comma ')' where_clause ';' { $$ = new Struct(); bnf_trace("tuple struct"); }
- | IDENT generic_def where_clause '{' struct_def_items opt_comma '}' { $$ = new Struct(); bnf_trace("normal struct"); }
+ : IDENT generic_def where_clause ';' { $$ = new Struct(); bnf_trace(context, "unit-like struct"); }
+ | IDENT generic_def '(' tuple_struct_def_items opt_comma ')' where_clause ';' { $$ = new Struct(); bnf_trace(context, "tuple struct"); }
+ | IDENT generic_def where_clause '{' struct_def_items opt_comma '}' { $$ = new Struct(); bnf_trace(context, "normal struct"); }
;
tuple_struct_def_items
@@ -309,7 +310,7 @@ tuple_struct_def_item: attrs opt_pub type;
struct_def_items
: struct_def_items ',' struct_def_item
- | struct_def_item { bnf_trace("struct_def_item"); }
+ | struct_def_item { bnf_trace(context, "struct_def_item"); }
;
struct_def_item: attrs opt_pub IDENT ':' type;
@@ -342,10 +343,10 @@ trait_item
/* --- Impl --- */
impl_def: impl_def_line '{' impl_items '}' { $$ = new Impl(); };
impl_def_line
- : generic_def trait_path RWD_for type where_clause { bnf_trace("trait impl"); }
- | generic_def '!' trait_path RWD_for type where_clause { bnf_trace("negative trait impl"); }
- | generic_def trait_path RWD_for DOUBLEDOT where_clause { bnf_trace("wildcard impl"); }
- | generic_def type where_clause { bnf_trace("inherent impl"); }
+ : generic_def trait_path RWD_for type where_clause { bnf_trace(context, "trait impl"); }
+ | generic_def '!' trait_path RWD_for type where_clause { bnf_trace(context, "negative trait impl"); }
+ | generic_def trait_path RWD_for DOUBLEDOT where_clause { bnf_trace(context, "wildcard impl"); }
+ | generic_def type where_clause { bnf_trace(context, "inherent impl"); }
;
impl_items: | impl_items attrs impl_item;
impl_item
@@ -356,12 +357,12 @@ impl_item
/* Generic paramters */
-generic_def : /* mt */ | '<' generic_def_list '>' { bnf_trace("generic_def_list"); };
+generic_def : /* mt */ | '<' generic_def_list '>' { bnf_trace(context, "generic_def_list"); };
generic_def_list : generic_def_one | generic_def_list ',' generic_def_one | ;
generic_def_one
: IDENT ':' bounds '=' type
| IDENT '=' type
- | IDENT ':' bounds { bnf_trace("bounded ident"); }
+ | IDENT ':' bounds { bnf_trace(context, "bounded ident"); }
| IDENT
| LIFETIME
| LIFETIME ':' LIFETIME
@@ -394,7 +395,7 @@ dlt: DOUBLELT { context.pushback('<'); context.pushback('<'); }
type_args
: '<' type_exprs '>'
- | '<' type_exprs DOUBLEGT { bnf_trace("Double-gt terminated type expr"); context.pushback('>'); }
+ | '<' type_exprs DOUBLEGT { bnf_trace(context, "Double-gt terminated type expr"); context.pushback('>'); }
| dlt type_args
;
@@ -512,6 +513,8 @@ nonbind_pattern
| value_pattern TRIPLEDOT value_pattern
| '&' pattern
| '&' RWD_mut pattern
+ | DOUBLEAMP pattern
+ | DOUBLEAMP RWD_mut pattern
;
value_pattern
: expr_path
@@ -531,7 +534,7 @@ pattern_list
Expressions!
=========================================
*/
-code: block { bnf_trace("code parsed"); };
+code: block { bnf_trace(context, "code parsed"); };
block: '{' block_contents '}';
@@ -544,10 +547,10 @@ tail_expr
| flow_control
;
flow_control
- : RWD_return opt_semicolon {}
- | RWD_return expr_0 opt_semicolon {}
- | RWD_break opt_lifetime opt_semicolon {}
- | RWD_continue opt_lifetime opt_semicolon {}
+ : RWD_return {}
+ | RWD_return expr_0 {}
+ | RWD_break opt_lifetime {}
+ | RWD_continue opt_lifetime {}
;
block_lines: | block_lines block_line;
block_line
@@ -581,7 +584,7 @@ expr_blocks
: RWD_match expr_NOSTRLIT '{' match_arms '}' { }
| RWD_if if_block
| RWD_unsafe '{' block_contents '}' { }
-/* | flow_control */
+ | flow_control
| loop_block
| block
;
@@ -624,7 +627,7 @@ match_arm
| match_arm_brace
;
match_arm_brace : match_patterns FATARROW '{' block_contents '}' { };
-match_arm_expr: match_patterns FATARROW tail_expr { bnf_trace("match_arm"); };
+match_arm_expr: match_patterns FATARROW tail_expr { bnf_trace(context, "match_arm"); };
/* rust_expr.y.h inserted */
diff --git a/bnf/rust_expr.y.h b/bnf/rust_expr.y.h
index 78121070..7b3494c8 100644
--- a/bnf/rust_expr.y.h
+++ b/bnf/rust_expr.y.h
@@ -9,6 +9,10 @@ closure_arg
: pattern
| pattern ':' type
;
+closure_ret
+ :
+ | THINARROW type
+ ;
#define SUFFIX_is_
#define _(v) v
diff --git a/bnf/rust_expr.y_tree.h b/bnf/rust_expr.y_tree.h
index 26beb77c..756e5e4a 100644
--- a/bnf/rust_expr.y_tree.h
+++ b/bnf/rust_expr.y_tree.h
@@ -62,7 +62,7 @@ _(expr_9)
/* 10: Cast */
_(expr_cast)
: _(expr_11)
- | _(expr_cast) RWD_as type_ele { bnf_trace("expr:cast"); }
+ | _(expr_cast) RWD_as type_ele { bnf_trace(context, "expr:cast"); }
;
/* 11: Times/Div/Modulo */
_(expr_11)
@@ -95,7 +95,7 @@ _(expr_fc)
_(expr_value)
: CHARLIT | INTEGER | FLOAT | STRING
| expr_blocks
- | expr_path '(' expr_list ')' { bnf_trace("function call"); }
+ | expr_path '(' expr_list ')' { bnf_trace(context, "function call"); }
#ifndef SUFFIX_is__NOSTRLIT
| expr_path '{' struct_literal_list '}'
| expr_path '{' struct_literal_list ',' '}'
@@ -108,7 +108,7 @@ _(expr_value)
| '(' expr ',' expr_list ')'
| '[' expr_list opt_comma ']'
| '[' expr ';' expr ']'
- | MACRO tt_paren { bnf_trace("Expr macro invocation"); }
- | '|' closure_arg_list '|' expr
+ | MACRO tt_paren { bnf_trace(context, "Expr macro invocation"); }
+ | '|' closure_arg_list '|' closure_ret expr
| DOUBLEPIPE expr
;