summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bnf/Makefile31
-rw-r--r--bnf/ast_types.hpp205
-rw-r--r--bnf/lex.hpp33
-rw-r--r--bnf/main.cpp105
-rw-r--r--bnf/rust.lex89
-rw-r--r--bnf/rust.y149
-rw-r--r--bnf/rust_tts.y.h17
7 files changed, 496 insertions, 133 deletions
diff --git a/bnf/Makefile b/bnf/Makefile
index 175f6b9e..e85e5fa4 100644
--- a/bnf/Makefile
+++ b/bnf/Makefile
@@ -1,27 +1,36 @@
.SUFFIXES:
-all: test.bin
-TSTFILES := ../samples/1.rs
-TSTFILES := $(addprefix ../../rust_os/libcore/, lib.rs str/mod.rs str/pattern.rs borrow.rs any.rs array.rs result.rs)
+OBJS := main.o rust.tab.o rust.lex.o
-test: test.bin $(TSTFILES)
- $(foreach f,$(TSTFILES), ./test.bin "$f" &&) true
+#TSTFILES := ../samples/1.rs
+TSTFILES := ../../rust_os/rustc_src/libcore/lib.rs
+#TSTFILES := $(addprefix ../../rust_os/libcore/, lib.rs str/mod.rs str/pattern.rs borrow.rs any.rs array.rs result.rs)
+
+
+
+all: test.bin
-OBJS := rust.tab.o rust.lex.o
+test: test.bin $(TSTFILES)
+ $(foreach f,$(TSTFILES), $(DBG) ./test.bin "$f" &&) true
test.bin: $(OBJS)
g++ -std=c++11 $(OBJS) -o $@
-%.o: %.cpp
+%.o: %.cpp ast_types.hpp
g++ -x c++ -std=c++11 $< -c -o $@ -I .
-%.o: .gen/%.cpp
+%.o: .gen/%.cpp ast_types.hpp
g++ -x c++ -std=c++11 $< -c -o $@ -I .
.gen/rust.tab.cpp: .gen/.rust.y
@mkdir -p $(dir $@)
- bison -o $@ $< -d --verbose
+ @echo [BISON] $@
+ @bison -o $@ $< -d --verbose
+# HACK: Bison emits duplicate entries in the union, remove those
+ @mv $(@:%.cpp=%.hpp) $(@:%.cpp=%.hpp.OLD)
+ @awk '{ if($$0 ~ /yacc.c:1909/) { ignore = 1; print $$0; } else if( ignore == 1 ) { trigger = $$0; ignore = 2; } else if( ignore == 2 ) { if($$0 == trigger) { ignore = 0 } } if( ignore > 0 ) { } else { print $$0; } }' < ${@:%.cpp=%.hpp.OLD} > $(@:%.cpp=%.hpp)
+.gen/rust.tab.hpp: .gen/rust.tab.cpp
.gen/.rust.y: Makefile rust.y rust_expr.y.h rust_tts.y.h
@mkdir -p $(dir $@)
@@ -33,5 +42,7 @@ test.bin: $(OBJS)
.gen/rust.lex.cpp: rust.lex
@mkdir -p $(dir $@)
flex -o $@ $<
-
+
+
+main.cpp: .gen/rust.tab.hpp
diff --git a/bnf/ast_types.hpp b/bnf/ast_types.hpp
index 5ed473f7..09896642 100644
--- a/bnf/ast_types.hpp
+++ b/bnf/ast_types.hpp
@@ -3,6 +3,7 @@
#include <vector>
#include <memory>
#include <utility>
+#include <cassert>
template<typename T>
T consume(T* ptr) {
@@ -19,6 +20,21 @@ template<typename T>
return ::std::unique_ptr<T>(new T(::std::move(ptr)));
}
+
+class Path
+{
+public:
+ struct TagSelf {};
+ Path(TagSelf)
+ {}
+ struct TagSuper {};
+ Path(TagSuper)
+ {}
+ struct TagAbs {};
+ Path(TagAbs)
+ {}
+};
+
class MetaItem;
typedef ::std::vector<MetaItem> MetaItems;
@@ -27,6 +43,7 @@ class MetaItem
::std::string m_key;
::std::string m_value;
MetaItems m_sub_items;
+ // TODO: How to represent `#[attr()]` (i.e. empty paren set) as distinct from `#[attr=""]` and `#[attr]`
public:
MetaItem(::std::string key):
m_key(key)
@@ -39,13 +56,42 @@ public:
m_key(key),
m_sub_items(sub_items)
{}
+
+ const ::std::string& key() const { return m_key; }
+ const ::std::string& string() const { assert(m_sub_items.size() == 0); return m_value; }
};
-class Attr
+class AttrList
{
+ ::std::vector<MetaItem> m_ents;
public:
- Attr(MetaItems items);
+ bool has(const char* name) const {
+ return get_first_ptr(name) != nullptr;
+ }
+ bool has(const ::std::string& name) const {
+ return this->has(name.c_str());
+ }
+
+ const MetaItem* get_first_ptr(const char* name) const {
+ for(const auto& e : m_ents) {
+ if( e.key() == name)
+ return &e;
+ }
+ return nullptr;
+ }
+ const MetaItem& get_first(const char* name) const {
+ auto p = get_first_ptr(name);
+ assert(p != 0);
+ return *p;
+ }
+
+ void push_back(MetaItem a) {
+ m_ents.push_back( ::std::move(a) );
+ }
+ void append(AttrList other) {
+ for(auto& e : other.m_ents)
+ m_ents.push_back( ::std::move(e) );
+ }
};
-typedef ::std::vector<Attr> AttrList;
class TokenTree;
@@ -53,19 +99,45 @@ typedef ::std::vector<TokenTree> TokenTreeList;
class TokenTree
{
+ int m_tok;
+ TokenTreeList m_subtts;
public:
- TokenTree(TokenTreeList tts);
- TokenTree(int tok);
+ TokenTree(TokenTreeList tts):
+ m_tok(0),
+ m_subtts(tts)
+ {}
+ TokenTree(int tok):
+ m_tok(tok)
+ {}
};
class Item
{
+ bool m_is_pub;
+ AttrList m_attrs;
public:
- void set_pub();
- void add_attrs(AttrList);
+ Item():
+ m_is_pub(false)
+ {}
+ Item(AttrList attrs):
+ m_attrs(attrs)
+ {}
+ virtual ~Item() {
+ }
+
+ void set_pub() {
+ m_is_pub = true;
+ }
+ void add_attrs(AttrList a) {
+ m_attrs.append( ::std::move(a) );
+ }
+
+ const AttrList& attrs() const { return m_attrs; }
};
+typedef ::std::vector< ::std::unique_ptr<Item> > ItemList;
+
class Global:
public Item
{
@@ -73,19 +145,128 @@ class Global:
class Module:
public Item
{
+ bool m_is_extern;
+ ::std::string m_name;
+ ItemList m_items;
public:
- Module(::std::string name);
- Module(AttrList attrs, ::std::vector< ::std::unique_ptr<Item> > items);
+ Module(::std::string name):
+ m_is_extern(true),
+ m_name(name)
+ {}
+ Module(AttrList attrs, ::std::vector< ::std::unique_ptr<Item> > items):
+ Item(attrs),
+ m_is_extern(false),
+ m_items( ::std::move(items) )
+ {}
+
+ bool is_external() const { return m_is_extern; }
+ const ::std::string& name() const { return m_name; }
+
+ void set_name(::std::string name) {
+ assert(m_name == "");
+ m_name = name;
+ }
- void set_name(::std::string name);
+ ItemList& items() {
+ return m_items;
+ }
};
class Macro:
public Item
{
+ ::std::string m_name;
+ ::std::string m_ident;
+ TokenTree m_args;
public:
- Macro(::std::string name, TokenTree contents);
- Macro(::std::string name, ::std::string ident, TokenTree contents);
+ Macro(::std::string name, TokenTree contents):
+ m_name(name),
+ m_ident(),
+ m_args(contents)
+ {}
+ Macro(::std::string name, ::std::string ident, TokenTree contents):
+ m_name(name),
+ m_ident(ident),
+ m_args(contents)
+ {}
};
+class UseItem
+{
+ ::std::string m_name;
+public:
+ struct TagSelf {};
+ UseItem(TagSelf):
+ m_name()
+ {}
+ UseItem(::std::string name):
+ m_name(name)
+ {}
+};
+class UseItems
+{
+ ::std::string m_alias;
+ ::std::vector<UseItem> m_items;
+public:
+ UseItems():
+ m_alias()
+ {}
+ struct TagWildcard {};
+ UseItems(TagWildcard):
+ m_alias("*")
+ {}
+ struct TagRename {};
+ UseItems(TagRename, ::std::string name):
+ m_alias(name)
+ {}
+ UseItems(::std::vector<UseItem> items):
+ m_alias(),
+ m_items(items)
+ {}
+};
+class UseSet:
+ public Item
+{
+public:
+ UseSet()
+ {}
+ UseSet(Path base, UseItems items)
+ {}
+};
+
+
+class Enum:
+ public Item
+{
+};
+class Struct:
+ public Item
+{
+};
+class Trait:
+ public Item
+{
+};
+
+class ExternBlock:
+ public Item
+{
+ ::std::string m_abi;
+ ItemList m_items;
+public:
+ ExternBlock(::std::string abi, ItemList items):
+ m_abi( abi ),
+ m_items( ::std::move(items) )
+ {}
+};
+
+class Impl:
+ public Item
+{
+};
+
+class Fn:
+ public Item
+{
+};
diff --git a/bnf/lex.hpp b/bnf/lex.hpp
new file mode 100644
index 00000000..30d8a2a9
--- /dev/null
+++ b/bnf/lex.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "ast_types.hpp"
+
+struct ParserContext
+{
+ ::std::string filename;
+ ::std::string base_path;
+
+ ::std::unique_ptr<Module> output_module;
+
+ // semi-evil hack used to break '>>' apart into '>' '>'
+ int next_token;
+
+
+ ParserContext(::std::string filename):
+ filename(filename),
+ output_module(),
+ next_token(0)
+ {}
+
+ void pushback(int tok) {
+ assert(next_token == 0);
+ next_token = tok;
+ }
+};
+#include ".gen/rust.tab.hpp"
+
+extern int yylineno;
+extern int yylex(YYSTYPE* lvalp, ParserContext& context);
+extern void yyerror(ParserContext& context, const char *s);
+extern int yydebug;
+
diff --git a/bnf/main.cpp b/bnf/main.cpp
new file mode 100644
index 00000000..e2c4b3b4
--- /dev/null
+++ b/bnf/main.cpp
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <string.h>
+#include "lex.hpp"
+
+extern FILE* yyin;
+
+::std::string get_dir_path(const ::std::string& input) {
+ auto pos = input.rfind("/");
+ if( pos == ::std::string::npos) {
+ 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");
+ if( !yyin ) {
+ fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", argv[1], strerror(errno));
+ return 1;
+ }
+ }
+ yylineno = 1;
+ yydebug = (getenv("BNFDEBUG") != NULL);
+
+ ParserContext context(base_filename);
+ if( context.filename != "-" ) {
+ context.base_path = get_dir_path(context.filename);
+ }
+
+ int rv = yyparse(context);
+ fclose(yyin);
+ if( rv != 0 ) {
+ return rv;
+ }
+
+ assert( context.output_module.get() );
+ auto& mod = *context.output_module;
+ printf("output module = %p\n", &mod);
+
+ for(auto& item : mod.items()) {
+ Module* opt_submod = dynamic_cast<Module*>(item.get());
+ if( !opt_submod ) continue;
+ Module& submod = *opt_submod;
+ printf("- Module %s\n", submod.name().c_str());
+
+ 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;
+ }
+ 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 {
+ fclose(yyin);
+ }
+ }
+ assert(filename.size() > 0);
+ yyin = fopen( filename.c_str(), "r" );
+ if( !yyin ) {
+ printf("> '%s' not found\n", filename.c_str());
+ return 1;
+ }
+
+ ParserContext new_context(filename);
+ int rv = yyparse(new_context);
+ fclose(yyin);
+ if( rv != 0 ) {
+ return rv;
+ }
+ submod = ::std::move( *new_context.output_module );
+ }
+
+ return 0;
+}
+void yyerror(ParserContext& context, const char *s) {
+ fprintf(stderr, "\x1b[31mERROR: %s:%d: yyerror(%s)\x1b[0m\n", context.filename.c_str(), yylineno, s);
+ exit(1);
+}
diff --git a/bnf/rust.lex b/bnf/rust.lex
index a0dce8fa..6155b4c4 100644
--- a/bnf/rust.lex
+++ b/bnf/rust.lex
@@ -1,9 +1,7 @@
%{
#include "ast_types.hpp"
-#include "rust.tab.hpp"
+#include "lex.hpp"
#include <stdio.h>
-void yyerror(const char *s);
-extern int yydebug;
%}
%option yylineno
@@ -12,24 +10,23 @@ extern int yydebug;
%{
int rustbnf_forcetoken = 0;
//#define YY_DECL yy::parser::symbol_type yylex_inner()
-#define YY_DECL int yylex_inner()
+#define YY_DECL int yylex_inner(YYSTYPE* lvalp, ParserContext& context)
YY_DECL;
// Wrap the real yylex with one that can yeild a pushbacked token
-int yylex() {
- if(rustbnf_forcetoken>0) {
- int rv = rustbnf_forcetoken;
- rustbnf_forcetoken = 0;
+int yylex(YYSTYPE* lvalp, ParserContext& context) {
+ if(context.next_token > 0) {
+ int rv = context.next_token;
+ context.next_token = 0;
return rv;
}
else {
- return yylex_inner();
+ return yylex_inner(lvalp, context);
}
}
void handle_block_comment();
-
-const char *gsCurrentFilename = "-";
+::std::string parse_escaped_string(const char* s);
%}
@@ -128,43 +125,57 @@ ident_c [a-zA-Z_]
if(*yytext == '_' && yytext[1] == 0)
return '_';
else {
- yylval.IDENT = new ::std::string( yytext );
+ lvalp->IDENT = new ::std::string( yytext );
return IDENT;
}
}
-{ident_c}({ident_c}|[0-9])*"!" { yylval.MACRO = new ::std::string(yytext); return MACRO; }
-'{ident_c}{ident_c}* { yylval.LIFETIME = new ::std::string(yytext); return LIFETIME; }
-[0-9]{dec_digit}*"."{dec_digit}+ { yylval.FLOAT = strtod(yytext, NULL); return FLOAT; }
-[0-9]{dec_digit}* { yylval.INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
-0x[0-9a-fA-F_]+ { yylval.INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
-0b[01_]+ { yylval.INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
+[0-9]{dec_digit}*"."{dec_digit}+(e[+\-]?{dec_digit}+)?(f32|f64)? { lvalp->FLOAT = strtod(yytext, NULL); return FLOAT; }
+[0-9]{dec_digit}* { lvalp->INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
+0x[0-9a-fA-F_]+ { lvalp->INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
+0b[01_]+ { lvalp->INTEGER = strtoull(yytext, NULL, 0); return INTEGER; }
+{ident_c}({ident_c}|[0-9])*"!" { lvalp->MACRO = new ::std::string(yytext, 0, strlen(yytext)-1); return MACRO; }
+'{ident_c}{ident_c}* { lvalp->LIFETIME = new ::std::string(yytext, 1); return LIFETIME; }
-b?'(.|\\['rn])' { yylval.CHARLIT = yytext[0]; return CHARLIT; }
-\"([^"])*\" { yylval.STRING = new ::std::string(yytext); }
+b?'(.|\\['rn])' { lvalp->CHARLIT = yytext[0]; return CHARLIT; }
+\"([^"])*\" { lvalp->STRING = new ::std::string( parse_escaped_string(yytext) ); return STRING; }
-. { fprintf(stderr, "\x1b[31m" "ERROR: %s:%d: Invalid character '%c'\x1b[0m\n", gsCurrentFilename, yylineno, *yytext); exit(1); }
+. { fprintf(stderr, "\x1b[31m" "ERROR: %s:%d: Invalid character '%c'\x1b[0m\n", context.filename.c_str(), yylineno, *yytext); exit(1); }
%%
-int main(int argc, char *argv[]) {
- if(argc < 2 || strcmp(argv[1], "-") == 0) {
- yyin = stdin;
- }
- else {
- gsCurrentFilename = argv[1];
- yyin = fopen(argv[1], "r");
- if( !yyin ) {
- fprintf(stderr, "ERROR: Unable to open '%s': '%s'\n", argv[1], strerror(errno));
- return 1;
+
+::std::string parse_escaped_string(const char* s) {
+ assert(*s++ == '"');
+
+ ::std::string rv;
+
+ for( ; *s != '\0'; s ++ )
+ {
+ if( *s == '\\' )
+ {
+ s ++;
+ switch(*s)
+ {
+ case 'n': rv += '\n'; break;
+ case 'r': rv += '\r'; break;
+ case '\n': break;
+ default:
+ fprintf(stderr, "Unknown escape code '\\%c' in string\n", *s);
+ exit(1);
+ }
+ }
+ else if( *s == '"') {
+ break ;
+ }
+ else {
+ rv += *s;
}
}
- yylineno = 1;
- yydebug = (getenv("BNFDEBUG") != NULL);
- yyparse();
- return 0;
-}
-void yyerror(const char *s) {
- fprintf(stderr, "\x1b[31mERROR: %s:%d: yyerror(%s)\x1b[0m\n", gsCurrentFilename, yylineno, s);
- exit(1);
+ if( *s == '\0' ) {
+ // wut?
+ }
+ assert(*s++ == '"');
+ assert(*s == '\0');
+ return rv;
}
// Thanks stackoverflow: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
diff --git a/bnf/rust.y b/bnf/rust.y
index 698dd37e..2607947a 100644
--- a/bnf/rust.y
+++ b/bnf/rust.y
@@ -1,4 +1,3 @@
-%define api.value.type union
%{
#include <stdio.h>
#include <stdarg.h>
@@ -6,17 +5,19 @@
#include <string>
#include <vector>
#include <memory>
+#include "lex.hpp"
#include "ast_types.hpp"
-extern int yylineno;
-extern int yylex();
-extern void yyerror(const char *s);
-
-// semi-evil hack used to break '>>' apart into '>' '>'
-extern int rustbnf_forcetoken;
+#define YYPARSE_PARAM parser_context
+#define YYLEX_PARAM parser_context
%}
+%define api.value.type union
+%define api.pure full
+%parse-param {ParserContext& context}
+%lex-param {*context}
+
%token <::std::string*> IDENT LIFETIME STRING MACRO
%token <int> INTEGER CHARLIT
%token <double> FLOAT
@@ -34,7 +35,6 @@ extern int rustbnf_forcetoken;
%token RWD_match RWD_if RWD_while RWD_loop RWD_for RWD_else
%token RWD_return RWD_break RWD_continue
%token RWD_extern
-%start module_root
%type <Module*> module_root
%type <int> tt_tok
@@ -43,18 +43,34 @@ extern int rustbnf_forcetoken;
%type <bool> opt_pub opt_mut
%type <::std::string*> opt_lifetime
%type <AttrList*> super_attrs attrs
-%type <Attr*> super_attr attr
-%type < ::std::vector< ::std::unique_ptr<Item> >* > module_body
-%type <Item*> item vis_item unsafe_item unsafe_vis_item impl_def extern_block use_def
-%type <Module*> module_def
-%type <Global*> static_def const_def
+%type <MetaItem*> super_attr attr
+%type <ItemList*> module_body extern_items
%type <MetaItem*> meta_item
%type <MetaItems*> meta_items
+%type <Item*> item vis_item unsafe_item unsafe_vis_item
+%type <UseSet*> use_def
+%type <Module*> module_def
+%type <Global*> static_def const_def
+%type <Struct*> struct_def
+%type <Enum*> enum_def
+%type <Trait*> trait_def
+%type <Fn*> fn_def fn_def_hdr fn_def_hdr_PROTO
+%type <ExternBlock*> extern_block
+%type <Impl*> impl_def
+
+%type <UseItems*> use_def_tail
+%type < ::std::vector<UseItem>* > use_picks
+%type <UseItem*> path_item
+
+%type <::std::string*> extern_abi
+%type <Item*> extern_item
+
%debug
%error-verbose
%{
+// TODO: Replace this with a C++-safe printf
/*static inline*/ void bnf_trace(const char* fmt, ...) {
fprintf(stderr, "\x1b[32m""TRACE: ");
va_list args;
@@ -63,25 +79,16 @@ extern int rustbnf_forcetoken;
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 char* fmt, const ::std::string& s) {
- bnf_trace(fmt, s.c_str());
+ bnf_trace(fmt, s.c_str(), '0');
}
-//#define YYPRINT(f,t,v) yyprint(f,t,v)
-//static void yyprint(FILE *outstream, int type, const YYSTYPE value)
-//{
-// switch(type)
-// {
-// case IDENT: fprintf(outstream, "%s", value.text); break;
-// case MACRO: fprintf(outstream, "%s!", value.text); break;
-// case STRING: fprintf(outstream, "\"%s\"", value.text); break;
-// case LIFETIME: fprintf(outstream, "'%s", value.text); break;
-// default:
-// break;
-// }
-//}
%}
+%start parse_root
%%
/*
@@ -89,6 +96,8 @@ extern int rustbnf_forcetoken;
Root
==========================
*/
+parse_root: module_root { context.output_module = box_raw($1); }
+
module_root: super_attrs module_body { $$ = new Module(consume($1), consume($2)); };
tt_list
@@ -129,15 +138,15 @@ attrs
;
super_attr
- : HASHBANG /*'#' '!'*/ '[' meta_items ']' { $$ = new Attr(consume($3)); }
- | SUPER_DOC_COMMENT { $$ = new Attr(MetaItems( { MetaItem("doc", consume($1)) } )); }
+ : HASHBANG /*'#' '!'*/ '[' meta_item ']' { $$ = $3; }
+ | SUPER_DOC_COMMENT { $$ = new MetaItem("doc", consume($1)); }
;
attr
- : '#' '[' meta_items ']' { $$ = new Attr( consume($3) ); }
- | DOC_COMMENT { $$ = new Attr(MetaItems( { MetaItem("doc", consume($1)) } )); }
+ : '#' '[' meta_item ']' { $$ = $3; }
+ | DOC_COMMENT { $$ = new MetaItem("doc", consume($1)); }
;
meta_items
- : meta_item { $$ = new MetaItems({ consume($1) }); }
+ : meta_item { $$ = new MetaItems(); $$->push_back( consume($1) ); }
| meta_items ',' meta_item { $$ = $1; $$->push_back( consume($3) ); }
;
meta_item
@@ -170,24 +179,29 @@ vis_item
| RWD_use use_def { $$ = $2; }
| RWD_static static_def { $$ = $2; }
| RWD_const const_def { $$ = $2; }
- | RWD_struct struct_def { $$ = nullptr; }
- | RWD_enum enum_def { $$ = nullptr; }
+ | RWD_struct struct_def { $$ = $2; }
+ | RWD_enum enum_def { $$ = $2; }
| unsafe_vis_item
;
/* Possibily unsafe visibility item */
unsafe_vis_item
- : fn_qualifiers RWD_fn fn_def { $$ = nullptr; }
- | RWD_trait trait_def { $$ = nullptr; }
+ : fn_qualifiers RWD_fn fn_def { $$ = $3; }
+ | RWD_trait trait_def { $$ = $2; }
;
unsafe_item
: unsafe_vis_item
| RWD_impl impl_def { $$ = $2; }
;
-extern_block: extern_abi '{' extern_items '}' { $$ = nullptr; /*new ExternBlock($1, $3);*/ };
-extern_abi: | STRING;
-extern_items: | extern_items extern_item;
-extern_item: opt_pub RWD_fn fn_def_hdr ';';
+extern_block: extern_abi '{' extern_items '}' { $$ = new ExternBlock( consume($1), consume($3) ); };
+extern_abi: { $$ = new ::std::string("C"); } | STRING;
+extern_items
+ : { $$ = new ItemList(); }
+ | extern_items extern_item { $$ = $1; $$->push_back( box_raw($2) ); }
+ ;
+extern_item
+ : opt_pub RWD_fn fn_def_hdr ';' { $$ = $3; if($1) $$->set_pub(); }
+ ;
module_def
: IDENT '{' module_root '}' { $3->set_name( consume($1) ); $$ = new Module(consume($3)); }
@@ -196,9 +210,9 @@ module_def
/* --- 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 { bnf_trace("function '%s'", $1); };
+fn_def_hdr: IDENT generic_def '(' fn_def_args ')' 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 { 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("function '%s'", *$1); };
fn_def_ret
: /* -> () */
@@ -238,42 +252,45 @@ fn_qualifiers
/* --- Use --- */
use_def
- : RWD_self use_def_tail { $$ = nullptr; }
- | RWD_self DOUBLECOLON use_path use_def_tail { $$ = nullptr; }
- | RWD_super use_def_tail { $$ = nullptr; }
- | RWD_super DOUBLECOLON use_path use_def_tail { $$ = nullptr; }
- | DOUBLECOLON use_path use_def_tail { $$ = nullptr; }
- | use_path use_def_tail { $$ = nullptr; }
- | '{' use_picks '}' ';' { $$ = nullptr; }
+ : RWD_self use_def_tail { $$ = new UseSet( Path(Path::TagSelf()), consume($2) ); }
+ | RWD_self DOUBLECOLON use_path use_def_tail { $$ = new UseSet(/* TODO */); }
+ | RWD_super use_def_tail { $$ = new UseSet( Path(Path::TagSuper()), consume($2) ); }
+ | RWD_super DOUBLECOLON use_path use_def_tail { $$ = new UseSet(/* TODO */); }
+ | 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) ); }
;
use_def_tail
- : RWD_as IDENT ';'
- | DOUBLECOLON '*' ';'
- | DOUBLECOLON '{' use_picks '}' ';'
- | ';'
+ : RWD_as IDENT ';' { $$ = new UseItems(UseItems::TagRename(), consume($2) ); }
+ | DOUBLECOLON '*' ';' { $$ = new UseItems(UseItems::TagWildcard()); }
+ | DOUBLECOLON '{' use_picks '}' ';' { $$ = new UseItems( consume($3) ); }
+ | ';' { $$ = new UseItems(); }
/* | RWD_use error ';' */
;
use_picks
- : use_picks ',' path_item
- | path_item
+ : use_picks ',' path_item { $$ = $1; $$->push_back( consume($3) ); }
+ | path_item { $$ = new ::std::vector<UseItem>(); $$->push_back( consume($1) ); }
+ ;
+path_item
+ : IDENT { $$ = new UseItem( consume($1) ); }
+ | RWD_self { $$ = new UseItem(UseItem::TagSelf()); }
;
-path_item: IDENT | RWD_self;
/* --- Static/Const --- */
opt_mut: { $$ = false; } | RWD_mut { $$ = true; };
-static_def: opt_mut IDENT ':' type '=' const_value { $$ = nullptr; };
-const_def: IDENT ':' type '=' const_value { $$ = nullptr; };
+static_def: opt_mut IDENT ':' type '=' const_value { $$ = new Global(); };
+const_def: IDENT ':' type '=' const_value { $$ = new Global(); };
const_value
: expr ';'
- | error ';' { yyerror("Syntax error in constant expression"); }
+ | error ';' { yyerror(context, "Syntax error in constant expression"); }
;
/* --- Struct --- */
struct_def
- : IDENT generic_def where_clause ';' { bnf_trace("unit-like struct"); }
- | IDENT generic_def '(' tuple_struct_def_items opt_comma ')' where_clause ';' { bnf_trace("tuple struct"); }
- | IDENT generic_def where_clause '{' struct_def_items opt_comma '}' { bnf_trace("normal struct"); }
+ : 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"); }
;
tuple_struct_def_items
@@ -289,7 +306,7 @@ struct_def_items
struct_def_item: attrs opt_pub IDENT ':' type;
/* --- Enum --- */
-enum_def: IDENT generic_def where_clause '{' enum_variants '}';
+enum_def: IDENT generic_def where_clause '{' enum_variants '}' { $$ = new Enum(); };
enum_variants: | enum_variant_list | enum_variant_list ',';
enum_variant_list: enum_variant | enum_variant_list ',' enum_variant;
enum_variant: attrs enum_variant_;
@@ -300,7 +317,7 @@ enum_variant_
;
/* --- Trait --- */
-trait_def: IDENT generic_def trait_bounds '{' trait_items '}';
+trait_def: IDENT generic_def trait_bounds '{' trait_items '}' { $$ = new Trait(); };
trait_bounds: ':' trait_bound_list | ;
trait_bound_list: trait_bound_list '+' bound | bound;
@@ -313,7 +330,7 @@ trait_item
;
/* --- Impl --- */
-impl_def: impl_def_line '{' impl_items '}' { $$ = nullptr; };
+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 DOUBLEDOT where_clause { bnf_trace("wildcard impl"); }
@@ -394,7 +411,7 @@ type_path_segs
type_path_seg
: IDENT
| IDENT '<' type_exprs '>'
- | IDENT '<' type_exprs DOUBLEGT { bnf_trace("Double-gt terminated type expr"); rustbnf_forcetoken = '>'; }
+ | IDENT '<' type_exprs DOUBLEGT { bnf_trace("Double-gt terminated type expr"); context.pushback('>'); }
;
type_exprs: type_exprs ',' type_arg | type_arg;
type_arg: type | LIFETIME | IDENT '=' type;
diff --git a/bnf/rust_tts.y.h b/bnf/rust_tts.y.h
index c752694f..4a590f2b 100644
--- a/bnf/rust_tts.y.h
+++ b/bnf/rust_tts.y.h
@@ -1,13 +1,18 @@
#define _C(v) v { $$ = v; }
#define _T(v) v { $$ = v; }
tt_tok
- : _T(IDENT) | _T(STRING) | _T(CHARLIT) | _T(LIFETIME) | _T(INTEGER) | _T(MACRO)
- | _C('+') | _C('*') | _C('/') | _C(',') | _C(';')
- | _T(RWD_self) | _T(RWD_super) | _T(RWD_mut) | _T(RWD_ref) | _T(RWD_let) | _T(RWD_where)
- | _T(RWD_for ) | _T(RWD_while) | _T(RWD_loop) | _T(RWD_if) | _T(RWD_else) | _T(RWD_match) | _T(RWD_return)
- | _T(RWD_impl) | _T(RWD_pub ) | _T(RWD_struct) | _T(RWD_enum) | _T(RWD_fn) | _T(RWD_type) | _T(RWD_static) | _T(RWD_const)
- | _C('!') | _T(EXCLAMEQUAL)
+ : _T(IDENT) | _T(STRING) | _T(CHARLIT) | _T(LIFETIME) | _T(INTEGER) | _T(MACRO) | _T(FLOAT)
+ | _C(',') | _C(';') | _C('_')
+ | _T(RWD_self) | _T(RWD_super) | _T(RWD_mut) | _T(RWD_ref) | _T(RWD_let) | _T(RWD_where) | _T(RWD_pub) | _T(RWD_in) | _T(RWD_as)
+ | _T(RWD_for ) | _T(RWD_while) | _T(RWD_loop) | _T(RWD_if) | _T(RWD_else) | _T(RWD_match)
+ | _T(RWD_return) | _T(RWD_continue) | _T(RWD_break)
+ | _T(RWD_impl) | _T(RWD_struct) | _T(RWD_enum) | _T(RWD_fn) | _T(RWD_type) | _T(RWD_static) | _T(RWD_const) | _T(RWD_trait) | _T(RWD_use)
+ | _T(RWD_extern) | _T(RWD_unsafe)
+ | _C('/') | _T(SLASHEQUAL)
+ | _C('*') | _T(STAREQUAL)
+ | _C('+') | _T(PLUSEQUAL)
| _C('-') | _T(THINARROW)
+ | _C('!') | _T(EXCLAMEQUAL)
| _C('&') | _T(DOUBLEAMP)
| _C(':') | _T(DOUBLECOLON)
| _C('|') | _T(DOUBLEPIPE)