From c248bf14d57a97757e9aa9f53fe27d5ffef2ccfd Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 1 Nov 2018 04:13:28 +0200 Subject: [PATCH 01/18] Polyfill LIFETIME builtin. --- build.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build.rs b/build.rs index 3e8f09d..4344e57 100644 --- a/build.rs +++ b/build.rs @@ -21,6 +21,22 @@ fn main() { // Start with the builtin rules for proc-macro grammars. let mut grammar = gll::proc_macro::builtin(); + // HACK(eddyb) inject a custom builtin - this should be upstreamed to gll! + { + use gll::proc_macro::{FlatTokenPat, Pat}; + + grammar.define( + "LIFETIME", + gll::grammar::eat(Pat(vec![ + FlatTokenPat::Punct { + ch: Some('\''), + joint: Some(true), + }, + FlatTokenPat::Ident(None), + ])), + ); + } + // Add in each grammar fragment to the grammar. for fragment in fragments { let path = fragment.into_path(); From 7e8dfb63b756c4fa63e1882059a77987ad27e0ac Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 1 Nov 2018 10:25:53 +0200 Subject: [PATCH 02/18] Make the output from the tester more useful. --- src/bin/tester.rs | 52 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/bin/tester.rs b/src/bin/tester.rs index 059ec6f..7aacc27 100644 --- a/src/bin/tester.rs +++ b/src/bin/tester.rs @@ -68,12 +68,37 @@ fn parse_file_with(path: &Path, f: impl FnOnce(ModuleContentsResult) -> R) -> /// Output the result of a single file to stderr, /// optionally prefixed by a given `path`. -fn report_file_result(path: Option<&Path>, result: ModuleContentsResult) { +fn report_file_result( + path: Option<&Path>, + result: ModuleContentsResult, + ambiguity_result: Result<(), MoreThanOne>, +) { if let Some(path) = path { eprint!("{}: ", path.display()); } - // FIXME(eddyb) when we start parsing more this could become quite noisy. - eprintln!("{:#?}", result); + // Avoid printing too much, especially not any parse nodes. + match (result, ambiguity_result) { + (Ok(_), Ok(_)) => eprintln!("OK"), + (Ok(_), Err(_)) => eprintln!("OK (ambiguous)"), + (Err(parse::ParseError::TooShort(handle)), _) => { + eprint!("FAIL after "); + + #[cfg(procmacro2_semver_exempt)] + { + // HACK(eddyb) work around `proc-macro2` `Span` printing limitation + let end_location = handle.source_info().end.end(); + eprintln!("{}:{}", end_location.line, end_location.column); + } + #[cfg(not(procmacro2_semver_exempt))] + { + eprintln!( + "(missing location information; \ + set `RUSTFLAGS='--cfg procmacro2_semver_exempt'`)" + ); + } + } + (Err(parse::ParseError::NoParse), _) => eprintln!("FAIL (lexer error?)"), + } } fn ambiguity_check(handle: ModuleContentsHandle) -> Result<(), MoreThanOne> { @@ -118,8 +143,11 @@ fn main() { } => { // Not much to do, try to parse the file and report the result. parse_file_with(&file, |result| { + let mut ambiguity_result = Ok(()); match result { Ok(handle) | Err(parse::ParseError::TooShort(handle)) => { + ambiguity_result = ambiguity_check(handle); + if let Some(out_path) = graphviz_forest { handle .parser @@ -130,7 +158,7 @@ fn main() { } Err(parse::ParseError::NoParse) => {} } - report_file_result(None, result); + report_file_result(None, result, ambiguity_result); }); } Command::Dir { verbose, dir } => { @@ -153,23 +181,25 @@ fn main() { let path = file.into_path(); parse_file_with(&path, |result| { // Increment counters and figure out the character to print. + let mut ambiguity_result = Ok(()); let (status, count) = match result { Ok(handle) => { - if ambiguity_check(handle).is_ok() { - ('~', &mut unambiguous_count) + ambiguity_result = ambiguity_check(handle); + if ambiguity_result.is_ok() { + ('.', &mut unambiguous_count) } else { - ('!', &mut ambiguous_count) + ('-', &mut ambiguous_count) } } - Err(parse::ParseError::TooShort(_)) => ('.', &mut too_short_count), - Err(parse::ParseError::NoParse) => ('X', &mut no_parse_count), + Err(parse::ParseError::TooShort(_)) => ('X', &mut too_short_count), + Err(parse::ParseError::NoParse) => ('L', &mut no_parse_count), }; *count += 1; total_count += 1; if verbose { // Unless we're in verbose mode, in which case we print more. - report_file_result(Some(&path), result); + report_file_result(Some(&path), result, ambiguity_result); } else { // Limit the compact output to 80 columns wide. if total_count % 80 == 0 { @@ -187,7 +217,7 @@ fn main() { println!("* {} parsed fully and unambiguously", unambiguous_count); println!("* {} parsed fully (but ambiguously)", ambiguous_count); println!("* {} parsed partially (only a prefix)", too_short_count); - println!("* {} didn't parse at all", no_parse_count); + println!("* {} didn't parse at all (lexer error?)", no_parse_count); } } } From 4c7e6e9852c41b4adab708923e83dcb9fb335349 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 1 Nov 2018 04:13:42 +0200 Subject: [PATCH 03/18] Implement a lot more of the grammar. --- grammar/abi.g | 32 +++++++++++++ grammar/attr.g | 8 ++-- grammar/expr.g | 116 +++++++++++++++++++++++++++++++++++++++++++++ grammar/generics.g | 35 ++++++++++++++ grammar/item.g | 95 +++++++++++++++++++++++++++++++++++-- grammar/macro.g | 13 +++++ grammar/pat.g | 39 +++++++++++++++ grammar/path.g | 10 +++- grammar/stmt.g | 7 +++ grammar/type.g | 24 ++++++++++ grammar/vis.g | 9 ++++ 11 files changed, 376 insertions(+), 12 deletions(-) create mode 100644 grammar/abi.g create mode 100644 grammar/expr.g create mode 100644 grammar/generics.g create mode 100644 grammar/macro.g create mode 100644 grammar/pat.g create mode 100644 grammar/stmt.g create mode 100644 grammar/type.g create mode 100644 grammar/vis.g diff --git a/grammar/abi.g b/grammar/abi.g new file mode 100644 index 0000000..cac5cfd --- /dev/null +++ b/grammar/abi.g @@ -0,0 +1,32 @@ +// FIXME(eddyb) implement more specific literal support in `gll::proc_macro` +Abi = LITERAL?; + +/* +// HACK(eddyb) taken from `librustc_target/spec/abi.rs` +Abi = + // Defaults to "C" + {} | + + // Platform-specific ABIs + "\"cdecl\"" | + "\"stdcall\"" | + "\"fastcall\"" | + "\"vectorcall\"" | + "\"thiscall\"" | + "\"aapcs\"" | + "\"win64\"" | + "\"sysv64\"" | + "\"ptx-kernel\"" | + "\"msp430-interrupt\"" | + "\"x86-interrupt\"" | + "\"amdgpu-kernel\"" | + + // Cross-platform ABIs + "\"Rust\"" | + "\"C\"" | + "\"system\"" | + "\"rust-intrinsic\"" | + "\"rust-call\"" | + "\"platform-intrinsic\"" | + "\"unadjusted\""; +*/ diff --git a/grammar/attr.g b/grammar/attr.g index 89bce29..c942f5e 100644 --- a/grammar/attr.g +++ b/grammar/attr.g @@ -1,9 +1,7 @@ OuterAttr = "#" attr:Attr; -InnerAttr = "#!" attr:Attr; +InnerAttr = "#" "!" attr:Attr; Attr = "[" path:Path input:AttrInput "]"; AttrInput = {} | - "=" LITERAL | - "(" TOKEN_TREE* ")" | - "[" TOKEN_TREE* "]" | - "{" TOKEN_TREE* "}"; + "=" TOKEN_TREE | + MacroInput; diff --git a/grammar/expr.g b/grammar/expr.g new file mode 100644 index 0000000..4323a13 --- /dev/null +++ b/grammar/expr.g @@ -0,0 +1,116 @@ +Expr = attrs:OuterAttr* kind:ExprKind; +ExprKind = + Literal:LITERAL | + Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } | + Borrow:{ "&" mutable:"mut"? expr:Expr } | + Box:{ "box" expr:Expr } | + Unary:{ op:UnaryOp expr:Expr } | + Try:{ expr:Expr "?" } | + Binary:{ left:Expr op:BinaryOp right:Expr } | + Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } | + Range:{ start:Expr? ".." end:Expr? } | + RangeInclusive:{ start:Expr? "..=" end:Expr } | + Type:{ expr:Expr ":" ty:Type } | + Cast:{ expr:Expr "as" ty:Type } | + Field:{ base:Expr "." field:FieldName } | + Index:{ base:Expr "[" index:Expr "]" } | + Array:{ "[" attrs:InnerAttr* exprs:Expr* % "," ","? "]" } | + Repeat:{ "[" attrs:InnerAttr* elem:Expr ";" count:Expr "]" } | + Tuple:{ "(" attrs:InnerAttr* exprs:Expr* % "," ","? ")" } | + Path:QPath | + Call:{ callee:Expr "(" args:Expr* % "," ","? ")" } | + MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } | + Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } | + Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } | + AsyncBlock:{ "async" block:Block } | + TryBlock:{ "try" block:Block } | + Continue:{ "continue" label:Label? } | + Break:{ "break" label:Label? value:Expr? } | + Return:{ "return" value:Expr? } | + Yield:{ "yield" value:Expr? } | + If:If | + Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } | + Loop:{ { label:Label ":" }? "loop" body:Block } | + While:{ { label:Label ":" }? "while" cond:Cond body:Block } | + For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } | + Closure:{ + generator_static:"static"? asyncness:"async"? by_val:"move"? + "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr + } | + MacroCall:MacroCall; + +UnaryOp = + Not:"!" | + Neg:"-" | + Deref:"*"; + +BinaryOp = + // Arithmetic & bitwise (these also have `BinaryAssignOp` forms) + Add:"+" | + Sub:"-" | + Mul:"*" | + Div:"/" | + Rem:"%" | + BitXor:"^" | + BitAnd:"&" | + BitOr:"|" | + Shl:"<<" | + Shr:">>" | + + // Logic (short-circuiting) + LogicAnd:"&&" | + LogicOr:"||" | + + // Comparisons + Eq:"==" | + Lt:"<" | + Le:"<=" | + Ne:"!=" | + Gt:">" | + Ge:">="; + +// FIXME(eddyb) figure out how to deduplicate this with `BinaryOp` +// The problem is something like `BinaryOp "="` allows a space in between, +// as the last token inside each `BinaryOp` case does not require being +// joint, but each token before the `=` here does impose that requirement. +BinaryAssignOp = + Add:"+=" | + Sub:"-=" | + Mul:"*=" | + Div:"/=" | + Rem:"%=" | + BitXor:"^=" | + BitAnd:"&=" | + BitOr:"|=" | + Shl:"<<=" | + Shr:">>="; + +FieldName = + Ident:IDENT | + // FIXME(eddyb) restrict this to only integer literals + Numeric:LITERAL; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +StructExprFieldsAndBase = + Fields:{ fields:StructExprField* % "," ","? } | + Base:{ ".." base:Expr } | + FieldsAndBase:{ fields:StructExprField+ % "," "," ".." base:Expr }; + +StructExprField = attrs:OuterAttr* kind:StructExprFieldKind; +StructExprFieldKind = + Shorthand:IDENT | + Explicit:{ field:FieldName ":" expr:Expr }; + +Label = LIFETIME; + +If = "if" cond:Cond then:Block { "else" else_expr:ElseExpr }?; +Cond = + Bool:Expr | + Let:{ "let" pat:Pat "=" expr:Expr }; +ElseExpr = + Block:Block | + If:If; + +MatchArm = attrs:OuterAttr* "|"? pats:Pat+ % "|" { "if" guard:Expr }? "=>" body:Expr ","?; + +ClosureArg = pat:Pat { ":" ty:Type }?; diff --git a/grammar/generics.g b/grammar/generics.g new file mode 100644 index 0000000..3bddd12 --- /dev/null +++ b/grammar/generics.g @@ -0,0 +1,35 @@ +Generics = "<" params:GenericParam* % "," ","? ">"; +GenericParam = attrs:OuterAttr* kind:GenericParamKind; +GenericParamKind = + Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* % "+" "+"? }? } | + Type:{ name:IDENT { ":" bounds:TypeBound* % "+" "+"? }? { "=" default:Type }? }; + +ForAllBinder = "for" generics:Generics; + +WhereClause = "where" bounds:WhereBound* % "," ","?; +WhereBound = + Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } | + Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } | + TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type }; + +LifetimeBound = outlives:LIFETIME; +TypeBound = + Outlives:LIFETIME | + Trait:TypeTraitBound | + TraitParen:{ "(" bound:TypeTraitBound ")" }; +TypeTraitBound = unbound:"?"? binder:ForAllBinder? path:Path; + +GenericArgs = + AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ","? ">" } | + Paren:{ "(" inputs:Type* % "," ","? ")" { "->" output:Type }? }; + +// FIXME(eddyb) find a way to express this `A* B*` pattern better +AngleBracketGenericArgsAndBindings = + Args:GenericArg+ % "," | + Bindings:TypeBinding+ % "," | + ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ % "," }; + +GenericArg = + Lifetime:LIFETIME | + Type:Type; +TypeBinding = name:IDENT "=" ty:Type; diff --git a/grammar/item.g b/grammar/item.g index d5d5f7c..93b73e6 100644 --- a/grammar/item.g +++ b/grammar/item.g @@ -1,7 +1,92 @@ -ModuleContents = attrs:InnerAttr* items:ItemWithOuterAttr*; +ModuleContents = attrs:InnerAttr* items:Item*; -ItemWithOuterAttr = attrs:OuterAttr* item:Item; -// TODO other items -Item = +Item = attrs:OuterAttr* vis:Vis? kind:ItemKind; +ItemKind = + Use:{ "use" use_tree:UseTree ";" } | ExternCrate:{ "extern" "crate" name:IDENT { "as" rename:IDENT }? ";" } | - Use:{ "use" path:Path { "as" rename:IDENT }? ";" }; // TODO use trees + Mod:{ "mod" name:IDENT { ";" | "{" contents:ModuleContents "}" } } | + ForeignMod:{ "extern" abi:Abi "{" attrs:InnerAttr* items:ForeignItem* "}" } | + Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type "=" value:Expr ";" } | + Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | + Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | + TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | + ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | + Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } | + Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } | + Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } | + Trait:{ + unsafety:"unsafe"? auto:"auto"? "trait" name:IDENT generics:Generics? + { ":" superbounds:TypeBound* % "+" "+"? }? + where_clause:WhereClause? "{" trait_items:TraitItem* "}" + } | + TraitAlias:{ + "trait" name:IDENT generics:Generics? + { ":" superbounds:TypeBound* % "+" "+"? }? + where_clause:WhereClause? "=" bounds:TypeBound* % "+" "+"? ";" + } | + Impl:{ + defaultness:"default"? unsafety:"unsafe"? "impl" generics:Generics? + { negate:"!"? trait_path:Path "for" }? ty:Type + where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" + } | + Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } | + MacroCall:ItemMacroCall; + +UseTree = + Glob:{ prefix:UseTreePrefix? "*" } | + Nested:{ prefix:UseTreePrefix? "{" children:UseTree* % "," ","? "}" } | + Simple:{ path:Path { "as" rename:IDENT }? }; +UseTreePrefix = + Path:{ path:Path "::" } | + Global:"::"; + +ForeignItem = attrs:OuterAttr* vis:Vis? kind:ForeignItemKind; +ForeignItemKind = + Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } | + Fn:{ "fn" decl:FnDecl ";" } | + Type:{ "type" name:IDENT ";" } | + MacroCall:ItemMacroCall; + +TraitItem = attrs:OuterAttr* kind:TraitItemKind; +TraitItemKind = + Const:{ "const" name:IDENT ":" ty:Type { "=" default:Expr }? ";" } | + Fn:{ header:FnHeader "fn" decl:FnDecl { default_body:Block | ";" } } | + Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } | + MacroCall:ItemMacroCall; + +ImplItem = attrs:OuterAttr* defaultness:"default"? vis:Vis? kind:ImplItemKind; +ImplItemKind = + Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | + Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | + Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | + ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | + MacroCall:ItemMacroCall; + +FnHeader = constness:"const"? unsafety:"unsafe"? asyncness:"async"? { "extern" abi:Abi }?; +FnDecl = name:IDENT generics:Generics? "(" args:FnArgs? ","? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +FnArgs = + Regular:FnArg+ % "," | + Variadic:"..." | + RegularAndVariadic:{ args:FnArg+ % "," "," "..." }; +FnArg = + SelfValue:{ mutable:"mut"? "self" } | + SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } | + Regular:FnSigInput; + +EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?; +EnumVariantKind = + Unit:{} | + Tuple:{ "(" fields:TupleField* % "," ","? ")" } | + Record:{ "{" fields:RecordField* % "," ","? "}" }; + +// FIXME(eddyb) could maybe be shared more with `EnumVariantKind`? +// The problem is the semicolons for `Unit` and `Tuple`, and the where clauses. +StructBody = + Unit:{ where_clause:WhereClause? ";" } | + Tuple:{ "(" fields:TupleField* % "," ","? ")" where_clause:WhereClause? ";" } | + Record:{ where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" }; + +TupleField = attrs:OuterAttr* vis:Vis? ty:Type; +RecordField = attrs:OuterAttr* vis:Vis? name:IDENT ":" ty:Type; diff --git a/grammar/macro.g b/grammar/macro.g new file mode 100644 index 0000000..3e31474 --- /dev/null +++ b/grammar/macro.g @@ -0,0 +1,13 @@ +MacroCall = path:Path "!" ident_input:IDENT? input:MacroInput; +MacroInput = + "(" TOKEN_TREE* ")" | + "[" TOKEN_TREE* "]" | + "{" TOKEN_TREE* "}"; + +// FIXME(eddyb) could maybe be shared more with `MacroInput`? +// The problem is the semicolons for the `()` and `[]` cases. +ItemMacroCall = path:Path "!" ident_input:IDENT? input:ItemMacroInput; +ItemMacroInput = + "(" TOKEN_TREE* ")" ";" | + "[" TOKEN_TREE* "]" ";" | + "{" TOKEN_TREE* "}"; diff --git a/grammar/pat.g b/grammar/pat.g new file mode 100644 index 0000000..49c3b68 --- /dev/null +++ b/grammar/pat.g @@ -0,0 +1,39 @@ +Pat = + Wild:"_" | + Literal:{ minus:"-"? lit:LITERAL } | + Range:{ start:PatRangeValue ".." end:PatRangeValue } | + RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } | + Binding:{ binding:Binding { "@" subpat:Pat }? } | + Paren:{ "(" pat:Pat ")" } | + Ref:{ "&" mutable:"mut"? pat:Pat } | + Box:{ "box" pat:Pat } | + Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } | + Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } | + Path:QPath | + TupleStruct:{ path:Path "(" fields:TuplePatField* % "," ","? ")" } | + Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } | + MacroCall:MacroCall; + +PatRangeValue = + Literal:{ minus:"-"? lit:LITERAL } | + Path:QPath; + +Binding = boxed:"box"? reference:"ref"? mutable:"mut"? name:IDENT; + +SlicePatElem = + Subslice:{ subpat:Pat? ".." } | + Pat:Pat; + +TuplePatField = + Ellipsis:".." | + Pat:Pat; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +StructPatFieldsAndEllipsis = + Fields:{ fields:StructPatField* % "," ","? } | + Ellipsis:{ ".." } | + FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." }; + +StructPatField = + Shorthand:Binding | + Explicit:{ field:FieldName ":" pat:Pat }; diff --git a/grammar/path.g b/grammar/path.g index b880d1a..ecb7fa5 100644 --- a/grammar/path.g +++ b/grammar/path.g @@ -1,2 +1,8 @@ -Path = global:"::"? segments:PathSegment* % "::"; -PathSegment = ident:IDENT; // TODO generics +Path = global:"::"? path:RelativePath; +RelativePath = segments:PathSegment+ % "::"; +PathSegment = ident:IDENT { "::"? args:GenericArgs }?; + +QSelf = "<" ty:Type { "as" trait_path:Path }? ">"; +QPath = + Unqualified:Path | + Qualified:{ qself:QSelf "::" path:RelativePath }; diff --git a/grammar/stmt.g b/grammar/stmt.g new file mode 100644 index 0000000..982780f --- /dev/null +++ b/grammar/stmt.g @@ -0,0 +1,7 @@ +Stmt = + Item:Item | + Local:{ attrs:OuterAttr* "let" pat:Pat { ":" ty:Type }? { "=" init:Expr }? ";" } | + Expr:Expr | + Semi:";"; + +Block = "{" attrs:InnerAttr* Stmt* "}"; diff --git a/grammar/type.g b/grammar/type.g new file mode 100644 index 0000000..743e5b1 --- /dev/null +++ b/grammar/type.g @@ -0,0 +1,24 @@ +Type = + Infer:"_" | + Never:"!" | + Paren:{ "(" ty:Type ")" } | + RawPtr:{ "*" { "const" | mutable:"mut" } pointee:Type } | + Ref:{ "&" lt:LIFETIME? mutable:"mut"? pointee:Type } | + Slice:{ "[" elem:Type "]" } | + Array:{ "[" elem:Type ";" len:Expr "]" } | + Tuple:{ "(" tys:Type* % "," ","? ")" } | + Path:QPath | + FnPtr:{ + binder:ForAllBinder? unsafety:"unsafe"? { "extern" abi:Abi }? + "fn" "(" inputs:FnSigInputs? ","? ")" { "->" ret_ty:Type }? + } | + ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } | + DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } | + TypeOf:{ "typeof" "(" expr:Expr ")" } | + MacroCall:MacroCall; + +FnSigInputs = + Regular:FnSigInput+ % "," | + Variadic:"..." | + RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." }; +FnSigInput = { pat:Pat ":" }? ty:Type; diff --git a/grammar/vis.g b/grammar/vis.g new file mode 100644 index 0000000..60fb246 --- /dev/null +++ b/grammar/vis.g @@ -0,0 +1,9 @@ +Vis = + Crate:"crate" | + Pub:"pub" | + Restricted:{ "pub" "(" restriction:VisRestriction ")" }; +VisRestriction = + Crate:"crate" | + Self_:"self" | + Super:"super" | + Path:{ "in" path:Path }; From 6ad653f47e147e5b1827369417a63ed31e2d5bcf Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 1 Nov 2018 23:20:23 +0200 Subject: [PATCH 04/18] Add a blacklist to the tester to avoid self-DoS-ing. --- src/bin/tester.rs | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/bin/tester.rs b/src/bin/tester.rs index 7aacc27..c7fd25c 100644 --- a/src/bin/tester.rs +++ b/src/bin/tester.rs @@ -176,9 +176,44 @@ fn main() { .map(|entry| entry.unwrap()) .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "rs")); + let mut stdout = io::stdout(); + // Go through all the files and try to parse each of them. for file in files { let path = file.into_path(); + + total_count += 1; + if !verbose { + // Limit the compact output to 80 columns wide. + if total_count % 80 == 0 { + println!(""); + } + } + + // HACK(eddyb) avoid parsing some files that hit + // `lykenware/gll` worst-cases (many GBs of RAM usage) + // FIXME(eddyb) fix the problems (e.g. implement GC). + const BLACKLIST: &[&str] = &[ + "libcore/unicode/tables.rs", + "issues/issue-29466.rs", + "issues/issue-29227.rs", + ]; + if BLACKLIST.iter().any(|&b| path.ends_with(b)) { + if verbose { + eprintln!("{}: SKIP (blacklisted)...", path.display()); + } else { + print!("S"); + stdout.flush().unwrap(); + } + continue; + } + + // Indicate the current file being parsed in verbose mode. + // This can be used to find files to blacklist (see above). + if verbose { + eprint!("{}...\r", path.display()); + } + parse_file_with(&path, |result| { // Increment counters and figure out the character to print. let mut ambiguity_result = Ok(()); @@ -195,18 +230,13 @@ fn main() { Err(parse::ParseError::NoParse) => ('L', &mut no_parse_count), }; *count += 1; - total_count += 1; if verbose { // Unless we're in verbose mode, in which case we print more. report_file_result(Some(&path), result, ambiguity_result); } else { - // Limit the compact output to 80 columns wide. - if total_count % 80 == 0 { - println!(""); - } print!("{}", status); - io::stdout().flush().unwrap(); + stdout.flush().unwrap(); } }) } From 9926a37de41a89ac9356795467e0664ae4805bdc Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Wed, 5 Dec 2018 03:15:05 +0000 Subject: [PATCH 05/18] adopt .lyg as lykenware/gll's new file extension --- build.rs | 4 ++-- grammar/{attr.g => attr.lyg} | 0 grammar/{item.g => item.lyg} | 0 grammar/{path.g => path.lyg} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename grammar/{attr.g => attr.lyg} (100%) rename grammar/{item.g => item.lyg} (100%) rename grammar/{path.g => path.lyg} (100%) diff --git a/build.rs b/build.rs index 4344e57..db4979d 100644 --- a/build.rs +++ b/build.rs @@ -11,12 +11,12 @@ fn main() { // FIXME(eddyb) streamline this process in `gll`. - // Find all the `.g` grammar fragments in `grammar/`. + // Find all the `.lyg` grammar fragments in `grammar/`. let fragments = WalkDir::new("grammar") .contents_first(true) .into_iter() .map(|entry| entry.unwrap()) - .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "g")); + .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "lyg")); // Start with the builtin rules for proc-macro grammars. let mut grammar = gll::proc_macro::builtin(); diff --git a/grammar/attr.g b/grammar/attr.lyg similarity index 100% rename from grammar/attr.g rename to grammar/attr.lyg diff --git a/grammar/item.g b/grammar/item.lyg similarity index 100% rename from grammar/item.g rename to grammar/item.lyg diff --git a/grammar/path.g b/grammar/path.lyg similarity index 100% rename from grammar/path.g rename to grammar/path.lyg From b267067ad1608a946a6db46e0b5f96e73c9450c8 Mon Sep 17 00:00:00 2001 From: Douglas Campos Date: Wed, 5 Dec 2018 03:22:56 +0000 Subject: [PATCH 06/18] adopt .lyg as lykenware/gll's new file extension --- grammar/{abi.g => abi.lyg} | 0 grammar/{expr.g => expr.lyg} | 0 grammar/{generics.g => generics.lyg} | 0 grammar/{macro.g => macro.lyg} | 0 grammar/{pat.g => pat.lyg} | 0 grammar/{stmt.g => stmt.lyg} | 0 grammar/{type.g => type.lyg} | 0 grammar/{vis.g => vis.lyg} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename grammar/{abi.g => abi.lyg} (100%) rename grammar/{expr.g => expr.lyg} (100%) rename grammar/{generics.g => generics.lyg} (100%) rename grammar/{macro.g => macro.lyg} (100%) rename grammar/{pat.g => pat.lyg} (100%) rename grammar/{stmt.g => stmt.lyg} (100%) rename grammar/{type.g => type.lyg} (100%) rename grammar/{vis.g => vis.lyg} (100%) diff --git a/grammar/abi.g b/grammar/abi.lyg similarity index 100% rename from grammar/abi.g rename to grammar/abi.lyg diff --git a/grammar/expr.g b/grammar/expr.lyg similarity index 100% rename from grammar/expr.g rename to grammar/expr.lyg diff --git a/grammar/generics.g b/grammar/generics.lyg similarity index 100% rename from grammar/generics.g rename to grammar/generics.lyg diff --git a/grammar/macro.g b/grammar/macro.lyg similarity index 100% rename from grammar/macro.g rename to grammar/macro.lyg diff --git a/grammar/pat.g b/grammar/pat.lyg similarity index 100% rename from grammar/pat.g rename to grammar/pat.lyg diff --git a/grammar/stmt.g b/grammar/stmt.lyg similarity index 100% rename from grammar/stmt.g rename to grammar/stmt.lyg diff --git a/grammar/type.g b/grammar/type.lyg similarity index 100% rename from grammar/type.g rename to grammar/type.lyg diff --git a/grammar/vis.g b/grammar/vis.lyg similarity index 100% rename from grammar/vis.g rename to grammar/vis.lyg From 3ff30f8d2be308c73a09d8397826ace9971ffc31 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 05:52:53 +0100 Subject: [PATCH 07/18] add unstable notes where ehuss made notes. --- grammar/expr.lyg | 10 +++++++++- grammar/generics.lyg | 1 + grammar/item.lyg | 21 ++++++++++++++++++--- grammar/pat.lyg | 2 ++ grammar/type.lyg | 1 + grammar/vis.lyg | 1 + 6 files changed, 32 insertions(+), 4 deletions(-) diff --git a/grammar/expr.lyg b/grammar/expr.lyg index 4323a13..295c341 100644 --- a/grammar/expr.lyg +++ b/grammar/expr.lyg @@ -10,6 +10,7 @@ ExprKind = Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } | Range:{ start:Expr? ".." end:Expr? } | RangeInclusive:{ start:Expr? "..=" end:Expr } | + // unstable(type_ascription): Type:{ expr:Expr ":" ty:Type } | Cast:{ expr:Expr "as" ty:Type } | Field:{ base:Expr "." field:FieldName } | @@ -22,11 +23,14 @@ ExprKind = MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } | Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } | Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } | + // ustable(async_await): AsyncBlock:{ "async" block:Block } | + // unstable(try_block): TryBlock:{ "try" block:Block } | Continue:{ "continue" label:Label? } | Break:{ "break" label:Label? value:Expr? } | Return:{ "return" value:Expr? } | + // unstable(generators): Yield:{ "yield" value:Expr? } | If:If | Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } | @@ -34,7 +38,11 @@ ExprKind = While:{ { label:Label ":" }? "while" cond:Cond body:Block } | For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } | Closure:{ - generator_static:"static"? asyncness:"async"? by_val:"move"? + // unstable(generators): + generator_static:"static"? + // unstable(async_await): + asyncness:"async"? + by_val:"move"? "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr } | MacroCall:MacroCall; diff --git a/grammar/generics.lyg b/grammar/generics.lyg index 3bddd12..3f3732b 100644 --- a/grammar/generics.lyg +++ b/grammar/generics.lyg @@ -10,6 +10,7 @@ WhereClause = "where" bounds:WhereBound* % "," ","?; WhereBound = Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } | Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } | + // unstable: TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type }; LifetimeBound = outlives:LIFETIME; diff --git a/grammar/item.lyg b/grammar/item.lyg index 93b73e6..0fad474 100644 --- a/grammar/item.lyg +++ b/grammar/item.lyg @@ -10,25 +10,33 @@ ItemKind = Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | + // unstable(existential_type): ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } | Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } | Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } | Trait:{ - unsafety:"unsafe"? auto:"auto"? "trait" name:IDENT generics:Generics? + unsafety:"unsafe"? + // unstable(optin_builtin_traits): + auto:"auto"? + "trait" name:IDENT generics:Generics? { ":" superbounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? "{" trait_items:TraitItem* "}" } | + // unstable(trait_alias): TraitAlias:{ "trait" name:IDENT generics:Generics? { ":" superbounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? "=" bounds:TypeBound* % "+" "+"? ";" } | Impl:{ - defaultness:"default"? unsafety:"unsafe"? "impl" generics:Generics? + // unstable(specialization): + defaultness:"default"? + unsafety:"unsafe"? "impl" generics:Generics? { negate:"!"? trait_path:Path "for" }? ty:Type where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" } | + // unstable(decl_macro): Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } | MacroCall:ItemMacroCall; @@ -44,7 +52,9 @@ ForeignItem = attrs:OuterAttr* vis:Vis? kind:ForeignItemKind; ForeignItemKind = Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } | Fn:{ "fn" decl:FnDecl ";" } | + // unstable(extern_types): Type:{ "type" name:IDENT ";" } | + // unstable(macros_in_extern): MacroCall:ItemMacroCall; TraitItem = attrs:OuterAttr* kind:TraitItemKind; @@ -54,11 +64,16 @@ TraitItemKind = Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } | MacroCall:ItemMacroCall; -ImplItem = attrs:OuterAttr* defaultness:"default"? vis:Vis? kind:ImplItemKind; +ImplItem = + attrs:OuterAttr* + // unstable(specialization): + defaultness:"default"? + vis:Vis? kind:ImplItemKind; ImplItemKind = Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | + // unstable(existential_type): ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | MacroCall:ItemMacroCall; diff --git a/grammar/pat.lyg b/grammar/pat.lyg index 49c3b68..6527b1c 100644 --- a/grammar/pat.lyg +++ b/grammar/pat.lyg @@ -1,11 +1,13 @@ Pat = Wild:"_" | Literal:{ minus:"-"? lit:LITERAL } | + // unstable(exclusive_range_pattern): Range:{ start:PatRangeValue ".." end:PatRangeValue } | RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } | Binding:{ binding:Binding { "@" subpat:Pat }? } | Paren:{ "(" pat:Pat ")" } | Ref:{ "&" mutable:"mut"? pat:Pat } | + // unstable(box_patterns): Box:{ "box" pat:Pat } | Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } | Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } | diff --git a/grammar/type.lyg b/grammar/type.lyg index 743e5b1..965aee6 100644 --- a/grammar/type.lyg +++ b/grammar/type.lyg @@ -14,6 +14,7 @@ Type = } | ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } | DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } | + // unstable(not exposed to users): TypeOf:{ "typeof" "(" expr:Expr ")" } | MacroCall:MacroCall; diff --git a/grammar/vis.lyg b/grammar/vis.lyg index 60fb246..8f7e7bf 100644 --- a/grammar/vis.lyg +++ b/grammar/vis.lyg @@ -1,4 +1,5 @@ Vis = + // unstable(crate_visibility_modifier): Crate:"crate" | Pub:"pub" | Restricted:{ "pub" "(" restriction:VisRestriction ")" }; From 1bf260fb71aba0fc4830527e339b5872fe855d9b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 05:54:49 +0100 Subject: [PATCH 08/18] format abi.lyg --- grammar/abi.lyg | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/grammar/abi.lyg b/grammar/abi.lyg index cac5cfd..c2ea104 100644 --- a/grammar/abi.lyg +++ b/grammar/abi.lyg @@ -4,29 +4,28 @@ Abi = LITERAL?; /* // HACK(eddyb) taken from `librustc_target/spec/abi.rs` Abi = - // Defaults to "C" - {} | - - // Platform-specific ABIs - "\"cdecl\"" | - "\"stdcall\"" | - "\"fastcall\"" | - "\"vectorcall\"" | - "\"thiscall\"" | - "\"aapcs\"" | - "\"win64\"" | - "\"sysv64\"" | - "\"ptx-kernel\"" | - "\"msp430-interrupt\"" | - "\"x86-interrupt\"" | - "\"amdgpu-kernel\"" | - - // Cross-platform ABIs - "\"Rust\"" | - "\"C\"" | - "\"system\"" | - "\"rust-intrinsic\"" | - "\"rust-call\"" | - "\"platform-intrinsic\"" | - "\"unadjusted\""; + // Defaults to "C" + | {} + // Platform-specific ABIs + | "\"cdecl\"" + | "\"stdcall\"" + | "\"fastcall\"" + | "\"vectorcall\"" + | "\"thiscall\"" + | "\"aapcs\"" + | "\"win64\"" + | "\"sysv64\"" + | "\"ptx-kernel\"" + | "\"msp430-interrupt\"" + | "\"x86-interrupt\"" + | "\"amdgpu-kernel\"" + // Cross-platform ABIs + | "\"Rust\"" + | "\"C\"" + | "\"system\"" + | "\"rust-intrinsic\"" + | "\"rust-call\"" + | "\"platform-intrinsic\"" + | "\"unadjusted\"" + ; */ From 7609557668b47eedbee1de0eee62f483539d4e74 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 05:55:30 +0100 Subject: [PATCH 09/18] format attr.lyg --- grammar/attr.lyg | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/grammar/attr.lyg b/grammar/attr.lyg index c942f5e..3ecc104 100644 --- a/grammar/attr.lyg +++ b/grammar/attr.lyg @@ -2,6 +2,7 @@ OuterAttr = "#" attr:Attr; InnerAttr = "#" "!" attr:Attr; Attr = "[" path:Path input:AttrInput "]"; AttrInput = - {} | - "=" TOKEN_TREE | - MacroInput; + | {} + | "=" TOKEN_TREE + | MacroInput + ; From e9900672eff8a15da7d0cef90c8ff81b3469a2cf Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:01:35 +0100 Subject: [PATCH 10/18] format expr.lyg --- grammar/expr.lyg | 194 ++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 94 deletions(-) diff --git a/grammar/expr.lyg b/grammar/expr.lyg index 295c341..b8b7f2c 100644 --- a/grammar/expr.lyg +++ b/grammar/expr.lyg @@ -1,123 +1,129 @@ Expr = attrs:OuterAttr* kind:ExprKind; ExprKind = - Literal:LITERAL | - Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } | - Borrow:{ "&" mutable:"mut"? expr:Expr } | - Box:{ "box" expr:Expr } | - Unary:{ op:UnaryOp expr:Expr } | - Try:{ expr:Expr "?" } | - Binary:{ left:Expr op:BinaryOp right:Expr } | - Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } | - Range:{ start:Expr? ".." end:Expr? } | - RangeInclusive:{ start:Expr? "..=" end:Expr } | - // unstable(type_ascription): - Type:{ expr:Expr ":" ty:Type } | - Cast:{ expr:Expr "as" ty:Type } | - Field:{ base:Expr "." field:FieldName } | - Index:{ base:Expr "[" index:Expr "]" } | - Array:{ "[" attrs:InnerAttr* exprs:Expr* % "," ","? "]" } | - Repeat:{ "[" attrs:InnerAttr* elem:Expr ";" count:Expr "]" } | - Tuple:{ "(" attrs:InnerAttr* exprs:Expr* % "," ","? ")" } | - Path:QPath | - Call:{ callee:Expr "(" args:Expr* % "," ","? ")" } | - MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } | - Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } | - Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } | - // ustable(async_await): - AsyncBlock:{ "async" block:Block } | - // unstable(try_block): - TryBlock:{ "try" block:Block } | - Continue:{ "continue" label:Label? } | - Break:{ "break" label:Label? value:Expr? } | - Return:{ "return" value:Expr? } | - // unstable(generators): - Yield:{ "yield" value:Expr? } | - If:If | - Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } | - Loop:{ { label:Label ":" }? "loop" body:Block } | - While:{ { label:Label ":" }? "while" cond:Cond body:Block } | - For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } | - Closure:{ - // unstable(generators): - generator_static:"static"? - // unstable(async_await): - asyncness:"async"? - by_val:"move"? - "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr - } | - MacroCall:MacroCall; + | Literal:LITERAL + | Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } + | Borrow:{ "&" mutable:"mut"? expr:Expr } + | Box:{ "box" expr:Expr } + | Unary:{ op:UnaryOp expr:Expr } + | Try:{ expr:Expr "?" } + | Binary:{ left:Expr op:BinaryOp right:Expr } + | Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } + | Range:{ start:Expr? ".." end:Expr? } + | RangeInclusive:{ start:Expr? "..=" end:Expr } + // unstable(type_ascription): + | Type:{ expr:Expr ":" ty:Type } + | Cast:{ expr:Expr "as" ty:Type } + | Field:{ base:Expr "." field:FieldName } + | Index:{ base:Expr "[" index:Expr "]" } + | Array:{ "[" attrs:InnerAttr* exprs:Expr* % "," ","? "]" } + | Repeat:{ "[" attrs:InnerAttr* elem:Expr ";" count:Expr "]" } + | Tuple:{ "(" attrs:InnerAttr* exprs:Expr* % "," ","? ")" } + | Path:QPath + | Call:{ callee:Expr "(" args:Expr* % "," ","? ")" } + | MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } + | Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } + | Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } + // ustable(async_await): + | AsyncBlock:{ "async" block:Block } + // unstable(try_block): + | TryBlock:{ "try" block:Block } + | Continue:{ "continue" label:Label? } + | Break:{ "break" label:Label? value:Expr? } + | Return:{ "return" value:Expr? } + // unstable(generators): + | Yield:{ "yield" value:Expr? } + | If:If + | Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } + | Loop:{ { label:Label ":" }? "loop" body:Block } + | While:{ { label:Label ":" }? "while" cond:Cond body:Block } + | For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } + | Closure:{ + // unstable(generators): + generator_static:"static"? + // unstable(async_await): + asyncness:"async"? + by_val:"move"? + "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr + } + | MacroCall:MacroCall + ; UnaryOp = - Not:"!" | - Neg:"-" | - Deref:"*"; + | Not:"!" + | Neg:"-" + | Deref:"*"; BinaryOp = - // Arithmetic & bitwise (these also have `BinaryAssignOp` forms) - Add:"+" | - Sub:"-" | - Mul:"*" | - Div:"/" | - Rem:"%" | - BitXor:"^" | - BitAnd:"&" | - BitOr:"|" | - Shl:"<<" | - Shr:">>" | - - // Logic (short-circuiting) - LogicAnd:"&&" | - LogicOr:"||" | - - // Comparisons - Eq:"==" | - Lt:"<" | - Le:"<=" | - Ne:"!=" | - Gt:">" | - Ge:">="; + // Arithmetic & bitwise (these also have `BinaryAssignOp` forms) + | Add:"+" + | Sub:"-" + | Mul:"*" + | Div:"/" + | Rem:"%" + | BitXor:"^" + | BitAnd:"&" + | BitOr:"|" + | Shl:"<<" + | Shr:">>" + // Logic (short-circuiting) + | LogicAnd:"&&" + | LogicOr:"||" + // Comparisons + | Eq:"==" + | Lt:"<" + | Le:"<=" + | Ne:"!=" + | Gt:">" + | Ge:">=" + ; // FIXME(eddyb) figure out how to deduplicate this with `BinaryOp` // The problem is something like `BinaryOp "="` allows a space in between, // as the last token inside each `BinaryOp` case does not require being // joint, but each token before the `=` here does impose that requirement. BinaryAssignOp = - Add:"+=" | - Sub:"-=" | - Mul:"*=" | - Div:"/=" | - Rem:"%=" | - BitXor:"^=" | - BitAnd:"&=" | - BitOr:"|=" | - Shl:"<<=" | - Shr:">>="; + | Add:"+=" + | Sub:"-=" + | Mul:"*=" + | Div:"/=" + | Rem:"%=" + | BitXor:"^=" + | BitAnd:"&=" + | BitOr:"|=" + | Shl:"<<=" + | Shr:">>=" + ; FieldName = - Ident:IDENT | - // FIXME(eddyb) restrict this to only integer literals - Numeric:LITERAL; + | Ident:IDENT + // FIXME(eddyb) restrict this to only integer literals + | Numeric:LITERAL + ; // FIXME(eddyb) find a way to express this `A* B?` pattern better StructExprFieldsAndBase = - Fields:{ fields:StructExprField* % "," ","? } | - Base:{ ".." base:Expr } | - FieldsAndBase:{ fields:StructExprField+ % "," "," ".." base:Expr }; + | Fields:{ fields:StructExprField* % "," ","? } + | Base:{ ".." base:Expr } + | FieldsAndBase:{ fields:StructExprField+ % "," "," ".." base:Expr } + ; StructExprField = attrs:OuterAttr* kind:StructExprFieldKind; StructExprFieldKind = - Shorthand:IDENT | - Explicit:{ field:FieldName ":" expr:Expr }; + | Shorthand:IDENT + | Explicit:{ field:FieldName ":" expr:Expr } + ; Label = LIFETIME; If = "if" cond:Cond then:Block { "else" else_expr:ElseExpr }?; Cond = - Bool:Expr | - Let:{ "let" pat:Pat "=" expr:Expr }; + | Bool:Expr + | Let:{ "let" pat:Pat "=" expr:Expr } + ; ElseExpr = - Block:Block | - If:If; + | Block:Block + | If:If + ; MatchArm = attrs:OuterAttr* "|"? pats:Pat+ % "|" { "if" guard:Expr }? "=>" body:Expr ","?; From b94e6be6692f2e1244176a0b3e488e1b1a8d189f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:04:11 +0100 Subject: [PATCH 11/18] format generics.lyg --- grammar/generics.lyg | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/grammar/generics.lyg b/grammar/generics.lyg index 3f3732b..b7c8c8b 100644 --- a/grammar/generics.lyg +++ b/grammar/generics.lyg @@ -1,36 +1,42 @@ Generics = "<" params:GenericParam* % "," ","? ">"; GenericParam = attrs:OuterAttr* kind:GenericParamKind; GenericParamKind = - Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* % "+" "+"? }? } | - Type:{ name:IDENT { ":" bounds:TypeBound* % "+" "+"? }? { "=" default:Type }? }; + | Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* % "+" "+"? }? } + | Type:{ name:IDENT { ":" bounds:TypeBound* % "+" "+"? }? { "=" default:Type }? } + ; ForAllBinder = "for" generics:Generics; WhereClause = "where" bounds:WhereBound* % "," ","?; WhereBound = - Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } | - Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } | - // unstable: - TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type }; + | Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } + | Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } + // unstable(#20041): + | TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type } + ; LifetimeBound = outlives:LIFETIME; TypeBound = - Outlives:LIFETIME | - Trait:TypeTraitBound | - TraitParen:{ "(" bound:TypeTraitBound ")" }; + | Outlives:LIFETIME + | Trait:TypeTraitBound + | TraitParen:{ "(" bound:TypeTraitBound ")" } + ; TypeTraitBound = unbound:"?"? binder:ForAllBinder? path:Path; GenericArgs = - AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ","? ">" } | - Paren:{ "(" inputs:Type* % "," ","? ")" { "->" output:Type }? }; + | AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ","? ">" } + | Paren:{ "(" inputs:Type* % "," ","? ")" { "->" output:Type }? } + ; // FIXME(eddyb) find a way to express this `A* B*` pattern better AngleBracketGenericArgsAndBindings = - Args:GenericArg+ % "," | - Bindings:TypeBinding+ % "," | - ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ % "," }; + | Args:GenericArg+ % "," + | Bindings:TypeBinding+ % "," + | ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ % "," } + ; GenericArg = - Lifetime:LIFETIME | - Type:Type; + | Lifetime:LIFETIME + | Type:Type + ; TypeBinding = name:IDENT "=" ty:Type; From 178801ea747ba662bb37caa7834831ad88bddee8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:10:40 +0100 Subject: [PATCH 12/18] format item.lyg --- grammar/item.lyg | 155 +++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/grammar/item.lyg b/grammar/item.lyg index 0fad474..0691694 100644 --- a/grammar/item.lyg +++ b/grammar/item.lyg @@ -2,106 +2,117 @@ ModuleContents = attrs:InnerAttr* items:Item*; Item = attrs:OuterAttr* vis:Vis? kind:ItemKind; ItemKind = - Use:{ "use" use_tree:UseTree ";" } | - ExternCrate:{ "extern" "crate" name:IDENT { "as" rename:IDENT }? ";" } | - Mod:{ "mod" name:IDENT { ";" | "{" contents:ModuleContents "}" } } | - ForeignMod:{ "extern" abi:Abi "{" attrs:InnerAttr* items:ForeignItem* "}" } | - Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type "=" value:Expr ";" } | - Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | - Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | - TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | - // unstable(existential_type): - ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | - Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } | - Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } | - Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } | - Trait:{ - unsafety:"unsafe"? - // unstable(optin_builtin_traits): - auto:"auto"? - "trait" name:IDENT generics:Generics? - { ":" superbounds:TypeBound* % "+" "+"? }? - where_clause:WhereClause? "{" trait_items:TraitItem* "}" - } | - // unstable(trait_alias): - TraitAlias:{ - "trait" name:IDENT generics:Generics? + | Use:{ "use" use_tree:UseTree ";" } + | ExternCrate:{ "extern" "crate" name:IDENT { "as" rename:IDENT }? ";" } + | Mod:{ "mod" name:IDENT { ";" | "{" contents:ModuleContents "}" } } + | ForeignMod:{ "extern" abi:Abi "{" attrs:InnerAttr* items:ForeignItem* "}" } + | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type "=" value:Expr ";" } + | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } + | TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } + // unstable(existential_type): + | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } + | Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } + | Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } + | Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } + | Trait:{ + unsafety:"unsafe"? + // unstable(optin_builtin_traits): + auto:"auto"? + "trait" name:IDENT generics:Generics? + { ":" superbounds:TypeBound* % "+" "+"? }? + where_clause:WhereClause? "{" trait_items:TraitItem* "}" + } + // unstable(trait_alias): + | TraitAlias:{ + "trait" name:IDENT generics:Generics? { ":" superbounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? "=" bounds:TypeBound* % "+" "+"? ";" - } | - Impl:{ - // unstable(specialization): - defaultness:"default"? - unsafety:"unsafe"? "impl" generics:Generics? - { negate:"!"? trait_path:Path "for" }? ty:Type - where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" - } | - // unstable(decl_macro): - Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } | - MacroCall:ItemMacroCall; + } + | Impl:{ + // unstable(specialization): + defaultness:"default"? + unsafety:"unsafe"? "impl" generics:Generics? + { negate:"!"? trait_path:Path "for" }? ty:Type + where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" + } + // unstable(decl_macro): + | Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } + | MacroCall:ItemMacroCall + ; UseTree = - Glob:{ prefix:UseTreePrefix? "*" } | - Nested:{ prefix:UseTreePrefix? "{" children:UseTree* % "," ","? "}" } | - Simple:{ path:Path { "as" rename:IDENT }? }; + | Glob:{ prefix:UseTreePrefix? "*" } + | Nested:{ prefix:UseTreePrefix? "{" children:UseTree* % "," ","? "}" } + | Simple:{ path:Path { "as" rename:IDENT }? } + ; UseTreePrefix = - Path:{ path:Path "::" } | - Global:"::"; + | Path:{ path:Path "::" } + | Global:"::" + ; ForeignItem = attrs:OuterAttr* vis:Vis? kind:ForeignItemKind; ForeignItemKind = - Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } | - Fn:{ "fn" decl:FnDecl ";" } | - // unstable(extern_types): - Type:{ "type" name:IDENT ";" } | - // unstable(macros_in_extern): - MacroCall:ItemMacroCall; + | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } + | Fn:{ "fn" decl:FnDecl ";" } + // unstable(extern_types): + | Type:{ "type" name:IDENT ";" } + // unstable(macros_in_extern): + | MacroCall:ItemMacroCall + ; TraitItem = attrs:OuterAttr* kind:TraitItemKind; TraitItemKind = - Const:{ "const" name:IDENT ":" ty:Type { "=" default:Expr }? ";" } | - Fn:{ header:FnHeader "fn" decl:FnDecl { default_body:Block | ";" } } | - Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } | - MacroCall:ItemMacroCall; + | Const:{ "const" name:IDENT ":" ty:Type { "=" default:Expr }? ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl { default_body:Block | ";" } } + | Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } + | MacroCall:ItemMacroCall + ; ImplItem = - attrs:OuterAttr* - // unstable(specialization): - defaultness:"default"? - vis:Vis? kind:ImplItemKind; + attrs:OuterAttr* + // unstable(specialization): + defaultness:"default"? + vis:Vis? kind:ImplItemKind + ; ImplItemKind = - Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } | - Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } | - Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } | - // unstable(existential_type): - ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } | - MacroCall:ItemMacroCall; + | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } + | Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } + // unstable(existential_type): + | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } + | MacroCall:ItemMacroCall + ; FnHeader = constness:"const"? unsafety:"unsafe"? asyncness:"async"? { "extern" abi:Abi }?; FnDecl = name:IDENT generics:Generics? "(" args:FnArgs? ","? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; // FIXME(eddyb) find a way to express this `A* B?` pattern better FnArgs = - Regular:FnArg+ % "," | - Variadic:"..." | - RegularAndVariadic:{ args:FnArg+ % "," "," "..." }; + | Regular:FnArg+ % "," + | Variadic:"..." + | RegularAndVariadic:{ args:FnArg+ % "," "," "..." } + ; FnArg = - SelfValue:{ mutable:"mut"? "self" } | - SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } | - Regular:FnSigInput; + | SelfValue:{ mutable:"mut"? "self" } + | SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } + | Regular:FnSigInput + ; EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?; EnumVariantKind = - Unit:{} | - Tuple:{ "(" fields:TupleField* % "," ","? ")" } | - Record:{ "{" fields:RecordField* % "," ","? "}" }; + | Unit:{} + | Tuple:{ "(" fields:TupleField* % "," ","? ")" } + | Record:{ "{" fields:RecordField* % "," ","? "}" } + ; // FIXME(eddyb) could maybe be shared more with `EnumVariantKind`? // The problem is the semicolons for `Unit` and `Tuple`, and the where clauses. StructBody = - Unit:{ where_clause:WhereClause? ";" } | - Tuple:{ "(" fields:TupleField* % "," ","? ")" where_clause:WhereClause? ";" } | - Record:{ where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" }; + | Unit:{ where_clause:WhereClause? ";" } + | Tuple:{ "(" fields:TupleField* % "," ","? ")" where_clause:WhereClause? ";" } + | Record:{ where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } + ; TupleField = attrs:OuterAttr* vis:Vis? ty:Type; RecordField = attrs:OuterAttr* vis:Vis? name:IDENT ":" ty:Type; From 91655dd306cef22aecfdb658d99064b256bbab61 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:11:44 +0100 Subject: [PATCH 13/18] format macro.lyg --- grammar/macro.lyg | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/grammar/macro.lyg b/grammar/macro.lyg index 3e31474..87072b4 100644 --- a/grammar/macro.lyg +++ b/grammar/macro.lyg @@ -1,13 +1,15 @@ MacroCall = path:Path "!" ident_input:IDENT? input:MacroInput; MacroInput = - "(" TOKEN_TREE* ")" | - "[" TOKEN_TREE* "]" | - "{" TOKEN_TREE* "}"; + | "(" TOKEN_TREE* ")" + | "[" TOKEN_TREE* "]" + | "{" TOKEN_TREE* "}" + ; // FIXME(eddyb) could maybe be shared more with `MacroInput`? // The problem is the semicolons for the `()` and `[]` cases. ItemMacroCall = path:Path "!" ident_input:IDENT? input:ItemMacroInput; ItemMacroInput = - "(" TOKEN_TREE* ")" ";" | - "[" TOKEN_TREE* "]" ";" | - "{" TOKEN_TREE* "}"; + | "(" TOKEN_TREE* ")" ";" + | "[" TOKEN_TREE* "]" ";" + | "{" TOKEN_TREE* "}" + ; From 149f0838af6a635d39ce64d2b29c3961b8023412 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:13:14 +0100 Subject: [PATCH 14/18] format pat.lyg --- grammar/pat.lyg | 60 +++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/grammar/pat.lyg b/grammar/pat.lyg index 6527b1c..8442949 100644 --- a/grammar/pat.lyg +++ b/grammar/pat.lyg @@ -1,41 +1,47 @@ Pat = - Wild:"_" | - Literal:{ minus:"-"? lit:LITERAL } | - // unstable(exclusive_range_pattern): - Range:{ start:PatRangeValue ".." end:PatRangeValue } | - RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } | - Binding:{ binding:Binding { "@" subpat:Pat }? } | - Paren:{ "(" pat:Pat ")" } | - Ref:{ "&" mutable:"mut"? pat:Pat } | - // unstable(box_patterns): - Box:{ "box" pat:Pat } | - Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } | - Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } | - Path:QPath | - TupleStruct:{ path:Path "(" fields:TuplePatField* % "," ","? ")" } | - Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } | - MacroCall:MacroCall; + | Wild:"_" + | Literal:{ minus:"-"? lit:LITERAL } + // unstable(exclusive_range_pattern): + | Range:{ start:PatRangeValue ".." end:PatRangeValue } + | RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } + | Binding:{ binding:Binding { "@" subpat:Pat }? } + | Paren:{ "(" pat:Pat ")" } + | Ref:{ "&" mutable:"mut"? pat:Pat } + // unstable(box_patterns): + | Box:{ "box" pat:Pat } + | Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } + | Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } + | Path:QPath + | TupleStruct:{ path:Path "(" fields:TuplePatField* % "," ","? ")" } + | Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } + | MacroCall:MacroCall + ; PatRangeValue = - Literal:{ minus:"-"? lit:LITERAL } | - Path:QPath; + | Literal:{ minus:"-"? lit:LITERAL } + | Path:QPath + ; Binding = boxed:"box"? reference:"ref"? mutable:"mut"? name:IDENT; SlicePatElem = - Subslice:{ subpat:Pat? ".." } | - Pat:Pat; + | Subslice:{ subpat:Pat? ".." } + | Pat:Pat + ; TuplePatField = - Ellipsis:".." | - Pat:Pat; + | Ellipsis:".." + | Pat:Pat + ; // FIXME(eddyb) find a way to express this `A* B?` pattern better StructPatFieldsAndEllipsis = - Fields:{ fields:StructPatField* % "," ","? } | - Ellipsis:{ ".." } | - FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." }; + | Fields:{ fields:StructPatField* % "," ","? } + | Ellipsis:{ ".." } + | FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." } + ; StructPatField = - Shorthand:Binding | - Explicit:{ field:FieldName ":" pat:Pat }; + | Shorthand:Binding + | Explicit:{ field:FieldName ":" pat:Pat } + ; From 024e799e456d381b78cf86e1689b99c7de3088d7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:13:43 +0100 Subject: [PATCH 15/18] format path.lyg --- grammar/path.lyg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grammar/path.lyg b/grammar/path.lyg index ecb7fa5..10de3e1 100644 --- a/grammar/path.lyg +++ b/grammar/path.lyg @@ -4,5 +4,6 @@ PathSegment = ident:IDENT { "::"? args:GenericArgs }?; QSelf = "<" ty:Type { "as" trait_path:Path }? ">"; QPath = - Unqualified:Path | - Qualified:{ qself:QSelf "::" path:RelativePath }; + | Unqualified:Path + | Qualified:{ qself:QSelf "::" path:RelativePath } + ; From 78f9302a87facca48df24b75f517a9ef77e7ecb7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:14:09 +0100 Subject: [PATCH 16/18] format stmt.lyg --- grammar/stmt.lyg | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/grammar/stmt.lyg b/grammar/stmt.lyg index 982780f..d0e2e48 100644 --- a/grammar/stmt.lyg +++ b/grammar/stmt.lyg @@ -1,7 +1,8 @@ Stmt = - Item:Item | - Local:{ attrs:OuterAttr* "let" pat:Pat { ":" ty:Type }? { "=" init:Expr }? ";" } | - Expr:Expr | - Semi:";"; + | Item:Item + | Local:{ attrs:OuterAttr* "let" pat:Pat { ":" ty:Type }? { "=" init:Expr }? ";" } + | Expr:Expr + | Semi:";" + ; Block = "{" attrs:InnerAttr* Stmt* "}"; From b63b6e0946d520341369dd4fc3d3a19eb70bf192 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:15:18 +0100 Subject: [PATCH 17/18] format type.lyg --- grammar/type.lyg | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/grammar/type.lyg b/grammar/type.lyg index 965aee6..124fb23 100644 --- a/grammar/type.lyg +++ b/grammar/type.lyg @@ -1,25 +1,27 @@ Type = - Infer:"_" | - Never:"!" | - Paren:{ "(" ty:Type ")" } | - RawPtr:{ "*" { "const" | mutable:"mut" } pointee:Type } | - Ref:{ "&" lt:LIFETIME? mutable:"mut"? pointee:Type } | - Slice:{ "[" elem:Type "]" } | - Array:{ "[" elem:Type ";" len:Expr "]" } | - Tuple:{ "(" tys:Type* % "," ","? ")" } | - Path:QPath | - FnPtr:{ - binder:ForAllBinder? unsafety:"unsafe"? { "extern" abi:Abi }? - "fn" "(" inputs:FnSigInputs? ","? ")" { "->" ret_ty:Type }? - } | - ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } | - DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } | + | Infer:"_" + | Never:"!" + | Paren:{ "(" ty:Type ")" } + | RawPtr:{ "*" { "const" | mutable:"mut" } pointee:Type } + | Ref:{ "&" lt:LIFETIME? mutable:"mut"? pointee:Type } + | Slice:{ "[" elem:Type "]" } + | Array:{ "[" elem:Type ";" len:Expr "]" } + | Tuple:{ "(" tys:Type* % "," ","? ")" } + | Path:QPath + | FnPtr:{ + binder:ForAllBinder? unsafety:"unsafe"? { "extern" abi:Abi }? + "fn" "(" inputs:FnSigInputs? ","? ")" { "->" ret_ty:Type }? + } + | ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } + | DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } // unstable(not exposed to users): - TypeOf:{ "typeof" "(" expr:Expr ")" } | - MacroCall:MacroCall; + | TypeOf:{ "typeof" "(" expr:Expr ")" } + | MacroCall:MacroCall + ; FnSigInputs = - Regular:FnSigInput+ % "," | - Variadic:"..." | - RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." }; + | Regular:FnSigInput+ % "," + | Variadic:"..." + | RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." } + ; FnSigInput = { pat:Pat ":" }? ty:Type; From ebbc976bb6124609aca4e3d6ceadcaccd80d9c8b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 5 Dec 2018 06:16:00 +0100 Subject: [PATCH 18/18] format vis.lyg --- grammar/vis.lyg | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/grammar/vis.lyg b/grammar/vis.lyg index 8f7e7bf..1d3d3f3 100644 --- a/grammar/vis.lyg +++ b/grammar/vis.lyg @@ -1,10 +1,12 @@ Vis = - // unstable(crate_visibility_modifier): - Crate:"crate" | - Pub:"pub" | - Restricted:{ "pub" "(" restriction:VisRestriction ")" }; + // unstable(crate_visibility_modifier): + | Crate:"crate" + | Pub:"pub" + | Restricted:{ "pub" "(" restriction:VisRestriction ")" } + ; VisRestriction = - Crate:"crate" | - Self_:"self" | - Super:"super" | - Path:{ "in" path:Path }; + | Crate:"crate" + | Self_:"self" + | Super:"super" + | Path:{ "in" path:Path } + ;