1 // Copyright 2012 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.
14 use parse::common::*; //resolve bug?
16 use parse::parser::Parser;
18 // a parser that can parse attributes.
19 pub trait parser_attr {
20 fn parse_outer_attributes(&self) -> ~[ast::attribute];
21 fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute;
22 fn parse_attribute_naked(
24 style: ast::attr_style,
27 fn parse_inner_attrs_and_next(&self) ->
28 (~[ast::attribute], ~[ast::attribute]);
29 fn parse_meta_item(&self) -> @ast::meta_item;
30 fn parse_meta_seq(&self) -> ~[@ast::meta_item];
31 fn parse_optional_meta(&self) -> ~[@ast::meta_item];
34 impl parser_attr for Parser {
36 // Parse attributes that appear before an item
37 fn parse_outer_attributes(&self) -> ~[ast::attribute] {
38 let mut attrs: ~[ast::attribute] = ~[];
42 if self.look_ahead(1u) != token::LBRACKET {
45 attrs += ~[self.parse_attribute(ast::attr_outer)];
47 token::DOC_COMMENT(s) => {
48 let attr = ::attr::mk_sugared_doc_attr(
49 copy *self.id_to_str(s),
53 if attr.node.style != ast::attr_outer {
54 self.fatal(~"expected outer comment");
65 // matches attribute = # attribute_naked
66 fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute {
67 let lo = self.span.lo;
68 self.expect(&token::POUND);
69 return self.parse_attribute_naked(style, lo);
72 // matches attribute_naked = [ meta_item ]
73 fn parse_attribute_naked(&self, style: ast::attr_style, lo: BytePos) ->
75 self.expect(&token::LBRACKET);
76 let meta_item = self.parse_meta_item();
77 self.expect(&token::RBRACKET);
78 let hi = self.span.hi;
79 return spanned(lo, hi, ast::attribute_ { style: style,
81 is_sugared_doc: false });
84 // Parse attributes that appear after the opening of an item, each
85 // terminated by a semicolon. In addition to a vector of inner attributes,
86 // this function also returns a vector that may contain the first outer
87 // attribute of the next item (since we can't know whether the attribute
88 // is an inner attribute of the containing item or an outer attribute of
89 // the first contained item until we see the semi).
91 // matches inner_attrs* outer_attr?
92 // you can make the 'next' field an Option, but the result is going to be
93 // more useful as a vector.
94 fn parse_inner_attrs_and_next(&self) ->
95 (~[ast::attribute], ~[ast::attribute]) {
96 let mut inner_attrs: ~[ast::attribute] = ~[];
97 let mut next_outer_attrs: ~[ast::attribute] = ~[];
101 if self.look_ahead(1u) != token::LBRACKET {
102 // This is an extension
105 let attr = self.parse_attribute(ast::attr_inner);
106 if *self.token == token::SEMI {
108 inner_attrs += ~[attr];
110 // It's not really an inner attribute
112 spanned(attr.span.lo, attr.span.hi,
113 ast::attribute_ { style: ast::attr_outer,
114 value: attr.node.value,
115 is_sugared_doc: false });
116 next_outer_attrs += ~[outer_attr];
120 token::DOC_COMMENT(s) => {
121 let attr = ::attr::mk_sugared_doc_attr(
122 copy *self.id_to_str(s),
127 if attr.node.style == ast::attr_inner {
128 inner_attrs += ~[attr];
130 next_outer_attrs += ~[attr];
137 (inner_attrs, next_outer_attrs)
140 // matches meta_item = IDENT
143 fn parse_meta_item(&self) -> @ast::meta_item {
144 let lo = self.span.lo;
145 let name = self.id_to_str(self.parse_ident());
149 let lit = self.parse_lit();
150 let hi = self.span.hi;
151 @spanned(lo, hi, ast::meta_name_value(name, lit))
154 let inner_items = self.parse_meta_seq();
155 let hi = self.span.hi;
156 @spanned(lo, hi, ast::meta_list(name, inner_items))
159 let hi = self.span.hi;
160 @spanned(lo, hi, ast::meta_word(name))
165 // matches meta_seq = ( COMMASEP(meta_item) )
166 fn parse_meta_seq(&self) -> ~[@ast::meta_item] {
170 seq_sep_trailing_disallowed(token::COMMA),
171 |p| p.parse_meta_item()
175 fn parse_optional_meta(&self) -> ~[@ast::meta_item] {
177 token::LPAREN => self.parse_meta_seq(),
187 // indent-tabs-mode: nil
189 // buffer-file-coding-system: utf-8-unix