summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-09-23 16:32:06 +0800
committerJohn Hodge <tpg@mutabah.net>2015-09-23 16:32:06 +0800
commit7b653aa7c645c3272d9e51da97dab0d0527bd5f5 (patch)
tree1bf0f704b55b733b55fc7cbf64b120e31df6a57b
parent6559c120c129cfd6418eaeb08ba3ecf0e1ebea91 (diff)
downloadmrust-7b653aa7c645c3272d9e51da97dab0d0527bd5f5.tar.gz
Successfully parses libcore/str/pattern.rs
-rw-r--r--bnf/Makefile6
-rw-r--r--bnf/rust.lex36
-rw-r--r--bnf/rust.y76
3 files changed, 91 insertions, 27 deletions
diff --git a/bnf/Makefile b/bnf/Makefile
index 57199bef..02cafc3a 100644
--- a/bnf/Makefile
+++ b/bnf/Makefile
@@ -4,12 +4,10 @@
all: test.bin
TSTFILE := ../samples/1.rs
-TSTFILE := ../../rust_os/libcore/lib.rs
-TSTFILE := ../../rust_os/libcore/str/mod.rs
-TSTFILE := ../../rust_os/libcore/str/pattern.rs
+TSTFILE := ../../rust_os/libcore/lib.rs ../../rust_os/libcore/str/mod.rs ../../rust_os/libcore/str/pattern.rs
test: test.bin $(TSTFILE)
- ./test.bin < $(TSTFILE)
+ for f in $(TSTFILE); do ./test.bin "$$f"; done
test.bin: rust.tab.c rust.lex.c
gcc rust.tab.c rust.lex.c -o $@
diff --git a/bnf/rust.lex b/bnf/rust.lex
index cb45b9bb..300742e9 100644
--- a/bnf/rust.lex
+++ b/bnf/rust.lex
@@ -31,8 +31,7 @@ ident_c [a-zA-Z_]
"//"[^/].*\n { }
"///".*\n { /* TODO: Handle /// by desugaring */ }
-"/*"[^*]([^(\*/)])*"*/" { }
-"/**"([^(\*/)])*"*/" { /* TODO: handle / ** by desugaring */ }
+"/*" { comment(); /* TODO: Handle doc comments */ }
\n /* */
\r /* */
[ \t] /* */
@@ -126,16 +125,45 @@ b?'(.|\\['rn])' { yylval.text = strdup(yytext); return CHARLIT; }
. { fprintf(stderr, "\x1b[31m" "ERROR: Invalid character '%c' on line %i\x1b[0m\n", *yytext, yylineno); exit(1); }
%%
-int main() {
+const char *gsCurrentFilename = "-";
+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'", argv[1], strerror(errno));
+ return 1;
+ }
+ }
yylineno = 1;
yydebug = (getenv("BNFDEBUG") != NULL);
yyparse();
return 0;
}
void yyerror(const char *s) {
- fprintf(stderr, "\x1b[31mERROR: ?:%d: yyerror(%s)\x1b[0m\n", yylineno, s);
+ fprintf(stderr, "\x1b[31mERROR: %s:%d: yyerror(%s)\x1b[0m\n", gsCurrentFilename, yylineno, s);
}
int yywrap(void) {
printf("done\n");
return 1;
}
+
+// Thanks stackoverflow: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+void comment() {
+ char c, c1;
+
+loop:
+ while ((c = input()) != '*' && c != 0)
+ putchar(c);
+
+ if ((c1 = input()) != '/' && c != 0) {
+ unput(c1);
+ goto loop;
+ }
+
+ if (c != 0)
+ putchar(c1);
+}
diff --git a/bnf/rust.y b/bnf/rust.y
index 2310552b..1d31e963 100644
--- a/bnf/rust.y
+++ b/bnf/rust.y
@@ -88,6 +88,8 @@ tt_paren: '(' tt_list ')';
tt_brace: '{' tt_list '}';
tt_square: '[' tt_list ']';
+tt_group_item: tt_paren ';' | tt_brace | tt_square ';';
+
super_attrs : | super_attrs super_attr;
opt_pub
@@ -95,6 +97,9 @@ opt_pub
| /* mt */ { bnf_trace("private"); }
;
opt_comma: | ',';
+opt_semicolon: | ';';
+opt_unsafe: | RWD_unsafe;
+opt_lifetime: | LIFETIME;
module_body
: module_body attrs item
@@ -131,9 +136,9 @@ item
| opt_pub RWD_const const_def
| opt_pub RWD_struct struct_def
| opt_pub RWD_enum enum_def
- | opt_pub RWD_trait trait_def
+ | opt_pub opt_unsafe RWD_trait trait_def
| RWD_extern extern_block
- | RWD_impl impl_def
+ | opt_unsafe RWD_impl impl_def
| MACRO IDENT tt_brace
| MACRO tt_brace
| MACRO tt_paren ';'
@@ -153,19 +158,35 @@ module_def
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_ret: /* -> () */ | THINARROW type | THINARROW '!';
+fn_def_hdr_PROTO: IDENT generic_def '(' fn_def_args_PROTO ')' fn_def_ret where_clause { bnf_trace("function '%s'", $1); };
+
+fn_def_ret
+ : /* -> () */
+ | THINARROW type
+ | THINARROW '!'
+ ;
fn_def_args: /* empty */ | fn_def_self | fn_def_self ',' fn_def_arg_list | fn_def_arg_list;
+fn_def_args_PROTO: /* empty */ | fn_def_self | fn_def_self ',' fn_def_arg_list_PROTO | fn_def_arg_list_PROTO;
+
fn_def_self
: RWD_self
+ | RWD_self ':' type
| RWD_mut RWD_self
+ | RWD_mut RWD_self ':' type
| '&' RWD_self
| '&' LIFETIME RWD_self
| '&' RWD_mut RWD_self
| '&' LIFETIME RWD_mut RWD_self
;
fn_def_arg_list: fn_def_arg | fn_def_arg_list ',' fn_def_arg;
-fn_def_arg : pattern ':' type;
+fn_def_arg: pattern ':' type;
+
+fn_def_arg_list_PROTO: fn_def_arg_PROTO | fn_def_arg_list_PROTO ',' fn_def_arg_PROTO;
+fn_def_arg_PROTO
+ : IDENT ':' type
+ | type
+ ;
fn_qualifiers
:
@@ -214,9 +235,9 @@ const_value
/* --- Struct --- */
struct_def
- : IDENT generic_def ';' { bnf_trace("unit-like struct"); }
- | IDENT generic_def '(' tuple_struct_def_items opt_comma ')' ';' { bnf_trace("tuple struct"); }
- | IDENT generic_def '{' struct_def_items opt_comma '}' { bnf_trace("normal struct"); }
+ : 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"); }
;
tuple_struct_def_items
@@ -232,8 +253,15 @@ struct_def_items
struct_def_item: attrs opt_pub IDENT ':' type;
/* --- Enum --- */
-enum_def:
+enum_def: IDENT generic_def where_clause '{' enum_variants '}';
+enum_variants: | enum_variant_list | enum_variant_list ',';
+enum_variant_list: enum_variant | enum_variant_list ',' enum_variant;
+enum_variant
+ : IDENT
+ | IDENT '(' type_list ')'
+ | IDENT '{' struct_def_items '}'
;
+
/* --- Trait --- */
trait_def: IDENT generic_def trait_bounds '{' trait_items '}';
trait_bounds: ':' type_path | ;
@@ -243,7 +271,8 @@ trait_items: | trait_items attrs trait_item;
trait_item
: RWD_type IDENT ';'
| RWD_type IDENT ':' trait_bound_list ';'
- | fn_qualifiers RWD_fn fn_def_hdr ';'
+ | fn_qualifiers RWD_fn fn_def_hdr_PROTO ';'
+ | fn_qualifiers RWD_fn fn_def_hdr_PROTO code
;
/* --- Impl --- */
@@ -257,6 +286,7 @@ impl_items: | impl_items attrs impl_item;
impl_item
: opt_pub fn_qualifiers RWD_fn fn_def
| opt_pub RWD_type generic_def IDENT '=' type ';'
+ | MACRO tt_group_item
;
@@ -311,7 +341,10 @@ expr_path_seg
type_path
: ufcs_path DOUBLECOLON IDENT
| DOUBLECOLON type_path_segs
+ | RWD_super DOUBLECOLON type_path_segs
+ | RWD_self DOUBLECOLON type_path_segs
| type_path_segs
+ | type_path_segs '(' type_list ')' fn_def_ret
;
ufcs_path: '<' type RWD_as type_path '>';
type_path_segs
@@ -402,11 +435,12 @@ pattern_list
Expressions!
=========================================
*/
-code: '{' block_contents '}' { bnf_trace("code parsed"); };
+code: block { bnf_trace("code parsed"); };
+
+block: '{' block_contents '}';
block_contents
- :
- | block_lines
+ : block_lines
| block_lines tail_expr
;
tail_expr
@@ -426,6 +460,7 @@ block_line
| attrs item
| expr_blocks
| stmt
+ | LIFETIME ':' loop_block
;
opt_type_annotation: | ':' type;
@@ -449,14 +484,16 @@ expr_blocks
: RWD_match expr_NOSTRLIT '{' match_arms opt_comma '}' { }
| RWD_if if_block
| RWD_unsafe '{' block_contents '}' { }
- | RWD_loop '{' block_contents '}' { }
+/* | flow_control */
+ | loop_block
+ | block
+ ;
+loop_block
+ : RWD_loop '{' block_contents '}' { }
| RWD_while expr_NOSTRLIT '{' block_contents '}' { }
+ | RWD_while RWD_let pattern '=' expr_NOSTRLIT '{' block_contents '}' { }
| RWD_for pattern RWD_in expr_NOSTRLIT '{' block_contents '}' { }
- | flow_control
- | '{' block_contents '}'
;
-opt_lifetime: | LIFETIME;
-opt_semicolon: | ';';
if_block
: if_block_head {}
@@ -482,10 +519,11 @@ match_patterns
| match_pattern
;
match_arm
- : match_patterns FATARROW expr { bnf_trace("match_arm"); }
+ : match_arm_expr
| match_arm_brace
;
-match_arm_brace : match_patterns FATARROW '{' block_contents '}';
+match_arm_brace : match_patterns FATARROW '{' block_contents '}' { };
+match_arm_expr: match_patterns FATARROW tail_expr { bnf_trace("match_arm"); };
/* rust_expr.y.h inserted */