From ad6bb17acf1645828f816c4f0165ccaa2b6c73f6 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Mon, 9 Feb 2015 19:41:27 -0800 Subject: [PATCH 1/4] Bison grammar: refactor index expressions to use ordinary expressions as indexes, remove index_expr and expr_norange --- src/grammar/parser-lalr.y | 86 ++++++--------------------------------- 1 file changed, 12 insertions(+), 74 deletions(-) diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index d3d3a2b997c..2e83e8bccd5 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -1193,12 +1193,10 @@ maybe_stmts // // In non-stmts contexts, expr can relax this trichotomy. // -// There are also two other expr subtypes: first, nonparen_expr -// disallows exprs surrounded by parens (including tuple expressions), -// this is necessary for BOX (place) expressions, so a parens expr -// following the BOX is always parsed as the place. There is also -// expr_norange used in index_expr, which disallows '..' in -// expressions as that has special meaning inside of brackets. +// There is also one other expr subtype: nonparen_expr disallows exprs +// surrounded by parens (including tuple expressions), this is +// necessary for BOX (place) expressions, so a parens expr following +// the BOX is always parsed as the place. stmts : stmt { $$ = mk_node("stmts", 1, $1); } @@ -1265,7 +1263,7 @@ nonblock_expr | path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); } | nonblock_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); } | nonblock_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); } -| nonblock_expr '[' index_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } +| nonblock_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } | nonblock_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); } | '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); } | '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); } @@ -1307,6 +1305,7 @@ nonblock_expr | nonblock_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); } | nonblock_expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); } | DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); } +| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); } | nonblock_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' nonblock_expr { $$ = mk_node("ExprBox", 2, $3, $5); } @@ -1322,7 +1321,7 @@ expr | path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); } | expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); } | expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); } -| expr '[' index_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } +| expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } | expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); } | '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); } | '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); } @@ -1364,6 +1363,7 @@ expr | expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); } | expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); } | DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); } +| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); } | expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 2, $3, $5); } @@ -1381,7 +1381,7 @@ nonparen_expr | path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); } | nonparen_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); } | nonparen_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); } -| nonparen_expr '[' index_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } +| nonparen_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } | nonparen_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); } | '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); } | CONTINUE { $$ = mk_node("ExprAgain", 0); } @@ -1422,6 +1422,7 @@ nonparen_expr | nonparen_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); } | nonparen_expr DOTDOT nonparen_expr { $$ = mk_node("ExprRange", 2, $1, $3); } | DOTDOT nonparen_expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); } +| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); } | nonparen_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 1, $3, $5); } @@ -1430,62 +1431,6 @@ nonparen_expr | nonblock_prefix_expr ; -expr_norange -: lit { $$ = mk_node("ExprLit", 1, $1); } -| %prec IDENT - path_expr { $$ = mk_node("ExprPath", 1, $1); } -| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); } -| macro_expr { $$ = mk_node("ExprMac", 1, $1); } -| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); } -| expr_norange '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); } -| expr_norange '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); } -| expr_norange '[' index_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } -| expr_norange '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); } -| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); } -| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); } -| CONTINUE { $$ = mk_node("ExprAgain", 0); } -| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); } -| RETURN { $$ = mk_node("ExprRet", 0); } -| RETURN expr { $$ = mk_node("ExprRet", 1, $2); } -| BREAK { $$ = mk_node("ExprBreak", 0); } -| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); } -| expr_norange '=' expr_norange { $$ = mk_node("ExprAssign", 2, $1, $3); } -| expr_norange SHLEQ expr_norange { $$ = mk_node("ExprAssignShl", 2, $1, $3); } -| expr_norange SHREQ expr_norange { $$ = mk_node("ExprAssignShr", 2, $1, $3); } -| expr_norange MINUSEQ expr_norange { $$ = mk_node("ExprAssignSub", 2, $1, $3); } -| expr_norange ANDEQ expr_norange { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); } -| expr_norange OREQ expr_norange { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); } -| expr_norange PLUSEQ expr_norange { $$ = mk_node("ExprAssignAdd", 2, $1, $3); } -| expr_norange STAREQ expr_norange { $$ = mk_node("ExprAssignMul", 2, $1, $3); } -| expr_norange SLASHEQ expr_norange { $$ = mk_node("ExprAssignDiv", 2, $1, $3); } -| expr_norange CARETEQ expr_norange { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); } -| expr_norange PERCENTEQ expr_norange { $$ = mk_node("ExprAssignRem", 2, $1, $3); } -| expr_norange OROR expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); } -| expr_norange ANDAND expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); } -| expr_norange EQEQ expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); } -| expr_norange NE expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); } -| expr_norange '<' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); } -| expr_norange '>' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); } -| expr_norange LE expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); } -| expr_norange GE expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); } -| expr_norange '|' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); } -| expr_norange '^' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); } -| expr_norange '&' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); } -| expr_norange SHL expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); } -| expr_norange SHR expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); } -| expr_norange '+' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); } -| expr_norange '-' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); } -| expr_norange '*' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); } -| expr_norange '/' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); } -| expr_norange '%' expr_norange { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); } -| expr_norange AS ty { $$ = mk_node("Expr_NorangeCast", 2, $1, $3); } -| BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } -| %prec BOXPLACE BOX '(' maybe_expr ')' expr_norange { $$ = mk_node("ExprBox", 2, $3, $5); } -| block_expr -| block -| nonblock_prefix_expr -; - expr_nostruct : lit { $$ = mk_node("ExprLit", 1, $1); } | %prec IDENT @@ -1494,7 +1439,7 @@ expr_nostruct | macro_expr { $$ = mk_node("ExprMac", 1, $1); } | expr_nostruct '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); } | expr_nostruct '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); } -| expr_nostruct '[' index_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } +| expr_nostruct '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); } | expr_nostruct '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); } | '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); } | '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); } @@ -1536,6 +1481,7 @@ expr_nostruct | expr_nostruct DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); } | expr_nostruct DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, $1, $3); } | DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, mk_none(), $2); } +| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); } | expr_nostruct AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr_nostruct { $$ = mk_node("ExprBox", 1, $3, $5); } @@ -1612,14 +1558,6 @@ vec_expr | exprs ';' expr { $$ = mk_node("VecRepeat", 2, $1, $3); } ; -index_expr -: expr_norange { $$ = mk_node("Index", 1, $1); } -| expr_norange DOTDOT { $$ = mk_node("SliceToEnd", 1, $1); } -| DOTDOT expr_norange { $$ = mk_node("SliceFromBeginning", 1, $2); } -| expr_norange DOTDOT expr_norange { $$ = mk_node("Slice", 2, $1, $3); } -| %empty { $$ = mk_none(); } -; - struct_expr_fields : field_inits | field_inits ',' From 41d6513b8f0429c6775097a7b69570a4c912e8b9 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 10 Feb 2015 16:10:05 -0800 Subject: [PATCH 2/4] Bison grammar: add qualified path expressions --- src/grammar/parser-lalr.y | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index 2e83e8bccd5..26168f6f5cb 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -1309,6 +1309,7 @@ nonblock_expr | nonblock_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' nonblock_expr { $$ = mk_node("ExprBox", 2, $3, $5); } +| expr_qualified_path | nonblock_prefix_expr ; @@ -1367,6 +1368,7 @@ expr | expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 2, $3, $5); } +| expr_qualified_path | block_expr | block | nonblock_prefix_expr @@ -1426,6 +1428,7 @@ nonparen_expr | nonparen_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 1, $3, $5); } +| expr_qualified_path | block_expr | block | nonblock_prefix_expr @@ -1485,6 +1488,7 @@ expr_nostruct | expr_nostruct AS ty { $$ = mk_node("ExprCast", 2, $1, $3); } | BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); } | %prec BOXPLACE BOX '(' maybe_expr ')' expr_nostruct { $$ = mk_node("ExprBox", 1, $3, $5); } +| expr_qualified_path | block_expr | block | nonblock_prefix_expr_nostruct @@ -1512,6 +1516,33 @@ nonblock_prefix_expr | proc_expr ; +expr_qualified_path +: '<' ty_sum AS trait_ref '>' MOD_SEP ident +{ + $$ = mk_node("ExprQualifiedPath", 3, $2, $4, $7); +} +| '<' ty_sum AS trait_ref '>' MOD_SEP ident generic_args +{ + $$ = mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8); +} +| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident +{ + $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12); +} +| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident +{ + $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13); +} +| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident generic_args +{ + $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12, $13); +} +| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident generic_args +{ + $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13, $14); +} + + lambda_expr : %prec LAMBDA OROR ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); } From 03cc48c38ddd3bbdf7f928dede249e7c8527edd0 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 10 Feb 2015 16:51:02 -0800 Subject: [PATCH 3/4] Bison grammar: refactor items to allow "extern crate" in stmts --- src/grammar/parser-lalr.y | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index 26168f6f5cb..2788476ebfe 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -258,11 +258,7 @@ mod_item // items that can appear outside of a fn block item -: item_static -| item_const -| item_type -| block_item -| view_item +: stmt_item | item_macro ; @@ -272,8 +268,7 @@ stmt_item | item_const | item_type | block_item -| use_item -| extern_fn_item +| view_item ; item_static @@ -295,7 +290,6 @@ view_item : use_item | extern_fn_item | EXTERN CRATE ident ';' { $$ = mk_node("ViewItemExternCrate", 1, $3); } -| EXTERN CRATE ident '=' str ';' { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); } | EXTERN CRATE str AS ident ';' { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); } ; From 3bca5f23aa8ac7a9e27ec582e05c2420313515d7 Mon Sep 17 00:00:00 2001 From: Brian Leibig Date: Tue, 10 Feb 2015 17:54:38 -0800 Subject: [PATCH 4/4] Bison grammar: fix precedence with ranges followed by blocks --- src/grammar/parser-lalr.y | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index 2788476ebfe..6a6f7e0e9f9 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -177,6 +177,8 @@ extern char *yytext; %precedence '{' '[' '(' '.' +%precedence RANGE + %start crate %% @@ -1475,7 +1477,7 @@ expr_nostruct | expr_nostruct '*' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); } | expr_nostruct '/' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); } | expr_nostruct '%' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); } -| expr_nostruct DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); } +| expr_nostruct DOTDOT %prec RANGE { $$ = mk_node("ExprRange", 2, $1, mk_none()); } | expr_nostruct DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, $1, $3); } | DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, mk_none(), $2); } | DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }