`llgen`, rather than the dialect given in ISO 14977. The dialect can be
defined self-referentially as follows:
- ~~~~ {.notrust .ebnf .notation}
+ ~~~~ {.ebnf .notation}
grammar : rule + ;
rule : nonterminal ':' productionrule ';' ;
productionrule : production [ '|' production ] * ;
## Comments
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
comment : block_comment | line_comment ;
block_comment : "/*" block_comment_body * '*' + '/' ;
block_comment_body : [block_comment | character] * ;
## Whitespace
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
whitespace : [ whitespace_char | comment ] + ;
~~~~
## Tokens
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
simple_token : keyword | unop | binop ;
token : simple_token | ident | literal | symbol | whitespace token ;
~~~~
The keywords are the following strings:
- ~~~~ {.notrust .keyword}
+ ~~~~ {.text .keyword}
as
box break
continue crate
rule. A literal is a form of constant expression, so is evaluated (primarily)
at compile time.
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
literal : string_lit | char_lit | num_lit ;
~~~~
#### Character and string literals
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
char_lit : '\x27' char_body '\x27' ;
string_lit : '"' string_body * '"' | 'r' raw_string ;
#### Number literals
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
num_lit : nonzero_dec [ dec_digit | '_' ] * num_suffix ?
| '0' [ [ dec_digit | '_' ] * num_suffix ?
| 'b' [ '1' | '0' | '_' ] + int_suffix ?
### Symbols
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
symbol : "::" "->"
| '#' | '[' | ']' | '(' | ')' | '{' | '}'
| ',' | ';' ;
## Paths
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
| expr_path ;
## Macros
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ;
macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ;
matcher : '(' matcher * ')' | '[' matcher * ']'
## Items
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
item : mod_item | fn_item | type_item | struct_item | enum_item
| static_item | trait_item | impl_item | extern_block ;
~~~~
### Modules
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
mod_item : "mod" ident ( ';' | '{' mod '}' );
mod : [ view_item | item ] * ;
~~~~
#### View items
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
view_item : extern_crate_decl | use_decl ;
~~~~
##### Extern crate declarations
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
extern_crate_decl : "extern" "crate" ident [ '(' link_attrs ')' ] ? [ '=' string_lit ] ? ;
link_attrs : link_attr [ ',' link_attrs ] + ;
link_attr : ident '=' literal ;
##### Use declarations
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
use_decl : "pub" ? "use" [ ident '=' path
| path_glob ] ;
~~~~
# fn main() { }
mod quux {
- pub use quux::foo::*;
+ pub use quux::foo::{bar, baz};
pub mod foo {
pub fn bar() { }
}
~~~~
-In this example, the module `quux` re-exports all of the public names defined in `foo`.
+In this example, the module `quux` re-exports two public names defined in `foo`.
Also note that the paths contained in `use` items are relative to the crate root.
-So, in the previous example, the `use` refers to `quux::foo::*`, and not simply to `foo::*`.
+So, in the previous example, the `use` refers to `quux::foo::{bar, baz}`, and not simply to `foo::{bar, baz}`.
This also means that top-level module declarations should be at the crate root if direct usage
of the declared modules within `use` items is desired. It is also possible to use `self` and `super`
at the beginning of a `use` item to refer to the current and direct parent modules respectively.
### Static items
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
static_item : "static" ident ':' type '=' expr ';' ;
~~~~
### External blocks
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
extern_block_item : "extern" '{' extern_block '}' ;
extern_block : [ foreign_fn ] * ;
~~~~
## Attributes
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
attribute : '#' '!' ? '[' meta_item ']' ;
meta_item : ident [ '=' literal
| '(' meta_seq ')' ] ? ;
#### Slot declarations
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
init : [ '=' ] expr ;
~~~~
### Structure expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
struct_expr : expr_path '{' ident ':' expr
[ ',' ident ':' expr ] *
[ ".." expr ] '}' |
### Block expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
block_expr : '{' [ view_item ] *
[ stmt ';' | item ] *
[ expr ] '}' ;
### Method-call expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
method_call_expr : expr '.' ident paren_expr_list ;
~~~~
### Field expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
field_expr : expr '.' ident ;
~~~~
### Vector expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
vec_expr : '[' "mut" ? vec_elems? ']' ;
vec_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
### Index expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
idx_expr : expr '[' expr ']' ;
~~~~
### Binary operator expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
binop_expr : expr binop expr ;
~~~~
The precedence of Rust binary operators is ordered as follows, going
from strong to weak:
- ~~~~ {.notrust .precedence}
+ ~~~~ {.text .precedence}
* / %
as
+ -
expression. Parentheses can be used to explicitly specify evaluation order
within an expression.
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
paren_expr : '(' expr ')' ;
~~~~
### Call expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
expr_list : [ expr [ ',' expr ]* ] ? ;
paren_expr_list : '(' expr_list ')' ;
call_expr : expr paren_expr_list ;
### Lambda expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
ident_list : [ ident [ ',' ident ]* ] ? ;
lambda_expr : '|' ident_list '|' expr ;
~~~~
### While loops
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
while_expr : "while" expr '{' block '}' ;
~~~~
A `loop` expression denotes an infinite loop.
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
loop_expr : [ lifetime ':' ] "loop" '{' block '}';
~~~~
### Break expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
break_expr : "break" [ lifetime ];
~~~~
### Continue expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
continue_expr : "continue" [ lifetime ];
~~~~
### For expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
for_expr : "for" pat "in" expr '{' block '}' ;
~~~~
### If expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
if_expr : "if" expr '{' block '}'
else_tail ? ;
### Match expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
match_expr : "match" expr '{' match_arm * '}' ;
match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
### Return expressions
- ~~~~ {.notrust .ebnf .gram}
+ ~~~~ {.ebnf .gram}
return_expr : "return" expr ? ;
~~~~
### Closure types
- ~~~~ {.notrust .ebnf .notation}
+ ~~~~ {.ebnf .notation}
closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
[ ':' bound-list ] [ '->' type ]
procedure_type := 'proc' [ '<' lifetime-list '>' ] '(' arg-list ')'
These four log levels correspond to levels 1-4, as controlled by `RUST_LOG`:
- ```notrust,bash
+ ```sh
$ RUST_LOG=rust=3 ./rust
This is an error log
This is a warn log
When generating the `expr` for the `A` impl, the `SubstructureFields` is
- ~~~notrust
+ ~~~text
Struct(~[FieldInfo {
span: <span of x>
name: Some(<ident of x>),
For the `B` impl, called with `B(a)` and `B(b)`,
- ~~~notrust
+ ~~~text
Struct(~[FieldInfo {
span: <span of `int`>,
name: None,
When generating the `expr` for a call with `self == C0(a)` and `other
== C0(b)`, the SubstructureFields is
- ~~~notrust
+ ~~~text
EnumMatching(0, <ast::Variant for C0>,
~[FieldInfo {
span: <span of int>
For `C1 {x}` and `C1 {x}`,
- ~~~notrust
+ ~~~text
EnumMatching(1, <ast::Variant for C1>,
~[FieldInfo {
span: <span of x>
For `C0(a)` and `C1 {x}` ,
- ~~~notrust
+ ~~~text
EnumNonMatching(~[(0, <ast::Variant for B0>,
~[(<span of int>, None, <expr for &a>)]),
(1, <ast::Variant for B1>,
A static method on the above would result in,
- ~~~~notrust
+ ~~~text
StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
use owned_slice::OwnedSlice;
use parse::token::InternedString;
-pub use self::ty::*;
-mod ty;
+use self::ty::*;
+
+pub mod ty;
pub struct TraitDef<'a> {
/// The span for the current #[deriving(Foo)] header.
/**
Creates the nested matches for an enum definition recursively, i.e.
- ~~~notrust
+ ~~~text
match self {
Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... },
Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... },