1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
14 use ast::{CallSugar, NoSugar, DoSugar, ForSugar};
15 use ast::{TyBareFn, TyClosure};
16 use ast::{RegionTyParamBound, TraitTyParamBound};
17 use ast::{provided, public, purity};
18 use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer};
19 use ast::{bind_by_copy, bitand, bitor, bitxor, blk};
20 use ast::{blk_check_mode, box};
21 use ast::{crate, crate_cfg, decl, decl_item};
22 use ast::{decl_local, default_blk, deref, div, enum_def};
23 use ast::{expr, expr_, expr_addr_of, expr_match, expr_again};
24 use ast::{expr_assign, expr_assign_op, expr_binary, expr_block};
25 use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
26 use ast::{expr_field, expr_fn_block, expr_if, expr_index};
27 use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
28 use ast::{expr_method_call, expr_paren, expr_path, expr_repeat};
29 use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary};
30 use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
31 use ast::{expr_vstore_slice, expr_vstore_box};
32 use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
33 use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many};
34 use ast::{foreign_item, foreign_item_const, foreign_item_fn, foreign_mod};
35 use ast::{ident, impure_fn, inherited, item, item_, item_const};
36 use ast::{item_const, item_enum, item_fn, item_foreign_mod, item_impl};
37 use ast::{item_mac, item_mod, item_struct, item_trait, item_ty, lit, lit_};
38 use ast::{lit_bool, lit_float, lit_float_unsuffixed, lit_int};
39 use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const};
40 use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal};
41 use ast::{match_seq, match_tok, method, mt, mul, mutability};
42 use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum};
43 use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct};
44 use ast::{pat_tup, pat_uniq, pat_wild, private};
45 use ast::{rem, required};
46 use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl};
47 use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field};
48 use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract};
49 use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value};
50 use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
51 use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
52 use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn};
53 use ast::{ty_infer, ty_method};
54 use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr};
55 use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, uniq};
56 use ast::{unnamed_field, unsafe_blk, unsafe_fn, view_item};
57 use ast::{view_item_, view_item_extern_mod, view_item_use};
58 use ast::{view_path, view_path_glob, view_path_list, view_path_simple};
61 use ast_util::{as_prec, ident_to_path, operator_prec};
63 use codemap::{span, BytePos, spanned, mk_sp};
65 use parse::attr::parser_attr;
67 use parse::common::{seq_sep_none};
68 use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed};
69 use parse::lexer::reader;
70 use parse::lexer::TokenAndSpan;
71 use parse::obsolete::{ObsoleteClassTraits};
72 use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator};
73 use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
74 use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds};
75 use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax};
76 use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer};
77 use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility};
78 use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern};
79 use parse::obsolete::{ObsoletePostFnTySigil};
80 use parse::obsolete::{ObsoleteBareFnType, ObsoleteNewtypeEnum};
81 use parse::obsolete::ObsoleteMode;
82 use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer};
83 use parse::obsolete::{ObsoletePurity, ObsoleteStaticMethod};
84 use parse::obsolete::{ObsoleteConstItem, ObsoleteFixedLengthVectorType};
85 use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
86 use parse::token::{is_plain_ident, INTERPOLATED, special_idents, token_to_binop};
88 use parse::{new_sub_parser_from_file, next_node_id, ParseSess};
92 use core::either::Either;
94 use core::hashmap::HashSet;
102 RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
105 type arg_or_capture_item = Either<arg, ()>;
106 type item_info = (ident, item_, Option<~[attribute]>);
108 pub enum item_or_view_item {
109 // indicates a failure to parse any kind of item:
112 iovi_foreign_item(@foreign_item),
113 iovi_view_item(@view_item)
117 enum view_item_parse_mode {
118 VIEW_ITEMS_AND_ITEMS_ALLOWED,
119 FOREIGN_ITEMS_ALLOWED,
120 IMPORTS_AND_ITEMS_ALLOWED
123 /* The expr situation is not as complex as I thought it would be.
124 The important thing is to make sure that lookahead doesn't balk
125 at INTERPOLATED tokens */
126 macro_rules! maybe_whole_expr (
129 INTERPOLATED(token::nt_expr(copy e)) => {
133 INTERPOLATED(token::nt_path(copy pt)) => {
146 macro_rules! maybe_whole (
147 ($p:expr, $constructor:ident) => (
149 INTERPOLATED(token::$constructor(copy x)) => {
156 (deref $p:expr, $constructor:ident) => (
158 INTERPOLATED(token::$constructor(copy x)) => {
165 (Some $p:expr, $constructor:ident) => (
167 INTERPOLATED(token::$constructor(copy x)) => {
174 (iovi $p:expr, $constructor:ident) => (
176 INTERPOLATED(token::$constructor(copy x)) => {
183 (pair_empty $p:expr, $constructor:ident) => (
185 INTERPOLATED(token::$constructor(copy x)) => {
195 fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>)
199 Some(ref attrs) => vec::append(lhs, (*attrs))
204 struct ParsedItemsAndViewItems {
205 attrs_remaining: ~[attribute],
206 view_items: ~[@view_item],
208 foreign_items: ~[@foreign_item]
211 /* ident is handled by common.rs */
213 pub fn Parser(sess: @mut ParseSess,
217 let tok0 = copy rdr.next_token();
218 let interner = rdr.interner();
225 token: @mut copy tok0.tok,
226 span: @mut copy tok0.sp,
227 last_span: @mut copy tok0.sp,
228 buffer: @mut ([copy tok0, .. 4]),
229 buffer_start: @mut 0,
231 tokens_consumed: @mut 0,
232 restriction: @mut UNRESTRICTED,
234 keywords: token::keyword_table(),
235 strict_keywords: token::strict_keyword_table(),
236 reserved_keywords: token::reserved_keyword_table(),
237 obsolete_set: @mut HashSet::new(),
238 mod_path_stack: @mut ~[],
242 // ooh, nasty mutable fields everywhere....
244 sess: @mut ParseSess,
246 // the current token:
247 token: @mut token::Token,
248 // the span of the current token:
250 // the span of the prior token:
251 last_span: @mut span,
252 buffer: @mut [TokenAndSpan, ..4],
253 buffer_start: @mut int,
254 buffer_end: @mut int,
255 tokens_consumed: @mut uint,
256 restriction: @mut restriction,
257 quote_depth: @mut uint, // not (yet) related to the quasiquoter
259 interner: @token::ident_interner,
260 keywords: HashSet<~str>,
261 strict_keywords: HashSet<~str>,
262 reserved_keywords: HashSet<~str>,
263 /// The set of seen errors about obsolete syntax. Used to suppress
264 /// extra detail when the same error is seen twice
265 obsolete_set: @mut HashSet<ObsoleteSyntax>,
266 /// Used to determine the path to externally loaded source files
267 mod_path_stack: @mut ~[~str],
272 impl Drop for Parser {
273 /* do not copy the parser; its state is tied to outside state */
274 fn finalize(&self) {}
278 // advance the parser by one token
280 *self.last_span = copy *self.span;
281 let next = if *self.buffer_start == *self.buffer_end {
282 self.reader.next_token()
284 let next = copy self.buffer[*self.buffer_start];
285 *self.buffer_start = (*self.buffer_start + 1) & 3;
288 *self.token = copy next.tok;
289 *self.span = copy next.sp;
290 *self.tokens_consumed += 1u;
292 // EFFECT: replace the current token and span with the given one
293 fn replace_token(&self, next: token::Token, lo: BytePos, hi: BytePos) {
295 *self.span = mk_sp(lo, hi);
297 fn buffer_length(&self) -> int {
298 if *self.buffer_start <= *self.buffer_end {
299 return *self.buffer_end - *self.buffer_start;
301 return (4 - *self.buffer_start) + *self.buffer_end;
303 fn look_ahead(&self, distance: uint) -> token::Token {
304 let dist = distance as int;
305 while self.buffer_length() < dist {
306 self.buffer[*self.buffer_end] = self.reader.next_token();
307 *self.buffer_end = (*self.buffer_end + 1) & 3;
309 return copy self.buffer[(*self.buffer_start + dist - 1) & 3].tok;
311 fn fatal(&self, m: ~str) -> ! {
312 self.sess.span_diagnostic.span_fatal(*copy self.span, m)
314 fn span_fatal(&self, sp: span, m: ~str) -> ! {
315 self.sess.span_diagnostic.span_fatal(sp, m)
317 fn span_note(&self, sp: span, m: ~str) {
318 self.sess.span_diagnostic.span_note(sp, m)
320 fn bug(&self, m: ~str) -> ! {
321 self.sess.span_diagnostic.span_bug(*copy self.span, m)
323 fn warn(&self, m: ~str) {
324 self.sess.span_diagnostic.span_warn(*copy self.span, m)
326 fn span_err(&self, sp: span, m: ~str) {
327 self.sess.span_diagnostic.span_err(sp, m)
329 fn abort_if_errors(&self) {
330 self.sess.span_diagnostic.handler().abort_if_errors();
332 fn get_id(&self) -> node_id { next_node_id(self.sess) }
334 fn id_to_str(&self, id: ident) -> @~str {
335 self.sess.interner.get(id)
338 // is this one of the keywords that signals a closure type?
339 fn token_is_closure_keyword(&self, tok: &token::Token) -> bool {
340 self.token_is_keyword(&~"pure", tok) ||
341 self.token_is_keyword(&~"unsafe", tok) ||
342 self.token_is_keyword(&~"once", tok) ||
343 self.token_is_keyword(&~"fn", tok)
346 fn token_is_lifetime(&self, tok: &token::Token) -> bool {
348 token::LIFETIME(*) => true,
353 fn get_lifetime(&self, tok: &token::Token) -> ast::ident {
355 token::LIFETIME(ref ident) => copy *ident,
356 _ => self.bug(~"not a lifetime"),
360 // parse a ty_bare_fun type:
361 fn parse_ty_bare_fn(&self) -> ty_
365 extern "ABI" [pure|unsafe] fn <'lt> (S) -> T
366 ^~~~^ ^~~~~~~~~~~~^ ^~~~^ ^~^ ^
377 let opt_abis = self.parse_opt_abis();
378 let abis = opt_abis.get_or_default(AbiSet::Rust());
379 let purity = self.parse_unsafety();
380 self.expect_keyword(&~"fn");
381 let (decl, lifetimes) = self.parse_ty_fn_decl();
382 return ty_bare_fn(@TyBareFn {
385 lifetimes: lifetimes,
390 // parse a ty_closure type
391 fn parse_ty_closure(&self,
393 region: Option<@ast::Lifetime>) -> ty_
397 (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T
398 ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^
400 | | | | | | Return type
401 | | | | | Argument types
403 | | | Once-ness (a.k.a., affine)
410 // At this point, the allocation type and lifetime bound have been
413 let purity = self.parse_unsafety();
414 let onceness = parse_onceness(self);
415 self.expect_keyword(&~"fn");
417 if self.parse_fn_ty_sigil().is_some() {
418 self.obsolete(*self.span,
419 ObsoletePostFnTySigil);
422 let (decl, lifetimes) = self.parse_ty_fn_decl();
424 return ty_closure(@TyClosure {
430 lifetimes: lifetimes,
433 fn parse_onceness(self: &Parser) -> Onceness {
434 if self.eat_keyword(&~"once") { Once } else { Many }
438 // looks like this should be called parse_unsafety
439 fn parse_unsafety(&self) -> purity {
440 if self.eat_keyword(&~"pure") {
441 self.obsolete(*self.last_span, ObsoletePurity);
443 } else if self.eat_keyword(&~"unsafe") {
450 // parse a function type (following the 'fn')
451 fn parse_ty_fn_decl(&self) -> (fn_decl, OptVec<ast::Lifetime>) {
462 let lifetimes = if self.eat(&token::LT) {
463 let lifetimes = self.parse_lifetimes();
470 let inputs = self.parse_unspanned_seq(
473 seq_sep_trailing_disallowed(token::COMMA),
474 |p| p.parse_arg_general(false)
476 let (ret_style, ret_ty) = self.parse_ret_ty();
477 let decl = ast::fn_decl {
485 // parse the methods in a trait declaration
486 fn parse_trait_methods(&self) -> ~[trait_method] {
487 do self.parse_unspanned_seq(
492 let attrs = p.parse_outer_attributes();
495 let vis = p.parse_visibility();
496 let pur = p.parse_fn_purity();
497 // NB: at the moment, trait methods are public by default; this
499 let ident = p.parse_ident();
501 let generics = p.parse_generics();
503 let (self_ty, d) = do self.parse_fn_decl_with_self() |p| {
504 // This is somewhat dubious; We don't want to allow argument
505 // names to be left off if there is a definition...
506 either::Left(p.parse_arg_general(false))
509 let hi = p.last_span.hi;
510 debug!("parse_trait_methods(): trait method signature ends in \
512 self.this_token_to_str());
516 debug!("parse_trait_methods(): parsing required method");
517 // NB: at the moment, visibility annotations on required
518 // methods are ignored; this could change.
531 debug!("parse_trait_methods(): parsing provided method");
532 let (inner_attrs, body) =
533 p.parse_inner_attrs_and_block();
534 let attrs = vec::append(attrs, inner_attrs);
535 provided(@ast::method {
553 "expected `;` or `}` but found `%s`",
554 self.this_token_to_str()
563 // parse a possibly mutable type
564 fn parse_mt(&self) -> mt {
565 let mutbl = self.parse_mutability();
566 let t = self.parse_ty(false);
567 mt { ty: t, mutbl: mutbl }
570 // parse [mut/const/imm] ID : TY
571 // now used only by obsolete record syntax parser...
572 fn parse_ty_field(&self) -> ty_field {
573 let lo = self.span.lo;
574 let mutbl = self.parse_mutability();
575 let id = self.parse_ident();
576 self.expect(&token::COLON);
577 let ty = self.parse_ty(false);
583 mt: ast::mt { ty: ty, mutbl: mutbl },
588 // parse optional return type [ -> TY ] in function decl
589 fn parse_ret_ty(&self) -> (ret_style, @Ty) {
590 return if self.eat(&token::RARROW) {
591 let lo = self.span.lo;
592 if self.eat(&token::NOT) {
598 span: mk_sp(lo, self.last_span.hi)
602 (return_val, self.parse_ty(false))
605 let pos = self.span.lo;
611 span: mk_sp(pos, pos),
618 // Useless second parameter for compatibility with quasiquote macros.
620 fn parse_ty(&self, _: bool) -> @Ty {
621 maybe_whole!(self, nt_ty);
623 let lo = self.span.lo;
625 let t = if *self.token == token::LPAREN {
627 if *self.token == token::RPAREN {
631 // (t) is a parenthesized ty
632 // (t,) is the type of a tuple with only one field,
634 let mut ts = ~[self.parse_ty(false)];
635 let mut one_tuple = false;
636 while *self.token == token::COMMA {
638 if *self.token != token::RPAREN {
639 ts.push(self.parse_ty(false));
645 let t = if ts.len() == 1 && !one_tuple {
650 self.expect(&token::RPAREN);
653 } else if *self.token == token::AT {
656 self.parse_box_or_uniq_pointee(ManagedSigil, ty_box)
657 } else if *self.token == token::TILDE {
660 self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq)
661 } else if *self.token == token::BINOP(token::STAR) {
662 // STAR POINTER (bare pointer?)
664 ty_ptr(self.parse_mt())
665 } else if *self.token == token::LBRACE {
666 // STRUCTURAL RECORD (remove?)
667 let elems = self.parse_unspanned_seq(
670 seq_sep_trailing_allowed(token::COMMA),
671 |p| p.parse_ty_field()
673 if elems.len() == 0 {
674 self.unexpected_last(&token::RBRACE);
676 self.obsolete(*self.last_span, ObsoleteRecordType);
678 } else if *self.token == token::LBRACKET {
680 self.expect(&token::LBRACKET);
681 let mt = self.parse_mt();
682 if mt.mutbl == m_mutbl { // `m_const` too after snapshot
683 self.obsolete(*self.last_span, ObsoleteMutVector);
686 // Parse the `, ..e` in `[ int, ..e ]`
687 // where `e` is a const expression
688 let t = match self.maybe_parse_fixed_vstore() {
690 Some(suffix) => ty_fixed_length_vec(mt, suffix)
692 self.expect(&token::RBRACKET);
694 } else if *self.token == token::BINOP(token::AND) {
697 self.parse_borrowed_pointee()
698 } else if self.eat_keyword(&~"extern") {
700 self.parse_ty_bare_fn()
701 } else if self.token_is_closure_keyword(© *self.token) {
703 let result = self.parse_ty_closure(ast::BorrowedSigil, None);
704 self.obsolete(*self.last_span, ObsoleteBareFnType);
706 } else if *self.token == token::MOD_SEP
707 || is_ident_or_path(&*self.token) {
709 let path = self.parse_path_with_tps(false);
710 ty_path(path, self.get_id())
712 self.fatal(fmt!("expected type, found token %?",
716 let sp = mk_sp(lo, self.last_span.hi);
717 @Ty {id: self.get_id(), node: t, span: sp}
720 // parse the type following a @ or a ~
721 fn parse_box_or_uniq_pointee(
724 ctor: &fn(v: mt) -> ty_) -> ty_
726 // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types:
728 token::LIFETIME(*) => {
729 let lifetime = @self.parse_lifetime();
731 return self.parse_ty_closure(sigil, Some(lifetime));
735 if self.look_ahead(1u) == token::BINOP(token::SLASH) &&
736 self.token_is_closure_keyword(&self.look_ahead(2u))
738 let lifetime = @self.parse_lifetime();
739 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
740 return self.parse_ty_closure(sigil, Some(lifetime));
741 } else if self.token_is_closure_keyword(© *self.token) {
742 return self.parse_ty_closure(sigil, None);
748 // other things are parsed as @ + a type. Note that constructs like
749 // @[] and @str will be resolved during typeck to slices and so forth,
750 // rather than boxed ptrs. But the special casing of str/vec is not
751 // reflected in the AST type.
752 let mt = self.parse_mt();
754 if mt.mutbl != m_imm && sigil == OwnedSigil {
755 self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
757 if mt.mutbl == m_const && sigil == ManagedSigil {
758 self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
764 fn parse_borrowed_pointee(&self) -> ty_ {
765 // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
766 let opt_lifetime = self.parse_opt_lifetime();
768 if self.token_is_closure_keyword(© *self.token) {
769 return self.parse_ty_closure(BorrowedSigil, opt_lifetime);
772 let mt = self.parse_mt();
773 return ty_rptr(opt_lifetime, mt);
776 // parse an optional mode.
777 // XXX: Remove after snapshot.
778 fn parse_arg_mode(&self) {
779 if self.eat(&token::BINOP(token::MINUS)) {
780 self.obsolete(*self.span, ObsoleteMode);
781 } else if self.eat(&token::ANDAND) {
783 } else if self.eat(&token::BINOP(token::PLUS)) {
784 if self.eat(&token::BINOP(token::PLUS)) {
785 // ++ mode is obsolete, but we need a snapshot
786 // to stop parsing it.
796 fn is_named_argument(&self) -> bool {
797 let offset = if *self.token == token::BINOP(token::AND) {
799 } else if *self.token == token::BINOP(token::MINUS) {
801 } else if *self.token == token::ANDAND {
803 } else if *self.token == token::BINOP(token::PLUS) {
804 if self.look_ahead(1) == token::BINOP(token::PLUS) {
811 is_plain_ident(&*self.token)
812 && self.look_ahead(1) == token::COLON
814 is_plain_ident(&self.look_ahead(offset))
815 && self.look_ahead(offset + 1) == token::COLON
819 // This version of parse arg doesn't necessarily require
821 fn parse_arg_general(&self, require_name: bool) -> arg {
822 let mut is_mutbl = false;
823 let pat = if require_name || self.is_named_argument() {
824 self.parse_arg_mode();
825 is_mutbl = self.eat_keyword(&~"mut");
826 let pat = self.parse_pat(false);
827 self.expect(&token::COLON);
830 ast_util::ident_to_pat(self.get_id(),
832 special_idents::invalid)
835 let t = self.parse_ty(false);
845 // parse a single function argument
846 fn parse_arg(&self) -> arg_or_capture_item {
847 either::Left(self.parse_arg_general(true))
850 // parse an argument in a lambda header e.g. |arg, arg|
851 fn parse_fn_block_arg(&self) -> arg_or_capture_item {
852 self.parse_arg_mode();
853 let is_mutbl = self.eat_keyword(&~"mut");
854 let pat = self.parse_pat(false);
855 let t = if self.eat(&token::COLON) {
861 span: mk_sp(self.span.lo, self.span.hi),
864 either::Left(ast::arg {
872 fn maybe_parse_fixed_vstore(&self) -> Option<@ast::expr> {
873 if self.eat(&token::BINOP(token::STAR)) {
874 self.obsolete(*self.last_span, ObsoleteFixedLengthVectorType);
875 Some(self.parse_expr())
876 } else if *self.token == token::COMMA &&
877 self.look_ahead(1) == token::DOTDOT {
880 Some(self.parse_expr())
886 // matches token_lit = LIT_INT | ...
887 fn lit_from_token(&self, tok: &token::Token) -> lit_ {
889 token::LIT_INT(i, it) => lit_int(i, it),
890 token::LIT_UINT(u, ut) => lit_uint(u, ut),
891 token::LIT_INT_UNSUFFIXED(i) => lit_int_unsuffixed(i),
892 token::LIT_FLOAT(s, ft) => lit_float(self.id_to_str(s), ft),
893 token::LIT_FLOAT_UNSUFFIXED(s) =>
894 lit_float_unsuffixed(self.id_to_str(s)),
895 token::LIT_STR(s) => lit_str(self.id_to_str(s)),
896 token::LPAREN => { self.expect(&token::RPAREN); lit_nil },
897 _ => { self.unexpected_last(tok); }
901 // matches lit = true | false | token_lit
902 fn parse_lit(&self) -> lit {
903 let lo = self.span.lo;
904 let lit = if self.eat_keyword(&~"true") {
906 } else if self.eat_keyword(&~"false") {
909 // XXX: This is a really bad copy!
910 let tok = copy *self.token;
912 self.lit_from_token(&tok)
914 codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
917 // parse a path into a vector of idents, whether the path starts
918 // with ::, and a span.
919 fn parse_path(&self) -> (~[ast::ident],bool,span) {
920 let lo = self.span.lo;
921 let is_global = self.eat(&token::MOD_SEP);
922 let (ids,span{lo:_,hi,expn_info}) = self.parse_path_non_global();
923 (ids,is_global,span{lo:lo,hi:hi,expn_info:expn_info})
926 // parse a path beginning with an identifier into a vector of idents and a span
927 fn parse_path_non_global(&self) -> (~[ast::ident],span) {
928 let lo = self.span.lo;
930 // must be at least one to begin:
931 ids.push(self.parse_ident());
935 match self.look_ahead(1u) {
936 token::IDENT(id,_) => {
938 ids.push(self.parse_ident());
946 (ids, mk_sp(lo, self.last_span.hi))
949 // parse a path that doesn't have type parameters attached
950 fn parse_path_without_tps(&self)
952 maybe_whole!(self, nt_path);
953 let (ids,is_global,sp) = self.parse_path();
954 @ast::Path { span: sp,
961 // parse a path optionally with type parameters. If 'colons'
962 // is true, then type parameters must be preceded by colons,
963 // as in a::t::<t1,t2>
964 fn parse_path_with_tps(&self, colons: bool) -> @ast::Path {
965 debug!("parse_path_with_tps(colons=%b)", colons);
967 maybe_whole!(self, nt_path);
968 let lo = self.span.lo;
969 let path = self.parse_path_without_tps();
970 if colons && !self.eat(&token::MOD_SEP) {
974 // Parse the (obsolete) trailing region parameter, if any, which will
975 // be written "foo/&x"
977 if *self.token == token::BINOP(token::SLASH)
978 && self.look_ahead(1u) == token::BINOP(token::AND)
980 self.bump(); self.bump();
981 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
983 token::IDENT(sid, _) => {
984 let span = copy self.span;
986 Some(@ast::Lifetime {
993 self.fatal(fmt!("Expected a lifetime name"));
1001 // Parse any lifetime or type parameters which may appear:
1002 let (lifetimes, tps) = self.parse_generic_values();
1003 let hi = self.span.lo;
1005 let rp = match (&rp_slash, &lifetimes) {
1006 (&Some(_), _) => rp_slash,
1010 } else if v.len() == 1 {
1013 self.fatal(fmt!("Expected at most one \
1014 lifetime name (for now)"));
1019 @ast::Path { span: mk_sp(lo, hi),
1025 /// parses 0 or 1 lifetime
1026 fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> {
1028 token::LIFETIME(*) => {
1029 Some(@self.parse_lifetime())
1032 // Also accept the (obsolete) syntax `foo/`
1033 token::IDENT(*) => {
1034 if self.look_ahead(1u) == token::BINOP(token::SLASH) {
1035 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
1036 Some(@self.parse_lifetime())
1048 fn token_is_lifetime(&self, tok: &token::Token) -> bool {
1050 token::LIFETIME(_) => true,
1055 /// Parses a single lifetime
1056 // matches lifetime = ( LIFETIME ) | ( IDENT / )
1057 fn parse_lifetime(&self) -> ast::Lifetime {
1059 token::LIFETIME(i) => {
1060 let span = copy self.span;
1062 return ast::Lifetime {
1069 // Also accept the (obsolete) syntax `foo/`
1070 token::IDENT(i, _) => {
1071 let span = copy self.span;
1073 self.expect(&token::BINOP(token::SLASH));
1074 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
1075 return ast::Lifetime {
1083 self.fatal(fmt!("Expected a lifetime name"));
1088 // matches lifetimes = ( lifetime ) | ( lifetime , lifetimes )
1089 // actually, it matches the empty one too, but putting that in there
1090 // messes up the grammar....
1091 fn parse_lifetimes(&self) -> OptVec<ast::Lifetime> {
1094 * Parses zero or more comma separated lifetimes.
1095 * Expects each lifetime to be followed by either
1096 * a comma or `>`. Used when parsing type parameter
1097 * lists, where we expect something like `<'a, 'b, T>`.
1100 let mut res = opt_vec::Empty;
1103 token::LIFETIME(_) => {
1104 res.push(self.parse_lifetime());
1112 token::COMMA => { self.bump();}
1113 token::GT => { return res; }
1114 token::BINOP(token::SHR) => { return res; }
1116 self.fatal(fmt!("expected `,` or `>` after lifetime name, got: %?",
1123 fn token_is_mutability(&self, tok: &token::Token) -> bool {
1124 self.token_is_keyword(&~"mut", tok) ||
1125 self.token_is_keyword(&~"const", tok)
1128 // parse mutability declaration (mut/const/imm)
1129 fn parse_mutability(&self) -> mutability {
1130 if self.eat_keyword(&~"mut") {
1132 } else if self.eat_keyword(&~"const") {
1139 // parse ident COLON expr
1140 fn parse_field(&self) -> field {
1141 let lo = self.span.lo;
1142 let m = self.parse_mutability();
1143 let i = self.parse_ident();
1144 self.expect(&token::COLON);
1145 let e = self.parse_expr();
1146 spanned(lo, e.span.hi, ast::field_ { mutbl: m, ident: i, expr: e })
1149 fn mk_expr(&self, lo: BytePos, hi: BytePos, node: expr_) -> @expr {
1152 callee_id: self.get_id(),
1154 span: mk_sp(lo, hi),
1158 fn mk_mac_expr(&self, lo: BytePos, hi: BytePos, m: mac_) -> @expr {
1161 callee_id: self.get_id(),
1162 node: expr_mac(codemap::spanned {node: m, span: mk_sp(lo, hi)}),
1163 span: mk_sp(lo, hi),
1167 fn mk_lit_u32(&self, i: u32) -> @expr {
1168 let span = self.span;
1169 let lv_lit = @codemap::spanned {
1170 node: lit_uint(i as u64, ty_u32),
1176 callee_id: self.get_id(),
1177 node: expr_lit(lv_lit),
1182 // at the bottom (top?) of the precedence hierarchy,
1183 // parse things like parenthesized exprs,
1184 // macros, return, etc.
1185 fn parse_bottom_expr(&self) -> @expr {
1186 maybe_whole_expr!(self);
1188 let lo = self.span.lo;
1189 let mut hi = self.span.hi;
1193 if *self.token == token::LPAREN {
1195 // (e) is parenthesized e
1196 // (e,) is a tuple with only one field, e
1197 let mut trailing_comma = false;
1198 if *self.token == token::RPAREN {
1201 let lit = @spanned(lo, hi, lit_nil);
1202 return self.mk_expr(lo, hi, expr_lit(lit));
1204 let mut es = ~[self.parse_expr()];
1205 while *self.token == token::COMMA {
1207 if *self.token != token::RPAREN {
1208 es.push(self.parse_expr());
1211 trailing_comma = true;
1215 self.expect(&token::RPAREN);
1217 return if es.len() == 1 && !trailing_comma {
1218 self.mk_expr(lo, self.span.hi, expr_paren(es[0]))
1221 self.mk_expr(lo, hi, expr_tup(es))
1223 } else if *self.token == token::LBRACE {
1225 let blk = self.parse_block_tail(lo, default_blk);
1226 return self.mk_expr(blk.span.lo, blk.span.hi,
1228 } else if token::is_bar(&*self.token) {
1229 return self.parse_lambda_expr();
1230 } else if self.eat_keyword(&~"if") {
1231 return self.parse_if_expr();
1232 } else if self.eat_keyword(&~"for") {
1233 return self.parse_sugary_call_expr(~"for", ForSugar,
1235 } else if self.eat_keyword(&~"do") {
1236 return self.parse_sugary_call_expr(~"do", DoSugar,
1238 } else if self.eat_keyword(&~"while") {
1239 return self.parse_while_expr();
1240 } else if self.token_is_lifetime(&*self.token) {
1241 let lifetime = self.get_lifetime(&*self.token);
1243 self.expect(&token::COLON);
1244 self.expect_keyword(&~"loop");
1245 return self.parse_loop_expr(Some(lifetime));
1246 } else if self.eat_keyword(&~"loop") {
1247 return self.parse_loop_expr(None);
1248 } else if self.eat_keyword(&~"match") {
1249 return self.parse_match_expr();
1250 } else if self.eat_keyword(&~"unsafe") {
1251 return self.parse_block_expr(lo, unsafe_blk);
1252 } else if *self.token == token::LBRACKET {
1254 let mutbl = self.parse_mutability();
1255 if mutbl == m_mutbl || mutbl == m_const {
1256 self.obsolete(*self.last_span, ObsoleteMutVector);
1259 if *self.token == token::RBRACKET {
1262 ex = expr_vec(~[], mutbl);
1265 let first_expr = self.parse_expr();
1266 if *self.token == token::COMMA &&
1267 self.look_ahead(1) == token::DOTDOT {
1268 // Repeating vector syntax: [ 0, ..512 ]
1271 let count = self.parse_expr();
1272 self.expect(&token::RBRACKET);
1273 ex = expr_repeat(first_expr, count, mutbl);
1274 } else if *self.token == token::COMMA {
1275 // Vector with two or more elements.
1277 let remaining_exprs = self.parse_seq_to_end(
1279 seq_sep_trailing_allowed(token::COMMA),
1282 ex = expr_vec(~[first_expr] + remaining_exprs, mutbl);
1284 // Vector with one element.
1285 self.expect(&token::RBRACKET);
1286 ex = expr_vec(~[first_expr], mutbl);
1290 } else if self.eat_keyword(&~"__log") {
1292 self.expect(&token::LPAREN);
1293 let lvl = self.parse_expr();
1294 self.expect(&token::COMMA);
1295 let e = self.parse_expr();
1296 ex = expr_log(lvl, e);
1298 self.expect(&token::RPAREN);
1299 } else if self.eat_keyword(&~"return") {
1300 // RETURN expression
1301 if can_begin_expr(&*self.token) {
1302 let e = self.parse_expr();
1304 ex = expr_ret(Some(e));
1305 } else { ex = expr_ret(None); }
1306 } else if self.eat_keyword(&~"break") {
1308 if self.token_is_lifetime(&*self.token) {
1309 let lifetime = self.get_lifetime(&*self.token);
1311 ex = expr_break(Some(lifetime));
1313 ex = expr_break(None);
1316 } else if self.eat_keyword(&~"copy") {
1318 let e = self.parse_expr();
1321 } else if *self.token == token::MOD_SEP ||
1322 is_ident(&*self.token) && !self.is_keyword(&~"true") &&
1323 !self.is_keyword(&~"false") {
1324 let pth = self.parse_path_with_tps(true);
1326 // `!`, as an operator, is prefix, so we know this isn't that
1327 if *self.token == token::NOT {
1328 // MACRO INVOCATION expression
1331 token::LPAREN | token::LBRACE => {}
1332 _ => self.fatal(~"expected open delimiter")
1335 let ket = token::flip_delimiter(&*self.token);
1336 let tts = self.parse_unspanned_seq(
1340 |p| p.parse_token_tree()
1342 let hi = self.span.hi;
1344 return self.mk_mac_expr(lo, hi, mac_invoc_tt(pth, tts));
1345 } else if *self.token == token::LBRACE {
1346 // This might be a struct literal.
1347 if self.looking_at_record_literal() {
1348 // It's a struct literal.
1350 let mut fields = ~[];
1351 let mut base = None;
1353 fields.push(self.parse_field());
1354 while *self.token != token::RBRACE {
1355 if self.try_parse_obsolete_with() {
1359 self.expect(&token::COMMA);
1361 if self.eat(&token::DOTDOT) {
1362 base = Some(self.parse_expr());
1366 if *self.token == token::RBRACE {
1367 // Accept an optional trailing comma.
1370 fields.push(self.parse_field());
1374 self.expect(&token::RBRACE);
1375 ex = expr_struct(pth, fields, base);
1376 return self.mk_expr(lo, hi, ex);
1381 ex = expr_path(pth);
1383 // other literal expression
1384 let lit = self.parse_lit();
1386 ex = expr_lit(@lit);
1389 return self.mk_expr(lo, hi, ex);
1392 // parse a block or unsafe block
1393 fn parse_block_expr(
1396 blk_mode: blk_check_mode
1398 self.expect(&token::LBRACE);
1399 let blk = self.parse_block_tail(lo, blk_mode);
1400 return self.mk_expr(blk.span.lo, blk.span.hi, expr_block(blk));
1403 // parse a.b or a(13) or a[4] or just a
1404 fn parse_dot_or_call_expr(&self) -> @expr {
1405 let b = self.parse_bottom_expr();
1406 self.parse_dot_or_call_expr_with(b)
1409 fn parse_dot_or_call_expr_with(&self, e0: @expr) -> @expr {
1415 if self.eat(&token::DOT) {
1417 token::IDENT(i, _) => {
1420 let (_, tys) = if self.eat(&token::MOD_SEP) {
1421 self.expect(&token::LT);
1422 self.parse_generic_values_after_lt()
1424 (opt_vec::Empty, ~[])
1427 // expr.f() method call
1430 let es = self.parse_unspanned_seq(
1433 seq_sep_trailing_disallowed(token::COMMA),
1438 let nd = expr_method_call(e, i, tys, es, NoSugar);
1439 e = self.mk_expr(lo, hi, nd);
1442 e = self.mk_expr(lo, hi, expr_field(e, i, tys));
1446 _ => self.unexpected()
1450 if self.expr_is_complete(e) { break; }
1454 let es = self.parse_unspanned_seq(
1457 seq_sep_trailing_disallowed(token::COMMA),
1462 let nd = expr_call(e, es, NoSugar);
1463 e = self.mk_expr(lo, hi, nd);
1467 token::LBRACKET => {
1469 let ix = self.parse_expr();
1471 self.expect(&token::RBRACKET);
1472 e = self.mk_expr(lo, hi, expr_index(e, ix));
1481 // parse an optional separator followed by a kleene-style
1482 // repetition token (+ or *).
1483 fn parse_sep_and_zerok(&self) -> (Option<token::Token>, bool) {
1484 if *self.token == token::BINOP(token::STAR)
1485 || *self.token == token::BINOP(token::PLUS) {
1486 let zerok = *self.token == token::BINOP(token::STAR);
1490 let sep = copy *self.token;
1492 if *self.token == token::BINOP(token::STAR)
1493 || *self.token == token::BINOP(token::PLUS) {
1494 let zerok = *self.token == token::BINOP(token::STAR);
1498 self.fatal(~"expected `*` or `+`");
1503 // parse a single token tree from the input.
1504 fn parse_token_tree(&self) -> token_tree {
1505 maybe_whole!(deref self, nt_tt);
1507 // this is the fall-through for the 'match' below.
1508 // invariants: the current token is not a left-delimiter,
1509 // not an EOF, and not the desired right-delimiter (if
1510 // it were, parse_seq_to_before_end would have prevented
1511 // reaching this point.
1512 fn parse_non_delim_tt_tok(p: &Parser) -> token_tree {
1513 maybe_whole!(deref p, nt_tt);
1515 token::RPAREN | token::RBRACE | token::RBRACKET
1519 "incorrect close delimiter: `%s`",
1520 p.this_token_to_str()
1524 /* we ought to allow different depths of unquotation */
1525 token::DOLLAR if *p.quote_depth > 0u => {
1529 if *p.token == token::LPAREN {
1530 let seq = p.parse_seq(
1534 |p| p.parse_token_tree()
1536 let (s, z) = p.parse_sep_and_zerok();
1538 mk_sp(sp.lo ,p.span.hi),
1544 tt_nonterminal(sp, p.parse_ident())
1553 // turn the next token into a tt_tok:
1554 fn parse_any_tt_tok(p: &Parser) -> token_tree{
1555 let res = tt_tok(*p.span, copy *p.token);
1562 self.fatal(~"file ended with unbalanced delimiters");
1564 token::LPAREN | token::LBRACE | token::LBRACKET => {
1565 let close_delim = token::flip_delimiter(&*self.token);
1568 // the open delimiter:
1569 ~[parse_any_tt_tok(self)],
1571 self.parse_seq_to_before_end(
1574 |p| p.parse_token_tree()
1576 // the close delimiter:
1577 ~[parse_any_tt_tok(self)]
1582 _ => parse_non_delim_tt_tok(self)
1586 // parse a stream of tokens into a list of token_trees,
1588 fn parse_all_token_trees(&self) -> ~[token_tree] {
1590 while *self.token != token::EOF {
1591 tts.push(self.parse_token_tree());
1596 fn parse_matchers(&self) -> ~[matcher] {
1597 // unification of matchers and token_trees would vastly improve
1598 // the interpolation of matchers
1599 maybe_whole!(self, nt_matchers);
1600 let name_idx = @mut 0u;
1602 token::LBRACE | token::LPAREN | token::LBRACKET => {
1603 self.parse_matcher_subseq(
1606 // tjc: not sure why we need a copy
1607 &token::flip_delimiter(&*self.token)
1610 _ => self.fatal(~"expected open delimiter")
1615 // This goofy function is necessary to correctly match parens in matchers.
1616 // Otherwise, `$( ( )` would be a valid matcher, and `$( () )` would be
1617 // invalid. It's similar to common::parse_seq.
1618 fn parse_matcher_subseq(
1620 name_idx: @mut uint,
1624 let mut ret_val = ~[];
1625 let mut lparens = 0u;
1629 while *self.token != *ket || lparens > 0u {
1630 if *self.token == token::LPAREN { lparens += 1u; }
1631 if *self.token == token::RPAREN { lparens -= 1u; }
1632 ret_val.push(self.parse_matcher(name_idx));
1640 fn parse_matcher(&self, name_idx: @mut uint) -> matcher {
1641 let lo = self.span.lo;
1643 let m = if *self.token == token::DOLLAR {
1645 if *self.token == token::LPAREN {
1646 let name_idx_lo = *name_idx;
1647 let ms = self.parse_matcher_subseq(
1653 self.fatal(~"repetition body must be nonempty");
1655 let (sep, zerok) = self.parse_sep_and_zerok();
1656 match_seq(ms, sep, zerok, name_idx_lo, *name_idx)
1658 let bound_to = self.parse_ident();
1659 self.expect(&token::COLON);
1660 let nt_name = self.parse_ident();
1661 let m = match_nonterminal(bound_to, nt_name, *name_idx);
1666 let m = match_tok(copy *self.token);
1671 return spanned(lo, self.span.hi, m);
1674 // parse a prefix-operator expr
1675 fn parse_prefix_expr(&self) -> @expr {
1676 let lo = self.span.lo;
1683 let e = self.parse_prefix_expr();
1685 ex = expr_unary(not, e);
1687 token::BINOP(b) => {
1691 let e = self.parse_prefix_expr();
1693 ex = expr_unary(neg, e);
1697 let e = self.parse_prefix_expr();
1699 ex = expr_unary(deref, e);
1703 let _lt = self.parse_opt_lifetime();
1704 let m = self.parse_mutability();
1705 let e = self.parse_prefix_expr();
1707 // HACK: turn &[...] into a &-evec
1709 expr_vec(*) | expr_lit(@codemap::spanned {
1710 node: lit_str(_), span: _
1713 expr_vstore(e, expr_vstore_slice)
1715 expr_vec(*) if m == m_mutbl => {
1716 expr_vstore(e, expr_vstore_mut_slice)
1718 _ => expr_addr_of(m, e)
1721 _ => return self.parse_dot_or_call_expr()
1726 let m = self.parse_mutability();
1728 self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
1731 let e = self.parse_prefix_expr();
1733 // HACK: turn @[...] into a @-evec
1735 expr_vec(*) | expr_repeat(*) if m == m_mutbl =>
1736 expr_vstore(e, expr_vstore_mut_box),
1738 expr_lit(@codemap::spanned { node: lit_str(_), span: _}) |
1739 expr_repeat(*) if m == m_imm => expr_vstore(e, expr_vstore_box),
1740 _ => expr_unary(box(m), e)
1745 let m = self.parse_mutability();
1747 self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
1750 let e = self.parse_prefix_expr();
1752 // HACK: turn ~[...] into a ~-evec
1755 expr_lit(@codemap::spanned { node: lit_str(_), span: _}) |
1757 if m == m_imm => expr_vstore(e, expr_vstore_uniq),
1758 _ => expr_unary(uniq(m), e)
1761 _ => return self.parse_dot_or_call_expr()
1763 return self.mk_expr(lo, hi, ex);
1766 // parse an expression of binops
1767 fn parse_binops(&self) -> @expr {
1768 self.parse_more_binops(self.parse_prefix_expr(), 0)
1771 // parse an expression of binops of at least min_prec precedence
1772 fn parse_more_binops(&self, lhs: @expr, min_prec: uint) ->
1774 if self.expr_is_complete(lhs) { return lhs; }
1775 let peeked = copy *self.token;
1776 if peeked == token::BINOP(token::OR) &&
1777 (*self.restriction == RESTRICT_NO_BAR_OP ||
1778 *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) {
1780 } else if peeked == token::OROR &&
1781 *self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP {
1784 let cur_opt = token_to_binop(peeked);
1787 let cur_prec = operator_prec(cur_op);
1788 if cur_prec > min_prec {
1790 let expr = self.parse_prefix_expr();
1791 let rhs = self.parse_more_binops(expr, cur_prec);
1792 let bin = self.mk_expr(lhs.span.lo, rhs.span.hi,
1793 expr_binary(cur_op, lhs, rhs));
1794 self.parse_more_binops(bin, min_prec)
1800 if as_prec > min_prec && self.eat_keyword(&~"as") {
1801 let rhs = self.parse_ty(true);
1802 let _as = self.mk_expr(lhs.span.lo,
1804 expr_cast(lhs, rhs));
1805 self.parse_more_binops(_as, min_prec)
1814 // parse an assignment expression....
1815 // actually, this seems to be the main entry point for
1816 // parsing an arbitrary expression.
1817 fn parse_assign_expr(&self) -> @expr {
1818 let lo = self.span.lo;
1819 let lhs = self.parse_binops();
1823 let rhs = self.parse_expr();
1824 self.mk_expr(lo, rhs.span.hi, expr_assign(lhs, rhs))
1826 token::BINOPEQ(op) => {
1828 let rhs = self.parse_expr();
1831 token::PLUS => aop = add,
1832 token::MINUS => aop = subtract,
1833 token::STAR => aop = mul,
1834 token::SLASH => aop = div,
1835 token::PERCENT => aop = rem,
1836 token::CARET => aop = bitxor,
1837 token::AND => aop = bitand,
1838 token::OR => aop = bitor,
1839 token::SHL => aop = shl,
1840 token::SHR => aop = shr
1842 self.mk_expr(lo, rhs.span.hi,
1843 expr_assign_op(aop, lhs, rhs))
1846 self.obsolete(*self.span, ObsoleteBinaryMove);
1847 // Bogus value (but it's an error)
1851 self.mk_expr(lo, self.span.hi,
1856 let rhs = self.parse_expr();
1857 self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs))
1865 // parse an 'if' expression ('if' token already eaten)
1866 fn parse_if_expr(&self) -> @expr {
1867 let lo = self.last_span.lo;
1868 let cond = self.parse_expr();
1869 let thn = self.parse_block();
1870 let mut els: Option<@expr> = None;
1871 let mut hi = thn.span.hi;
1872 if self.eat_keyword(&~"else") {
1873 let elexpr = self.parse_else_expr();
1875 hi = elexpr.span.hi;
1877 self.mk_expr(lo, hi, expr_if(cond, thn, els))
1880 // `|args| { ... }` or `{ ...}` like in `do` expressions
1881 fn parse_lambda_block_expr(&self) -> @expr {
1882 self.parse_lambda_expr_(
1885 token::BINOP(token::OR) | token::OROR => {
1886 self.parse_fn_block_decl()
1889 // No argument list - `do foo {`
1903 let blk = self.parse_block();
1904 self.mk_expr(blk.span.lo, blk.span.hi, expr_block(blk))
1909 fn parse_lambda_expr(&self) -> @expr {
1910 self.parse_lambda_expr_(|| self.parse_fn_block_decl(),
1911 || self.parse_expr())
1914 // parse something of the form |args| expr
1915 // this is used both in parsing a lambda expr
1916 // and in parsing a block expr as e.g. in for...
1917 fn parse_lambda_expr_(
1919 parse_decl: &fn() -> fn_decl,
1920 parse_body: &fn() -> @expr
1922 let lo = self.last_span.lo;
1923 let decl = parse_decl();
1924 let body = parse_body();
1925 let fakeblock = ast::blk_ {
1932 let fakeblock = spanned(body.span.lo, body.span.hi,
1934 return self.mk_expr(lo, body.span.hi,
1935 expr_fn_block(decl, fakeblock));
1938 fn parse_else_expr(&self) -> @expr {
1939 if self.eat_keyword(&~"if") {
1940 return self.parse_if_expr();
1942 let blk = self.parse_block();
1943 return self.mk_expr(blk.span.lo, blk.span.hi, expr_block(blk));
1947 // parse a 'for' or 'do'.
1948 // the 'for' and 'do' expressions parse as calls, but look like
1949 // function calls followed by a closure expression.
1950 fn parse_sugary_call_expr(&self, keyword: ~str,
1952 ctor: &fn(v: @expr) -> expr_) -> @expr {
1953 let lo = self.last_span;
1954 // Parse the callee `foo` in
1957 // etc, or the portion of the call expression before the lambda in
1960 // for foo.bar(a) || {
1961 // Turn on the restriction to stop at | or || so we can parse
1962 // them as the lambda arguments
1963 let e = self.parse_expr_res(RESTRICT_NO_BAR_OR_DOUBLEBAR_OP);
1965 expr_call(f, args, NoSugar) => {
1966 let block = self.parse_lambda_block_expr();
1967 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
1969 let args = vec::append(args, ~[last_arg]);
1970 self.mk_expr(lo.lo, block.span.hi, expr_call(f, args, sugar))
1972 expr_method_call(f, i, tps, args, NoSugar) => {
1973 let block = self.parse_lambda_block_expr();
1974 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
1976 let args = vec::append(args, ~[last_arg]);
1977 self.mk_expr(lo.lo, block.span.hi,
1978 expr_method_call(f, i, tps, args, sugar))
1980 expr_field(f, i, tps) => {
1981 let block = self.parse_lambda_block_expr();
1982 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
1984 self.mk_expr(lo.lo, block.span.hi,
1985 expr_method_call(f, i, tps, ~[last_arg], sugar))
1987 expr_path(*) | expr_call(*) | expr_method_call(*) |
1989 let block = self.parse_lambda_block_expr();
1990 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
1992 self.mk_expr(lo.lo, last_arg.span.hi,
1993 expr_call(e, ~[last_arg], sugar))
1996 // There may be other types of expressions that can
1997 // represent the callee in `for` and `do` expressions
1998 // but they aren't represented by tests
1999 debug!("sugary call on %?", e.node);
2002 fmt!("`%s` must be followed by a block call", keyword));
2007 fn parse_while_expr(&self) -> @expr {
2008 let lo = self.last_span.lo;
2009 let cond = self.parse_expr();
2010 let body = self.parse_block();
2011 let hi = body.span.hi;
2012 return self.mk_expr(lo, hi, expr_while(cond, body));
2015 fn parse_loop_expr(&self, opt_ident: Option<ast::ident>) -> @expr {
2016 // loop headers look like 'loop {' or 'loop unsafe {'
2017 let is_loop_header =
2018 *self.token == token::LBRACE
2019 || (is_ident(&*self.token)
2020 && self.look_ahead(1) == token::LBRACE);
2023 // This is a loop body
2024 let lo = self.last_span.lo;
2025 let body = self.parse_block();
2026 let hi = body.span.hi;
2027 return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
2029 // This is a 'continue' expression
2030 if opt_ident.is_some() {
2031 self.span_err(*self.last_span,
2032 ~"a label may not be used with a `loop` \
2036 let lo = self.span.lo;
2037 let ex = if self.token_is_lifetime(&*self.token) {
2038 let lifetime = self.get_lifetime(&*self.token);
2040 expr_again(Some(lifetime))
2044 let hi = self.span.hi;
2045 return self.mk_expr(lo, hi, ex);
2049 // For distingishing between record literals and blocks
2050 fn looking_at_record_literal(&self) -> bool {
2051 let lookahead = self.look_ahead(1);
2052 *self.token == token::LBRACE &&
2053 (self.token_is_keyword(&~"mut", &lookahead) ||
2054 (is_plain_ident(&lookahead) &&
2055 self.look_ahead(2) == token::COLON))
2058 fn parse_match_expr(&self) -> @expr {
2059 let lo = self.last_span.lo;
2060 let discriminant = self.parse_expr();
2061 self.expect(&token::LBRACE);
2062 let mut arms: ~[arm] = ~[];
2063 while *self.token != token::RBRACE {
2064 let pats = self.parse_pats();
2065 let mut guard = None;
2066 if self.eat_keyword(&~"if") { guard = Some(self.parse_expr()); }
2067 self.expect(&token::FAT_ARROW);
2068 let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
2071 !classify::expr_is_simple_block(expr)
2072 && *self.token != token::RBRACE;
2075 self.expect(&token::COMMA);
2077 self.eat(&token::COMMA);
2080 let blk = codemap::spanned {
2091 arms.push(ast::arm { pats: pats, guard: guard, body: blk });
2093 let hi = self.span.hi;
2095 return self.mk_expr(lo, hi, expr_match(discriminant, arms));
2098 // parse an expression
2099 fn parse_expr(&self) -> @expr {
2100 return self.parse_expr_res(UNRESTRICTED);
2103 // parse an expression, subject to the given restriction
2104 fn parse_expr_res(&self, r: restriction) -> @expr {
2105 let old = *self.restriction;
2106 *self.restriction = r;
2107 let e = self.parse_assign_expr();
2108 *self.restriction = old;
2112 // parse the RHS of a local variable declaration (e.g. '= 14;')
2113 fn parse_initializer(&self) -> Option<@expr> {
2117 return Some(self.parse_expr());
2120 self.obsolete(*self.span, ObsoleteMoveInit);
2131 // parse patterns, separated by '|' s
2132 fn parse_pats(&self) -> ~[@pat] {
2135 pats.push(self.parse_pat(true));
2136 if *self.token == token::BINOP(token::OR) { self.bump(); }
2137 else { return pats; }
2141 fn parse_pat_vec_elements(
2144 ) -> (~[@pat], Option<@pat>, ~[@pat]) {
2145 let mut before = ~[];
2146 let mut slice = None;
2147 let mut after = ~[];
2148 let mut first = true;
2149 let mut before_slice = true;
2151 while *self.token != token::RBRACKET {
2152 if first { first = false; }
2153 else { self.expect(&token::COMMA); }
2155 let mut is_slice = false;
2157 if *self.token == token::DOTDOT {
2160 before_slice = false;
2164 let subpat = self.parse_pat(refutable);
2167 @ast::pat { node: pat_wild, _ } => (),
2168 @ast::pat { node: pat_ident(_, _, _), _ } => (),
2169 @ast::pat { span, _ } => self.span_fatal(
2170 span, ~"expected an identifier or `_`"
2173 slice = Some(subpat);
2176 before.push(subpat);
2183 (before, slice, after)
2186 // parse the fields of a struct-like pattern
2187 fn parse_pat_fields(&self, refutable: bool) -> (~[ast::field_pat], bool) {
2188 let mut fields = ~[];
2189 let mut etc = false;
2190 let mut first = true;
2191 while *self.token != token::RBRACE {
2192 if first { first = false; }
2193 else { self.expect(&token::COMMA); }
2195 if *self.token == token::UNDERSCORE {
2197 if *self.token != token::RBRACE {
2200 "expected `}`, found `%s`",
2201 self.this_token_to_str()
2209 let lo1 = self.last_span.lo;
2210 let fieldname = self.parse_ident();
2211 let hi1 = self.last_span.lo;
2212 let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
2215 if *self.token == token::COLON {
2217 subpat = self.parse_pat(refutable);
2219 subpat = @ast::pat {
2221 node: pat_ident(bind_infer, fieldpath, None),
2222 span: *self.last_span
2225 fields.push(ast::field_pat { ident: fieldname, pat: subpat });
2227 return (fields, etc);
2230 // parse a pattern. The 'refutable' argument
2231 // appears to control whether the binding_mode
2232 // 'bind_infer' or 'bind_by_copy' is used.
2233 fn parse_pat(&self, refutable: bool) -> @pat {
2234 maybe_whole!(self, nt_pat);
2236 let lo = self.span.lo;
2237 let mut hi = self.span.hi;
2241 token::UNDERSCORE => { self.bump(); pat = pat_wild; }
2245 let sub = self.parse_pat(refutable);
2247 // HACK: parse @"..." as a literal of a vstore @str
2248 pat = match sub.node {
2250 node: expr_lit(@codemap::spanned {
2256 callee_id: self.get_id(),
2257 node: expr_vstore(e, expr_vstore_box),
2258 span: mk_sp(lo, hi),
2268 let sub = self.parse_pat(refutable);
2270 // HACK: parse ~"..." as a literal of a vstore ~str
2271 pat = match sub.node {
2273 node: expr_lit(@codemap::spanned {
2279 callee_id: self.get_id(),
2280 node: expr_vstore(e, expr_vstore_uniq),
2281 span: mk_sp(lo, hi),
2288 token::BINOP(token::AND) => {
2290 let lo = self.span.lo;
2292 let sub = self.parse_pat(refutable);
2294 // HACK: parse &"..." as a literal of a borrowed str
2295 pat = match sub.node {
2297 node: expr_lit(@codemap::spanned {
2298 node: lit_str(_), span: _}), _
2302 callee_id: self.get_id(),
2303 node: expr_vstore(e, expr_vstore_slice),
2308 _ => pat_region(sub)
2313 let (_, _) = self.parse_pat_fields(refutable);
2316 self.obsolete(*self.span, ObsoleteRecordPattern);
2320 // parse (pat,pat,pat,...) as tuple
2322 if *self.token == token::RPAREN {
2325 let lit = @codemap::spanned {
2327 span: mk_sp(lo, hi)};
2328 let expr = self.mk_expr(lo, hi, expr_lit(lit));
2329 pat = pat_lit(expr);
2331 let mut fields = ~[self.parse_pat(refutable)];
2332 if self.look_ahead(1) != token::RPAREN {
2333 while *self.token == token::COMMA {
2335 fields.push(self.parse_pat(refutable));
2338 if fields.len() == 1 { self.expect(&token::COMMA); }
2340 self.expect(&token::RPAREN);
2341 pat = pat_tup(fields);
2344 token::LBRACKET => {
2345 // parse [pat,pat,...] as vector pattern
2347 let (before, slice, after) =
2348 self.parse_pat_vec_elements(refutable);
2350 self.expect(&token::RBRACKET);
2351 pat = ast::pat_vec(before, slice, after);
2354 if !is_ident_or_path(&tok)
2355 || self.is_keyword(&~"true")
2356 || self.is_keyword(&~"false")
2358 // parse an expression pattern or exp .. exp
2359 let val = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2360 if self.eat(&token::DOTDOT) {
2361 let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
2362 pat = pat_range(val, end);
2366 } else if self.eat_keyword(&~"ref") {
2368 let mutbl = self.parse_mutability();
2369 pat = self.parse_pat_ident(refutable, bind_by_ref(mutbl));
2370 } else if self.eat_keyword(&~"copy") {
2372 pat = self.parse_pat_ident(refutable, bind_by_copy);
2374 // XXX---refutable match bindings should work same as let
2376 if refutable {bind_infer} else {bind_by_copy};
2378 let can_be_enum_or_struct;
2379 match self.look_ahead(1) {
2380 token::LPAREN | token::LBRACKET | token::LT |
2381 token::LBRACE | token::MOD_SEP =>
2382 can_be_enum_or_struct = true,
2384 can_be_enum_or_struct = false
2387 if is_plain_ident(&*self.token) && !can_be_enum_or_struct {
2388 let name = self.parse_path_without_tps();
2390 if self.eat(&token::AT) {
2392 sub = Some(self.parse_pat(refutable));
2397 pat = pat_ident(binding_mode, name, sub);
2399 // parse an enum pat
2400 let enum_path = self.parse_path_with_tps(true);
2405 self.parse_pat_fields(refutable);
2407 pat = pat_struct(enum_path, fields, etc);
2410 let mut args: ~[@pat] = ~[];
2412 token::LPAREN => match self.look_ahead(1u) {
2413 token::BINOP(token::STAR) => {
2414 // This is a "top constructor only" pat
2415 self.bump(); self.bump();
2416 self.expect(&token::RPAREN);
2417 pat = pat_enum(enum_path, None);
2420 args = self.parse_unspanned_seq(
2423 seq_sep_trailing_disallowed(
2426 |p| p.parse_pat(refutable)
2428 pat = pat_enum(enum_path, Some(args));
2432 if vec::len(enum_path.idents)==1u {
2433 // it could still be either an enum
2434 // or an identifier pattern, resolve
2435 // will sort it out:
2436 pat = pat_ident(binding_mode,
2440 pat = pat_enum(enum_path, Some(args));
2451 @ast::pat { id: self.get_id(), node: pat, span: mk_sp(lo, hi) }
2454 // used by the copy foo and ref foo patterns to give a good
2455 // error message when parsing mistakes like ref foo(a,b)
2456 fn parse_pat_ident(&self,
2458 binding_mode: ast::binding_mode)
2460 if !is_plain_ident(&*self.token) {
2461 self.span_fatal(*self.last_span,
2462 ~"expected identifier, found path");
2464 // why a path here, and not just an identifier?
2465 let name = self.parse_path_without_tps();
2466 let sub = if self.eat(&token::AT) {
2467 Some(self.parse_pat(refutable))
2472 // just to be friendly, if they write something like
2474 // we end up here with ( as the current token. This shortly
2475 // leads to a parse error. Note that if there is no explicit
2476 // binding mode then we do not end up here, because the lookahead
2477 // will direct us over to parse_enum_variant()
2478 if *self.token == token::LPAREN {
2481 ~"expected identifier, found enum pattern");
2484 pat_ident(binding_mode, name, sub)
2487 // parse a local variable declaration
2488 fn parse_local(&self, is_mutbl: bool) -> @local {
2489 let lo = self.span.lo;
2490 let pat = self.parse_pat(false);
2494 span: mk_sp(lo, lo),
2496 if self.eat(&token::COLON) { ty = self.parse_ty(false); }
2497 let init = self.parse_initializer();
2511 // parse a "let" stmt
2512 fn parse_let(&self) -> @decl {
2513 let is_mutbl = self.eat_keyword(&~"mut");
2514 let lo = self.span.lo;
2515 let mut locals = ~[self.parse_local(is_mutbl)];
2516 while self.eat(&token::COMMA) {
2517 locals.push(self.parse_local(is_mutbl));
2519 return @spanned(lo, self.last_span.hi, decl_local(locals));
2522 // parse a structure field
2523 fn parse_name_and_ty(&self,
2525 attrs: ~[attribute]) -> @struct_field {
2526 let mut is_mutbl = struct_immutable;
2527 let lo = self.span.lo;
2528 if self.eat_keyword(&~"mut") {
2529 is_mutbl = struct_mutable;
2531 if !is_plain_ident(&*self.token) {
2532 self.fatal(~"expected ident");
2534 let name = self.parse_ident();
2535 self.expect(&token::COLON);
2536 let ty = self.parse_ty(false);
2537 @spanned(lo, self.last_span.hi, ast::struct_field_ {
2538 kind: named_field(name, is_mutbl, pr),
2545 // parse a statement. may include decl
2546 fn parse_stmt(&self, first_item_attrs: ~[attribute]) -> @stmt {
2547 maybe_whole!(self, nt_stmt);
2549 fn check_expected_item(p: &Parser, current_attrs: &[attribute]) {
2550 // If we have attributes then we should have an item
2551 if !current_attrs.is_empty() {
2552 p.fatal(~"expected item after attrs");
2556 let lo = self.span.lo;
2557 if self.is_keyword(&~"let") {
2558 check_expected_item(self, first_item_attrs);
2559 self.expect_keyword(&~"let");
2560 let decl = self.parse_let();
2561 return @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id()));
2562 } else if is_ident(&*self.token)
2563 && !self.is_any_keyword(© *self.token)
2564 && self.look_ahead(1) == token::NOT {
2565 // parse a macro invocation. Looks like there's serious
2566 // overlap here; if this clause doesn't catch it (and it
2567 // won't, for brace-delimited macros) it will fall through
2568 // to the macro clause of parse_item_or_view_item. This
2569 // could use some cleanup, it appears to me.
2571 check_expected_item(self, first_item_attrs);
2573 // Potential trouble: if we allow macros with paths instead of
2574 // idents, we'd need to look ahead past the whole path here...
2575 let pth = self.parse_path_without_tps();
2578 let id = if *self.token == token::LPAREN {
2579 token::special_idents::invalid // no special identifier
2584 let tts = self.parse_unspanned_seq(
2588 |p| p.parse_token_tree()
2590 let hi = self.span.hi;
2592 if id == token::special_idents::invalid {
2593 return @spanned(lo, hi, stmt_mac(
2594 spanned(lo, hi, mac_invoc_tt(pth, tts)), false));
2596 // if it has a special ident, it's definitely an item
2597 return @spanned(lo, hi, stmt_decl(
2598 @spanned(lo, hi, decl_item(
2600 lo, hi, id /*id is good here*/,
2601 item_mac(spanned(lo, hi, mac_invoc_tt(pth, tts))),
2602 inherited, ~[/*no attrs*/]))),
2607 let item_attrs = vec::append(first_item_attrs,
2608 self.parse_outer_attributes());
2610 match self.parse_item_or_view_item(/*bad*/ copy item_attrs,
2614 let decl = @spanned(lo, hi, decl_item(i));
2615 return @spanned(lo, hi, stmt_decl(decl, self.get_id()));
2617 iovi_view_item(vi) => {
2618 self.span_fatal(vi.span, ~"view items must be declared at \
2619 the top of the block");
2621 iovi_foreign_item(_) => {
2622 self.fatal(~"foreign items are not allowed here");
2624 iovi_none() => { /* fallthrough */ }
2627 check_expected_item(self, item_attrs);
2629 // Remainder are line-expr stmts.
2630 let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
2631 return @spanned(lo, e.span.hi, stmt_expr(e, self.get_id()));
2635 // is this expression a successfully-parsed statement?
2636 fn expr_is_complete(&self, e: @expr) -> bool {
2637 return *self.restriction == RESTRICT_STMT_EXPR &&
2638 !classify::expr_requires_semi_to_be_stmt(e);
2641 // parse a block. No inner attrs are allowed.
2642 fn parse_block(&self) -> blk {
2643 maybe_whole!(self, nt_block);
2645 let lo = self.span.lo;
2646 if self.eat_keyword(&~"unsafe") {
2647 self.obsolete(copy *self.span, ObsoleteUnsafeBlock);
2649 self.expect(&token::LBRACE);
2651 return self.parse_block_tail_(lo, default_blk, ~[]);
2654 // parse a block. Inner attrs are allowed.
2655 fn parse_inner_attrs_and_block(&self)
2656 -> (~[attribute], blk) {
2658 maybe_whole!(pair_empty self, nt_block);
2660 let lo = self.span.lo;
2661 if self.eat_keyword(&~"unsafe") {
2662 self.obsolete(copy *self.span, ObsoleteUnsafeBlock);
2664 self.expect(&token::LBRACE);
2665 let (inner, next) = self.parse_inner_attrs_and_next();
2667 (inner, self.parse_block_tail_(lo, default_blk, next))
2670 // Precondition: already parsed the '{' or '#{'
2671 // I guess that also means "already parsed the 'impure'" if
2672 // necessary, and this should take a qualifier.
2673 // some blocks start with "#{"...
2674 fn parse_block_tail(&self, lo: BytePos, s: blk_check_mode) -> blk {
2675 self.parse_block_tail_(lo, s, ~[])
2678 // parse the rest of a block expression or function body
2679 fn parse_block_tail_(&self, lo: BytePos, s: blk_check_mode,
2680 first_item_attrs: ~[attribute]) -> blk {
2681 let mut stmts = ~[];
2682 let mut expr = None;
2684 let ParsedItemsAndViewItems {
2685 attrs_remaining: attrs_remaining,
2686 view_items: view_items,
2689 } = self.parse_items_and_view_items(first_item_attrs,
2692 for items.each |item| {
2693 let decl = @spanned(item.span.lo, item.span.hi, decl_item(*item));
2694 stmts.push(@spanned(item.span.lo, item.span.hi,
2695 stmt_decl(decl, self.get_id())));
2698 let mut initial_attrs = attrs_remaining;
2700 if *self.token == token::RBRACE && !vec::is_empty(initial_attrs) {
2701 self.fatal(~"expected item");
2704 while *self.token != token::RBRACE {
2707 self.bump(); // empty
2710 let stmt = self.parse_stmt(initial_attrs);
2711 initial_attrs = ~[];
2713 stmt_expr(e, stmt_id) => {
2714 // Expression without semicolon
2718 stmts.push(@codemap::spanned {
2719 node: stmt_semi(e, stmt_id),
2726 if classify::stmt_ends_with_semi(stmt) {
2729 "expected `;` or `}` after \
2730 expression but found `%s`",
2731 self.token_to_str(&t)
2740 stmt_mac(ref m, _) => {
2741 // Statement macro; might be an expr
2745 stmts.push(@codemap::spanned {
2746 node: stmt_mac(copy *m, true),
2750 // if a block ends in `m!(arg)` without
2751 // a `;`, it must be an expr
2753 self.mk_mac_expr(stmt.span.lo,
2757 _ => { stmts.push(stmt); }
2761 _ => { // All other kinds of statements:
2764 if classify::stmt_ends_with_semi(stmt) {
2765 self.expect(&token::SEMI);
2772 let hi = self.span.hi;
2774 let bloc = ast::blk_ {
2775 view_items: view_items,
2781 spanned(lo, hi, bloc)
2784 fn mk_ty_path(&self, i: ident) -> @Ty {
2788 ident_to_path(*self.last_span, i),
2790 span: *self.last_span,
2794 fn parse_optional_purity(&self) -> ast::purity {
2795 if self.eat_keyword(&~"pure") {
2796 self.obsolete(*self.last_span, ObsoletePurity);
2798 } else if self.eat_keyword(&~"unsafe") {
2805 fn parse_optional_onceness(&self) -> ast::Onceness {
2806 if self.eat_keyword(&~"once") { ast::Once } else { ast::Many }
2809 // matches optbounds = ( ( : ( boundseq )? )? )
2810 // where boundseq = ( bound + boundseq ) | bound
2811 // and bound = 'static | ty
2812 fn parse_optional_ty_param_bounds(&self) -> @OptVec<TyParamBound> {
2813 if !self.eat(&token::COLON) {
2814 return @opt_vec::Empty;
2817 let mut result = opt_vec::Empty;
2820 token::LIFETIME(lifetime) => {
2821 if str::eq_slice(*self.id_to_str(lifetime), "static") {
2822 result.push(RegionTyParamBound);
2824 self.span_err(*self.span,
2825 ~"`'static` is the only permissible \
2826 region bound here");
2830 token::MOD_SEP | token::IDENT(*) => {
2831 let obsolete_bound = match *self.token {
2832 token::MOD_SEP => false,
2833 token::IDENT(copy sid, _) => {
2834 match *self.id_to_str(sid) {
2841 ObsoleteLowerCaseKindBounds);
2851 if !obsolete_bound {
2852 let tref = self.parse_trait_ref();
2853 result.push(TraitTyParamBound(tref));
2859 if self.eat(&token::BINOP(token::PLUS)) {
2863 if is_ident_or_path(&*self.token) {
2864 self.obsolete(*self.span,
2865 ObsoleteTraitBoundSeparator);
2872 // matches typaram = IDENT optbounds
2873 fn parse_ty_param(&self) -> TyParam {
2874 let ident = self.parse_ident();
2875 let bounds = self.parse_optional_ty_param_bounds();
2876 ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds }
2879 // parse a set of optional generic type parameter declarations
2880 // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
2881 // | ( < lifetimes , typaramseq ( , )? > )
2882 // where typaramseq = ( typaram ) | ( typaram , typaramseq )
2883 fn parse_generics(&self) -> ast::Generics {
2884 if self.eat(&token::LT) {
2885 let lifetimes = self.parse_lifetimes();
2886 let ty_params = self.parse_seq_to_gt(
2888 |p| p.parse_ty_param());
2889 ast::Generics { lifetimes: lifetimes, ty_params: ty_params }
2891 ast_util::empty_generics()
2895 // parse a generic use site
2896 fn parse_generic_values(
2897 &self) -> (OptVec<ast::Lifetime>, ~[@Ty])
2899 if !self.eat(&token::LT) {
2900 (opt_vec::Empty, ~[])
2902 self.parse_generic_values_after_lt()
2906 fn parse_generic_values_after_lt(
2907 &self) -> (OptVec<ast::Lifetime>, ~[@Ty])
2909 let lifetimes = self.parse_lifetimes();
2910 let result = self.parse_seq_to_gt(
2912 |p| p.parse_ty(false));
2913 (lifetimes, opt_vec::take_vec(result))
2916 // parse the argument list and result type of a function declaration
2917 fn parse_fn_decl(&self)
2920 let args_or_capture_items: ~[arg_or_capture_item] =
2921 self.parse_unspanned_seq(
2924 seq_sep_trailing_disallowed(token::COMMA),
2928 let inputs = either::lefts(args_or_capture_items);
2930 let (ret_style, ret_ty) = self.parse_ret_ty();
2938 fn is_self_ident(&self) -> bool {
2940 token::IDENT(id, false) if id == special_idents::self_
2946 fn expect_self_ident(&self) {
2947 if !self.is_self_ident() {
2950 "expected `self` but found `%s`",
2951 self.this_token_to_str()
2958 // parse the argument list and result type of a function
2959 // that may have a self type.
2960 fn parse_fn_decl_with_self(
2963 &fn(&Parser) -> arg_or_capture_item
2964 ) -> (self_ty, fn_decl) {
2965 fn maybe_parse_self_ty(
2966 cnstr: &fn(v: mutability) -> ast::self_ty_,
2968 ) -> ast::self_ty_ {
2969 // We need to make sure it isn't a mode or a type
2970 if p.token_is_keyword(&~"self", &p.look_ahead(1)) ||
2971 ((p.token_is_keyword(&~"const", &p.look_ahead(1)) ||
2972 p.token_is_keyword(&~"mut", &p.look_ahead(1))) &&
2973 p.token_is_keyword(&~"self", &p.look_ahead(2))) {
2976 let mutability = p.parse_mutability();
2977 p.expect_self_ident();
2984 fn maybe_parse_borrowed_self_ty(
2986 ) -> ast::self_ty_ {
2987 // The following things are possible to see here:
2992 // fn(&'lt mut self)
2994 // We already know that the current token is `&`.
2997 self.token_is_keyword(&~"self", &self.look_ahead(1)))
3000 self.expect_self_ident();
3001 sty_region(None, m_imm)
3003 self.token_is_mutability(&self.look_ahead(1)) &&
3004 self.token_is_keyword(&~"self", &self.look_ahead(2)))
3007 let mutability = self.parse_mutability();
3008 self.expect_self_ident();
3009 sty_region(None, mutability)
3011 self.token_is_lifetime(&self.look_ahead(1)) &&
3012 self.token_is_keyword(&~"self", &self.look_ahead(2)))
3015 let lifetime = @self.parse_lifetime();
3016 self.expect_self_ident();
3017 sty_region(Some(lifetime), m_imm)
3019 self.token_is_lifetime(&self.look_ahead(1)) &&
3020 self.token_is_mutability(&self.look_ahead(2)) &&
3021 self.token_is_keyword(&~"self", &self.look_ahead(3)))
3024 let lifetime = @self.parse_lifetime();
3025 let mutability = self.parse_mutability();
3026 self.expect_self_ident();
3027 sty_region(Some(lifetime), mutability)
3033 self.expect(&token::LPAREN);
3035 // A bit of complexity and lookahead is needed here in order to to be
3036 // backwards compatible.
3037 let lo = self.span.lo;
3038 let self_ty = match *self.token {
3039 token::BINOP(token::AND) => {
3040 maybe_parse_borrowed_self_ty(self)
3043 maybe_parse_self_ty(sty_box, self)
3046 maybe_parse_self_ty(sty_uniq, self)
3048 token::IDENT(*) if self.is_self_ident() => {
3057 // If we parsed a self type, expect a comma before the argument list.
3058 let args_or_capture_items;
3059 if self_ty != sty_static {
3063 let sep = seq_sep_trailing_disallowed(token::COMMA);
3064 args_or_capture_items = self.parse_seq_to_before_end(
3071 args_or_capture_items = ~[];
3076 "expected `,` or `)`, found `%s`",
3077 self.this_token_to_str()
3083 let sep = seq_sep_trailing_disallowed(token::COMMA);
3084 args_or_capture_items = self.parse_seq_to_before_end(
3091 self.expect(&token::RPAREN);
3093 let hi = self.span.hi;
3095 let inputs = either::lefts(args_or_capture_items);
3096 let (ret_style, ret_ty) = self.parse_ret_ty();
3098 let fn_decl = ast::fn_decl {
3104 (spanned(lo, hi, self_ty), fn_decl)
3107 // parse the |arg, arg| header on a lambda
3108 fn parse_fn_block_decl(&self) -> fn_decl {
3109 let inputs_captures = {
3110 if self.eat(&token::OROR) {
3113 self.parse_unspanned_seq(
3114 &token::BINOP(token::OR),
3115 &token::BINOP(token::OR),
3116 seq_sep_trailing_disallowed(token::COMMA),
3117 |p| p.parse_fn_block_arg()
3121 let output = if self.eat(&token::RARROW) {
3122 self.parse_ty(false)
3124 @Ty { id: self.get_id(), node: ty_infer, span: *self.span }
3128 inputs: either::lefts(inputs_captures),
3134 // parse the name and optional generic types of a function header.
3135 fn parse_fn_header(&self) -> (ident, ast::Generics) {
3136 let id = self.parse_ident();
3137 let generics = self.parse_generics();
3141 fn mk_item(&self, lo: BytePos, hi: BytePos, ident: ident,
3142 node: item_, vis: visibility,
3143 attrs: ~[attribute]) -> @item {
3144 @ast::item { ident: ident,
3149 span: mk_sp(lo, hi) }
3152 // parse an item-position function declaration.
3153 fn parse_item_fn(&self, purity: purity, abis: AbiSet) -> item_info {
3154 let (ident, generics) = self.parse_fn_header();
3155 let decl = self.parse_fn_decl();
3156 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3158 item_fn(decl, purity, abis, generics, body),
3162 // parse a method in a trait impl
3163 fn parse_method(&self) -> @method {
3164 let attrs = self.parse_outer_attributes();
3165 let lo = self.span.lo;
3167 let visa = self.parse_visibility();
3168 let pur = self.parse_fn_purity();
3169 let ident = self.parse_ident();
3170 let generics = self.parse_generics();
3171 let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| {
3175 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
3176 let hi = body.span.hi;
3177 let attrs = vec::append(attrs, inner_attrs);
3187 span: mk_sp(lo, hi),
3188 self_id: self.get_id(),
3193 // parse trait Foo { ... }
3194 fn parse_item_trait(&self) -> item_info {
3195 let ident = self.parse_ident();
3196 self.parse_region_param();
3197 let tps = self.parse_generics();
3199 // Parse traits, if necessary.
3201 if *self.token == token::COLON {
3203 traits = self.parse_trait_ref_list(&token::LBRACE);
3208 let meths = self.parse_trait_methods();
3209 (ident, item_trait(tps, traits, meths), None)
3212 // Parses two variants (with the region/type params always optional):
3213 // impl<T> Foo { ... }
3214 // impl<T> ToStr for ~[T] { ... }
3215 fn parse_item_impl(&self, visibility: ast::visibility) -> item_info {
3216 // First, parse type parameters if necessary.
3217 let generics = self.parse_generics();
3219 // This is a new-style impl declaration.
3221 let ident = special_idents::clownshoes_extensions;
3223 // Special case: if the next identifier that follows is '(', don't
3224 // allow this to be parsed as a trait.
3225 let could_be_trait = *self.token != token::LPAREN;
3228 let mut ty = self.parse_ty(false);
3230 // Parse traits, if necessary.
3231 let opt_trait = if could_be_trait && self.eat_keyword(&~"for") {
3232 // New-style trait. Reinterpret the type as a trait.
3233 let opt_trait_ref = match ty.node {
3234 ty_path(path, node_id) => {
3241 self.span_err(*self.span, ~"not a trait");
3246 ty = self.parse_ty(false);
3248 } else if self.eat(&token::COLON) {
3249 self.obsolete(copy *self.span, ObsoleteImplSyntax);
3250 Some(self.parse_trait_ref())
3255 // Do not allow visibility to be specified in `impl...for...`. It is
3257 if opt_trait.is_some() && visibility != ast::inherited {
3258 self.obsolete(*self.span, ObsoleteTraitImplVisibility);
3261 let mut meths = ~[];
3262 if !self.eat(&token::SEMI) {
3263 self.expect(&token::LBRACE);
3264 while !self.eat(&token::RBRACE) {
3265 meths.push(self.parse_method());
3269 (ident, item_impl(generics, opt_trait, ty, meths), None)
3272 // parse a::B<~str,int>
3273 fn parse_trait_ref(&self) -> @trait_ref {
3275 path: self.parse_path_with_tps(false),
3276 ref_id: self.get_id(),
3280 // parse B + C<~str,int> + D
3281 fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] {
3282 self.parse_seq_to_before_end(
3284 seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
3285 |p| p.parse_trait_ref()
3289 // parse struct Foo { ... }
3290 fn parse_item_struct(&self) -> item_info {
3291 let class_name = self.parse_ident();
3292 self.parse_region_param();
3293 let generics = self.parse_generics();
3294 if self.eat(&token::COLON) {
3295 self.obsolete(copy *self.span, ObsoleteClassTraits);
3296 let _ = self.parse_trait_ref_list(&token::LBRACE);
3299 let mut fields: ~[@struct_field];
3302 if self.eat(&token::LBRACE) {
3303 // It's a record-like struct.
3304 is_tuple_like = false;
3306 while *self.token != token::RBRACE {
3307 for self.parse_struct_decl_field().each |struct_field| {
3308 fields.push(*struct_field)
3311 if fields.len() == 0 {
3312 self.fatal(fmt!("Unit-like struct should be written as: struct %s;",
3313 *self.interner.get(class_name)));
3316 } else if *self.token == token::LPAREN {
3317 // It's a tuple-like struct.
3318 is_tuple_like = true;
3319 fields = do self.parse_unspanned_seq(
3322 seq_sep_trailing_allowed(token::COMMA)
3324 let attrs = self.parse_outer_attributes();
3326 let struct_field_ = ast::struct_field_ {
3327 kind: unnamed_field,
3329 ty: p.parse_ty(false),
3332 @spanned(lo, p.span.hi, struct_field_)
3334 self.expect(&token::SEMI);
3335 } else if self.eat(&token::SEMI) {
3336 // It's a unit-like struct.
3337 is_tuple_like = true;
3342 "expected `{`, `(`, or `;` after struct name \
3344 self.this_token_to_str()
3349 let _ = self.get_id(); // XXX: Workaround for crazy bug.
3350 let new_id = self.get_id();
3352 item_struct(@ast::struct_def {
3354 ctor_id: if is_tuple_like { Some(new_id) } else { None }
3359 fn token_is_pound_or_doc_comment(&self, tok: token::Token) -> bool {
3361 token::POUND | token::DOC_COMMENT(_) => true,
3366 // parse a structure field declaration
3367 fn parse_single_struct_field(&self,
3369 attrs: ~[attribute]) -> @struct_field {
3370 if self.eat_obsolete_ident("let") {
3371 self.obsolete(*self.last_span, ObsoleteLet);
3374 let a_var = self.parse_name_and_ty(vis, attrs);
3377 self.obsolete(copy *self.span, ObsoleteFieldTerminator);
3388 "expected `,`, or '}' but found `%s`",
3389 self.this_token_to_str()
3397 // parse an element of a struct definition
3398 fn parse_struct_decl_field(&self) -> ~[@struct_field] {
3400 let attrs = self.parse_outer_attributes();
3402 if self.try_parse_obsolete_priv_section(attrs) {
3406 if self.eat_keyword(&~"priv") {
3407 return ~[self.parse_single_struct_field(private, attrs)]
3410 if self.eat_keyword(&~"pub") {
3411 return ~[self.parse_single_struct_field(public, attrs)];
3414 if self.try_parse_obsolete_struct_ctor() {
3418 return ~[self.parse_single_struct_field(inherited, attrs)];
3421 // parse visiility: PUB, PRIV, or nothing
3422 fn parse_visibility(&self) -> visibility {
3423 if self.eat_keyword(&~"pub") { public }
3424 else if self.eat_keyword(&~"priv") { private }
3428 fn parse_staticness(&self) -> bool {
3429 if self.eat_keyword(&~"static") {
3430 self.obsolete(*self.last_span, ObsoleteStaticMethod);
3437 // given a termination token and a vector of already-parsed
3438 // attributes (of length 0 or 1), parse all of the items in a module
3439 fn parse_mod_items(&self, term: token::Token,
3440 first_item_attrs: ~[attribute]) -> _mod {
3441 // parse all of the items up to closing or an attribute.
3442 // view items are legal here.
3443 let ParsedItemsAndViewItems {
3444 attrs_remaining: attrs_remaining,
3445 view_items: view_items,
3446 items: starting_items,
3448 } = self.parse_items_and_view_items(first_item_attrs,
3450 let mut items: ~[@item] = starting_items;
3451 let attrs_remaining_len = attrs_remaining.len();
3453 // don't think this other loop is even necessary....
3455 let mut first = true;
3456 while *self.token != term {
3457 let mut attrs = self.parse_outer_attributes();
3459 attrs = attrs_remaining + attrs;
3462 debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
3464 match self.parse_item_or_view_item(
3466 true // macros allowed
3468 iovi_item(item) => items.push(item),
3469 iovi_view_item(view_item) => {
3470 self.span_fatal(view_item.span, ~"view items must be \
3471 declared at the top of the \
3477 "expected item but found `%s`",
3478 self.this_token_to_str()
3483 debug!("parse_mod_items: attrs=%?", attrs);
3486 if first && attrs_remaining_len > 0u {
3487 // We parsed attributes for the first item but didn't find it
3488 self.fatal(~"expected item");
3491 ast::_mod { view_items: view_items, items: items }
3494 fn parse_item_const(&self) -> item_info {
3495 let id = self.parse_ident();
3496 self.expect(&token::COLON);
3497 let ty = self.parse_ty(false);
3498 self.expect(&token::EQ);
3499 let e = self.parse_expr();
3500 self.expect(&token::SEMI);
3501 (id, item_const(ty, e), None)
3504 // parse a mod { ...} item
3505 fn parse_item_mod(&self, outer_attrs: ~[ast::attribute]) -> item_info {
3506 let id_span = *self.span;
3507 let id = self.parse_ident();
3508 let info_ = if *self.token == token::SEMI {
3510 // This mod is in an external file. Let's go get it!
3511 let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span);
3512 (id, m, Some(attrs))
3514 self.push_mod_path(id, outer_attrs);
3515 self.expect(&token::LBRACE);
3516 let (inner, next) = self.parse_inner_attrs_and_next();
3517 let m = self.parse_mod_items(token::RBRACE, next);
3518 self.expect(&token::RBRACE);
3519 self.pop_mod_path();
3520 (id, item_mod(m), Some(inner))
3523 // XXX: Transitionary hack to do the template work inside core
3524 // (int-template, iter-trait). If there's a 'merge' attribute
3525 // on the mod, then we'll go and suck in another file and merge
3527 match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") {
3530 self.sess.cm.span_to_filename(*self.span));
3531 let prefix = prefix.dir_path();
3532 let path = Path(copy *path);
3533 let (new_mod_item, new_attrs) = self.eval_src_mod_from_path(
3534 prefix, path, ~[], id_span);
3536 let (main_id, main_mod_item, main_attrs) = info_;
3537 let main_attrs = main_attrs.get();
3539 let (main_mod, new_mod) =
3540 match (main_mod_item, new_mod_item) {
3541 (item_mod(m), item_mod(n)) => (m, n),
3542 _ => self.bug(~"parsed mod item should be mod")
3544 let merged_mod = ast::_mod {
3545 view_items: main_mod.view_items + new_mod.view_items,
3546 items: main_mod.items + new_mod.items
3549 let merged_attrs = main_attrs + new_attrs;
3550 (main_id, item_mod(merged_mod), Some(merged_attrs))
3556 fn push_mod_path(&self, id: ident, attrs: ~[ast::attribute]) {
3557 let default_path = self.sess.interner.get(id);
3558 let file_path = match ::attr::first_attr_value_str_by_name(
3562 None => copy *default_path
3564 self.mod_path_stack.push(file_path)
3567 fn pop_mod_path(&self) {
3568 self.mod_path_stack.pop();
3571 // read a module from a source file.
3572 fn eval_src_mod(&self, id: ast::ident,
3573 outer_attrs: ~[ast::attribute],
3574 id_sp: span) -> (ast::item_, ~[ast::attribute]) {
3576 let prefix = Path(self.sess.cm.span_to_filename(*self.span));
3577 let prefix = prefix.dir_path();
3578 let mod_path_stack = &*self.mod_path_stack;
3579 let mod_path = Path(".").push_many(*mod_path_stack);
3580 let default_path = *self.sess.interner.get(id) + ~".rs";
3581 let file_path = match ::attr::first_attr_value_str_by_name(
3582 outer_attrs, ~"path") {
3584 let path = Path(copy *d);
3585 if !path.is_absolute {
3586 mod_path.push(copy *d)
3591 None => mod_path.push(default_path)
3594 self.eval_src_mod_from_path(prefix, file_path,
3598 fn eval_src_mod_from_path(&self, prefix: Path, path: Path,
3599 outer_attrs: ~[ast::attribute],
3601 ) -> (ast::item_, ~[ast::attribute]) {
3603 let full_path = if path.is_absolute {
3606 prefix.push_many(path.components)
3608 let full_path = full_path.normalize();
3610 new_sub_parser_from_file(self.sess, copy self.cfg,
3612 let (inner, next) = p0.parse_inner_attrs_and_next();
3613 let mod_attrs = vec::append(
3614 /*bad*/ copy outer_attrs,
3617 let first_item_outer_attrs = next;
3618 let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
3619 return (ast::item_mod(m0), mod_attrs);
3621 fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
3622 match ::attr::first_attr_value_str_by_name(attrs, ~"path") {
3629 // parse a function declaration from a foreign module
3630 fn parse_item_foreign_fn(&self, attrs: ~[attribute]) -> @foreign_item {
3631 let lo = self.span.lo;
3632 let vis = self.parse_visibility();
3633 let purity = self.parse_fn_purity();
3634 let (ident, generics) = self.parse_fn_header();
3635 let decl = self.parse_fn_decl();
3636 let hi = self.span.hi;
3637 self.expect(&token::SEMI);
3638 @ast::foreign_item { ident: ident,
3640 node: foreign_item_fn(decl, purity, generics),
3642 span: mk_sp(lo, hi),
3646 // parse a const definition from a foreign module
3647 fn parse_item_foreign_const(&self, vis: ast::visibility,
3648 attrs: ~[attribute]) -> @foreign_item {
3649 let lo = self.span.lo;
3651 // XXX: Obsolete; remove after snap.
3652 if self.eat_keyword(&~"const") {
3653 self.obsolete(*self.last_span, ObsoleteConstItem);
3655 self.expect_keyword(&~"static");
3658 let ident = self.parse_ident();
3659 self.expect(&token::COLON);
3660 let ty = self.parse_ty(false);
3661 let hi = self.span.hi;
3662 self.expect(&token::SEMI);
3663 @ast::foreign_item { ident: ident,
3665 node: foreign_item_const(ty),
3667 span: mk_sp(lo, hi),
3671 // parse safe/unsafe and fn
3672 fn parse_fn_purity(&self) -> purity {
3673 if self.eat_keyword(&~"fn") { impure_fn }
3674 else if self.eat_keyword(&~"pure") {
3675 self.obsolete(*self.last_span, ObsoletePurity);
3676 self.expect_keyword(&~"fn");
3677 // NB: We parse this as impure for bootstrapping purposes.
3679 } else if self.eat_keyword(&~"unsafe") {
3680 self.expect_keyword(&~"fn");
3683 else { self.unexpected(); }
3687 // at this point, this is essentially a wrapper for
3688 // parse_foreign_items.
3689 fn parse_foreign_mod_items(&self, sort: ast::foreign_mod_sort,
3691 first_item_attrs: ~[attribute])
3693 let ParsedItemsAndViewItems {
3694 attrs_remaining: attrs_remaining,
3695 view_items: view_items,
3697 foreign_items: foreign_items
3698 } = self.parse_foreign_items(first_item_attrs, true);
3699 let mut initial_attrs = attrs_remaining;
3700 assert!(*self.token == token::RBRACE);
3704 view_items: view_items,
3705 items: foreign_items
3709 // parse extern foo; or extern mod foo { ... } or extern { ... }
3710 fn parse_item_foreign_mod(&self,
3712 opt_abis: Option<AbiSet>,
3713 visibility: visibility,
3714 attrs: ~[attribute],
3715 items_allowed: bool)
3716 -> item_or_view_item
3718 let mut must_be_named_mod = false;
3719 if self.is_keyword(&~"mod") {
3720 must_be_named_mod = true;
3721 self.expect_keyword(&~"mod");
3722 } else if *self.token != token::LBRACE {
3726 "expected `{` or `mod` but found `%s`",
3727 self.this_token_to_str()
3732 let (sort, ident) = match *self.token {
3733 token::IDENT(*) => (ast::named, self.parse_ident()),
3735 if must_be_named_mod {
3739 "expected foreign module name but found `%s`",
3740 self.this_token_to_str()
3746 special_idents::clownshoes_foreign_mod)
3750 // extern mod foo { ... } or extern { ... }
3751 if items_allowed && self.eat(&token::LBRACE) {
3752 let abis = opt_abis.get_or_default(AbiSet::C());
3754 let (inner, next) = self.parse_inner_attrs_and_next();
3755 let m = self.parse_foreign_mod_items(sort, abis, next);
3756 self.expect(&token::RBRACE);
3758 return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
3759 item_foreign_mod(m), visibility,
3760 maybe_append(/*bad*/ copy attrs,
3764 if opt_abis.is_some() {
3765 self.span_err(*self.span, ~"an ABI may not be specified here");
3769 let metadata = self.parse_optional_meta();
3770 self.expect(&token::SEMI);
3771 iovi_view_item(@ast::view_item {
3772 node: view_item_extern_mod(ident, metadata, self.get_id()),
3775 span: mk_sp(lo, self.last_span.hi)
3779 // parse type Foo = Bar;
3780 fn parse_item_type(&self) -> item_info {
3781 let ident = self.parse_ident();
3782 self.parse_region_param();
3783 let tps = self.parse_generics();
3784 self.expect(&token::EQ);
3785 let ty = self.parse_ty(false);
3786 self.expect(&token::SEMI);
3787 (ident, item_ty(ty, tps), None)
3790 // parse obsolete region parameter
3791 fn parse_region_param(&self) {
3792 if self.eat(&token::BINOP(token::SLASH)) {
3793 self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
3794 self.expect(&token::BINOP(token::AND));
3798 // parse a structure-like enum variant definition
3799 // this should probably be renamed or refactored...
3800 fn parse_struct_def(&self) -> @struct_def {
3801 let mut fields: ~[@struct_field] = ~[];
3802 while *self.token != token::RBRACE {
3803 for self.parse_struct_decl_field().each |struct_field| {
3804 fields.push(*struct_field);
3809 return @ast::struct_def {
3815 // parse the part of an "enum" decl following the '{'
3816 fn parse_enum_def(&self, _generics: &ast::Generics) -> enum_def {
3817 let mut variants = ~[];
3818 let mut all_nullary = true, have_disr = false;
3819 while *self.token != token::RBRACE {
3820 let variant_attrs = self.parse_outer_attributes();
3821 let vlo = self.span.lo;
3823 let vis = self.parse_visibility();
3826 let mut args = ~[], disr_expr = None;
3827 ident = self.parse_ident();
3828 if self.eat(&token::LBRACE) {
3829 // Parse a struct variant.
3830 all_nullary = false;
3831 kind = struct_variant_kind(self.parse_struct_def());
3832 } else if *self.token == token::LPAREN {
3833 all_nullary = false;
3834 let arg_tys = self.parse_unspanned_seq(
3837 seq_sep_trailing_disallowed(token::COMMA),
3838 |p| p.parse_ty(false)
3840 for arg_tys.each |ty| {
3841 args.push(ast::variant_arg {
3846 kind = tuple_variant_kind(args);
3847 } else if self.eat(&token::EQ) {
3849 disr_expr = Some(self.parse_expr());
3850 kind = tuple_variant_kind(args);
3852 kind = tuple_variant_kind(~[]);
3855 let vr = ast::variant_ {
3857 attrs: variant_attrs,
3860 disr_expr: disr_expr,
3863 variants.push(spanned(vlo, self.last_span.hi, vr));
3865 if !self.eat(&token::COMMA) { break; }
3867 self.expect(&token::RBRACE);
3868 if (have_disr && !all_nullary) {
3869 self.fatal(~"discriminator values can only be used with a c-like \
3873 ast::enum_def { variants: variants }
3876 // parse an "enum" declaration
3877 fn parse_item_enum(&self) -> item_info {
3878 let id = self.parse_ident();
3879 self.parse_region_param();
3880 let generics = self.parse_generics();
3882 if *self.token == token::EQ {
3885 let ty = self.parse_ty(false);
3886 self.expect(&token::SEMI);
3887 let variant = spanned(ty.span.lo, ty.span.hi, ast::variant_ {
3890 kind: tuple_variant_kind(
3891 ~[ast::variant_arg {ty: ty, id: self.get_id()}]
3898 self.obsolete(*self.last_span, ObsoleteNewtypeEnum);
3903 ast::enum_def { variants: ~[variant] },
3909 self.expect(&token::LBRACE);
3911 let enum_definition = self.parse_enum_def(&generics);
3912 (id, item_enum(enum_definition, generics), None)
3915 fn parse_fn_ty_sigil(&self) -> Option<Sigil> {
3925 token::BINOP(token::AND) => {
3935 fn fn_expr_lookahead(&self, tok: token::Token) -> bool {
3937 token::LPAREN | token::AT | token::TILDE | token::BINOP(_) => true,
3942 // parse a string as an ABI spec on an extern type or module
3943 fn parse_opt_abis(&self) -> Option<AbiSet> {
3945 token::LIT_STR(s) => {
3947 let the_string = self.id_to_str(s);
3948 let mut words = ~[];
3949 for str::each_word(*the_string) |s| { words.push(s) }
3950 let mut abis = AbiSet::empty();
3951 for words.each |word| {
3952 match abi::lookup(*word) {
3954 if abis.contains(abi) {
3957 fmt!("ABI `%s` appears twice",
3967 fmt!("illegal ABI: \
3968 expected one of [%s], \
3970 str::connect_slices(
3986 // parse one of the items or view items allowed by the
3987 // flags; on failure, return iovi_none.
3988 // NB: this function no longer parses the items inside an
3990 fn parse_item_or_view_item(
3992 attrs: ~[attribute],
3993 macros_allowed: bool
3994 ) -> item_or_view_item {
3995 maybe_whole!(iovi self, nt_item);
3996 let lo = self.span.lo;
3998 let visibility = self.parse_visibility();
4000 // must be a view item:
4001 if self.eat_keyword(&~"use") {
4002 // USE ITEM (iovi_view_item)
4003 let view_item = self.parse_use();
4004 self.expect(&token::SEMI);
4005 return iovi_view_item(@ast::view_item {
4009 span: mk_sp(lo, self.last_span.hi)
4012 // either a view item or an item:
4013 if self.eat_keyword(&~"extern") {
4014 let opt_abis = self.parse_opt_abis();
4016 if self.eat_keyword(&~"fn") {
4017 // EXTERN FUNCTION ITEM
4018 let abis = opt_abis.get_or_default(AbiSet::C());
4019 let (ident, item_, extra_attrs) =
4020 self.parse_item_fn(extern_fn, abis);
4021 return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
4026 // EXTERN MODULE ITEM (iovi_view_item)
4027 return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs,
4031 // the rest are all guaranteed to be items:
4032 if (self.is_keyword(&~"const") ||
4033 (self.is_keyword(&~"static") &&
4034 !self.token_is_keyword(&~"fn", &self.look_ahead(1)))) {
4035 // CONST / STATIC ITEM
4036 if self.is_keyword(&~"const") {
4037 self.obsolete(*self.span, ObsoleteConstItem);
4040 let (ident, item_, extra_attrs) = self.parse_item_const();
4041 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4043 maybe_append(attrs, extra_attrs)));
4045 if self.is_keyword(&~"fn") &&
4046 !self.fn_expr_lookahead(self.look_ahead(1u)) {
4049 let (ident, item_, extra_attrs) =
4050 self.parse_item_fn(impure_fn, AbiSet::Rust());
4051 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4053 maybe_append(attrs, extra_attrs)));
4055 if self.eat_keyword(&~"pure") {
4056 // PURE FUNCTION ITEM (obsolete)
4057 self.obsolete(*self.last_span, ObsoletePurity);
4058 self.expect_keyword(&~"fn");
4059 let (ident, item_, extra_attrs) =
4060 self.parse_item_fn(impure_fn, AbiSet::Rust());
4061 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4063 maybe_append(attrs, extra_attrs)));
4065 if self.is_keyword(&~"unsafe")
4066 && self.look_ahead(1u) != token::LBRACE {
4067 // UNSAFE FUNCTION ITEM
4069 self.expect_keyword(&~"fn");
4070 let (ident, item_, extra_attrs) =
4071 self.parse_item_fn(unsafe_fn, AbiSet::Rust());
4072 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4074 maybe_append(attrs, extra_attrs)));
4076 if self.eat_keyword(&~"mod") {
4078 let (ident, item_, extra_attrs) = self.parse_item_mod(attrs);
4079 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4081 maybe_append(attrs, extra_attrs)));
4083 if self.eat_keyword(&~"type") {
4085 let (ident, item_, extra_attrs) = self.parse_item_type();
4086 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4088 maybe_append(attrs, extra_attrs)));
4090 if self.eat_keyword(&~"enum") {
4092 let (ident, item_, extra_attrs) = self.parse_item_enum();
4093 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4095 maybe_append(attrs, extra_attrs)));
4097 if self.eat_keyword(&~"trait") {
4099 let (ident, item_, extra_attrs) = self.parse_item_trait();
4100 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4102 maybe_append(attrs, extra_attrs)));
4104 if self.eat_keyword(&~"impl") {
4106 let (ident, item_, extra_attrs) =
4107 self.parse_item_impl(visibility);
4108 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4110 maybe_append(attrs, extra_attrs)));
4112 if self.eat_keyword(&~"struct") {
4114 let (ident, item_, extra_attrs) = self.parse_item_struct();
4115 return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
4117 maybe_append(attrs, extra_attrs)));
4119 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4122 // parse a foreign item; on failure, return iovi_none.
4123 fn parse_foreign_item(
4125 attrs: ~[attribute],
4126 macros_allowed: bool
4127 ) -> item_or_view_item {
4128 maybe_whole!(iovi self, nt_item);
4129 let lo = self.span.lo;
4131 let visibility = self.parse_visibility();
4133 if (self.is_keyword(&~"const") || self.is_keyword(&~"static")) {
4134 // FOREIGN CONST ITEM
4135 let item = self.parse_item_foreign_const(visibility, attrs);
4136 return iovi_foreign_item(item);
4138 if (self.is_keyword(&~"fn") || self.is_keyword(&~"pure") ||
4139 self.is_keyword(&~"unsafe")) {
4140 // FOREIGN FUNCTION ITEM
4141 let item = self.parse_item_foreign_fn(attrs);
4142 return iovi_foreign_item(item);
4144 self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
4147 // this is the fall-through for parsing items.
4148 fn parse_macro_use_or_failure(
4150 attrs: ~[attribute],
4151 macros_allowed: bool,
4153 visibility : visibility
4154 ) -> item_or_view_item {
4155 if macros_allowed && !self.is_any_keyword(© *self.token)
4156 && self.look_ahead(1) == token::NOT
4157 && (is_plain_ident(&self.look_ahead(2))
4158 || self.look_ahead(2) == token::LPAREN
4159 || self.look_ahead(2) == token::LBRACE) {
4160 // MACRO INVOCATION ITEM
4161 if attrs.len() > 0 {
4162 self.fatal(~"attrs on macros are not yet supported");
4166 let pth = self.parse_path_without_tps();
4167 self.expect(&token::NOT);
4169 // a 'special' identifier (like what `macro_rules!` uses)
4170 // is optional. We should eventually unify invoc syntax
4172 let id = if is_plain_ident(&*self.token) {
4175 token::special_idents::invalid // no special identifier
4177 // eat a matched-delimiter token tree:
4178 let tts = match *self.token {
4179 token::LPAREN | token::LBRACE => {
4180 let ket = token::flip_delimiter(&*self.token);
4181 self.parse_unspanned_seq(
4185 |p| p.parse_token_tree()
4188 _ => self.fatal(~"expected open delimiter")
4190 // single-variant-enum... :
4191 let m = ast::mac_invoc_tt(pth, tts);
4192 let m: ast::mac = codemap::spanned { node: m,
4193 span: mk_sp(self.span.lo,
4195 let item_ = item_mac(m);
4196 return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_,
4197 visibility, attrs));
4200 // FAILURE TO PARSE ITEM
4201 if visibility != inherited {
4202 let mut s = ~"unmatched visibility `";
4203 s += if visibility == public { ~"pub" } else { ~"priv" };
4205 self.span_fatal(*self.last_span, s);
4210 fn parse_item(&self, attrs: ~[attribute]) -> Option<@ast::item> {
4211 match self.parse_item_or_view_item(attrs, true) {
4214 iovi_view_item(_) =>
4215 self.fatal(~"view items are not allowed here"),
4216 iovi_foreign_item(_) =>
4217 self.fatal(~"foreign items are not allowed here"),
4223 // parse, e.g., "use a::b::{z,y}"
4224 fn parse_use(&self) -> view_item_ {
4225 return view_item_use(self.parse_view_paths());
4229 // matches view_path : MOD? IDENT EQ non_global_path
4230 // | MOD? non_global_path MOD_SEP LBRACE RBRACE
4231 // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
4232 // | MOD? non_global_path MOD_SEP STAR
4233 // | MOD? non_global_path
4234 fn parse_view_path(&self) -> @view_path {
4235 let lo = self.span.lo;
4237 let first_ident = self.parse_ident();
4238 let mut path = ~[first_ident];
4239 debug!("parsed view_path: %s", *self.id_to_str(first_ident));
4244 path = ~[self.parse_ident()];
4245 while *self.token == token::MOD_SEP {
4247 let id = self.parse_ident();
4250 let path = @ast::Path { span: mk_sp(lo, self.span.hi),
4255 return @spanned(lo, self.span.hi,
4256 view_path_simple(first_ident,
4262 // foo::bar or foo::{a,b,c} or foo::*
4263 while *self.token == token::MOD_SEP {
4267 token::IDENT(i, _) => {
4272 // foo::bar::{a,b,c}
4274 let idents = self.parse_unspanned_seq(
4277 seq_sep_trailing_allowed(token::COMMA),
4278 |p| p.parse_path_list_ident()
4280 let path = @ast::Path { span: mk_sp(lo, self.span.hi),
4285 return @spanned(lo, self.span.hi,
4286 view_path_list(path, idents, self.get_id()));
4290 token::BINOP(token::STAR) => {
4292 let path = @ast::Path { span: mk_sp(lo, self.span.hi),
4297 return @spanned(lo, self.span.hi,
4298 view_path_glob(path, self.get_id()));
4307 let last = path[vec::len(path) - 1u];
4308 let path = @ast::Path { span: mk_sp(lo, self.span.hi),
4315 view_path_simple(last, path, self.get_id()));
4318 // matches view_paths = view_path | view_path , view_paths
4319 fn parse_view_paths(&self) -> ~[@view_path] {
4320 let mut vp = ~[self.parse_view_path()];
4321 while *self.token == token::COMMA {
4323 vp.push(self.parse_view_path());
4328 fn is_view_item(&self) -> bool {
4330 if !self.is_keyword(&~"pub") && !self.is_keyword(&~"priv") {
4331 tok = copy *self.token;
4332 next_tok = self.look_ahead(1);
4334 tok = self.look_ahead(1);
4335 next_tok = self.look_ahead(2);
4337 self.token_is_keyword(&~"use", &tok)
4338 || (self.token_is_keyword(&~"extern", &tok) &&
4339 self.token_is_keyword(&~"mod", &next_tok))
4342 // parse a view item.
4345 attrs: ~[attribute],
4348 let lo = self.span.lo;
4349 let node = if self.eat_keyword(&~"use") {
4351 } else if self.eat_keyword(&~"extern") {
4352 self.expect_keyword(&~"mod");
4353 let ident = self.parse_ident();
4354 let metadata = self.parse_optional_meta();
4355 view_item_extern_mod(ident, metadata, self.get_id())
4357 self.bug(~"expected view item");
4359 self.expect(&token::SEMI);
4360 @ast::view_item { node: node,
4363 span: mk_sp(lo, self.last_span.hi) }
4366 // Parses a sequence of items. Stops when it finds program
4367 // text that can't be parsed as an item
4368 // - mod_items uses extern_mod_allowed = true
4369 // - block_tail_ uses extern_mod_allowed = false
4370 fn parse_items_and_view_items(&self,
4371 first_item_attrs: ~[attribute],
4372 mut extern_mod_allowed: bool,
4373 macros_allowed: bool)
4374 -> ParsedItemsAndViewItems {
4375 let mut attrs = vec::append(first_item_attrs,
4376 self.parse_outer_attributes());
4377 // First, parse view items.
4378 let mut (view_items, items) = (~[], ~[]);
4379 let mut done = false;
4380 // I think this code would probably read better as a single
4381 // loop with a mutable three-state-variable (for extern mods,
4382 // view items, and regular items) ... except that because
4383 // of macros, I'd like to delay that entire check until later.
4385 match self.parse_item_or_view_item(/*bad*/ copy attrs,
4391 iovi_view_item(view_item) => {
4392 match view_item.node {
4393 view_item_use(*) => {
4394 // `extern mod` must precede `use`.
4395 extern_mod_allowed = false;
4397 view_item_extern_mod(*)
4398 if !extern_mod_allowed => {
4399 self.span_err(view_item.span,
4401 declarations are not \
4404 view_item_extern_mod(*) => {}
4406 view_items.push(view_item);
4408 iovi_item(item) => {
4410 attrs = self.parse_outer_attributes();
4413 iovi_foreign_item(_) => {
4417 attrs = self.parse_outer_attributes();
4420 // Next, parse items.
4423 match self.parse_item_or_view_item(/*bad*/ copy attrs,
4426 iovi_view_item(view_item) => {
4427 self.span_err(view_item.span,
4428 ~"`use` and `extern mod` declarations \
4429 must precede items");
4431 iovi_item(item) => {
4434 iovi_foreign_item(_) => {
4438 attrs = self.parse_outer_attributes();
4442 ParsedItemsAndViewItems {
4443 attrs_remaining: attrs,
4444 view_items: view_items,
4450 // Parses a sequence of foreign items. Stops when it finds program
4451 // text that can't be parsed as an item
4452 fn parse_foreign_items(&self, first_item_attrs: ~[attribute],
4453 macros_allowed: bool)
4454 -> ParsedItemsAndViewItems {
4455 let mut attrs = vec::append(first_item_attrs,
4456 self.parse_outer_attributes());
4457 let mut foreign_items = ~[];
4459 match self.parse_foreign_item(/*bad*/ copy attrs, macros_allowed) {
4461 iovi_view_item(view_item) => {
4462 // I think this can't occur:
4463 self.span_err(view_item.span,
4464 ~"`use` and `extern mod` declarations \
4465 must precede items");
4468 // FIXME #5668: this will occur for a macro invocation:
4471 iovi_foreign_item(foreign_item) => {
4472 foreign_items.push(foreign_item);
4475 attrs = self.parse_outer_attributes();
4478 ParsedItemsAndViewItems {
4479 attrs_remaining: attrs,
4482 foreign_items: foreign_items
4486 // Parses a source module as a crate. This is the main
4487 // entry point for the parser.
4488 fn parse_crate_mod(&self) -> @crate {
4489 let lo = self.span.lo;
4490 // parse the crate's inner attrs, maybe (oops) one
4491 // of the attrs of an item:
4492 let (inner, next) = self.parse_inner_attrs_and_next();
4493 let first_item_outer_attrs = next;
4494 // parse the items inside the crate:
4495 let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
4496 @spanned(lo, self.span.lo,
4497 ast::crate_ { module: m,
4499 config: copy self.cfg })
4502 fn parse_str(&self) -> @~str {
4504 token::LIT_STR(s) => {
4508 _ => self.fatal(~"expected string literal")
4518 // indent-tabs-mode: nil
4519 // c-basic-offset: 4
4520 // buffer-file-coding-system: utf-8-unix