提交 5b72e52e 编写于 作者: P Paul Stansifer

Access parse/attrs.rs with an impl.

上级 09652c8f
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
export parse_from_source_str; export parse_from_source_str;
import parser::parser; import parser::parser;
import attr::parser_attr;
import common::parser_common; import common::parser_common;
import ast::node_id; import ast::node_id;
import util::interner; import util::interner;
...@@ -44,7 +45,7 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg, ...@@ -44,7 +45,7 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg,
let p = new_parser_from_file(sess, cfg, input, parser::CRATE_FILE); let p = new_parser_from_file(sess, cfg, input, parser::CRATE_FILE);
let lo = p.span.lo; let lo = p.span.lo;
let prefix = path::dirname(p.reader.filemap.name); let prefix = path::dirname(p.reader.filemap.name);
let leading_attrs = attr::parse_inner_attrs_and_next(p); let leading_attrs = p.parse_inner_attrs_and_next();
let crate_attrs = leading_attrs.inner; let crate_attrs = leading_attrs.inner;
let first_cdir_attr = leading_attrs.next; let first_cdir_attr = leading_attrs.next;
let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr); let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
......
...@@ -3,116 +3,130 @@ ...@@ -3,116 +3,130 @@
import common::{parser_common, seq_sep}; import common::{parser_common, seq_sep};
export attr_or_ext; export attr_or_ext;
export parse_outer_attributes; export parser_attr;
export parse_outer_attrs_or_ext;
export parse_inner_attrs_and_next;
export parse_optional_meta;
// A type to distingush between the parsing of item attributes or syntax // A type to distingush between the parsing of item attributes or syntax
// extensions, which both begin with token.POUND // extensions, which both begin with token.POUND
type attr_or_ext = option<either<[ast::attribute], @ast::expr>>; type attr_or_ext = option<either<[ast::attribute], @ast::expr>>;
fn parse_outer_attrs_or_ext( impl parser_attr for parser {
p: parser,
first_item_attrs: [ast::attribute]) -> attr_or_ext { fn parse_outer_attrs_or_ext(first_item_attrs: [ast::attribute])
let expect_item_next = vec::is_not_empty(first_item_attrs); -> attr_or_ext
if p.token == token::POUND { {
let lo = p.span.lo; let expect_item_next = vec::is_not_empty(first_item_attrs);
if p.look_ahead(1u) == token::LBRACKET { if self.token == token::POUND {
p.bump(); let lo = self.span.lo;
let first_attr = parse_attribute_naked(p, ast::attr_outer, lo); if self.look_ahead(1u) == token::LBRACKET {
ret some(left([first_attr] + parse_outer_attributes(p))); self.bump();
} else if !(p.look_ahead(1u) == token::LT let first_attr =
|| p.look_ahead(1u) == token::LBRACKET self.parse_attribute_naked(ast::attr_outer, lo);
|| expect_item_next) { ret some(left([first_attr] + self.parse_outer_attributes()));
p.bump(); } else if !(self.look_ahead(1u) == token::LT
ret some(right(p.parse_syntax_ext_naked(lo))); || self.look_ahead(1u) == token::LBRACKET
|| expect_item_next) {
self.bump();
ret some(right(self.parse_syntax_ext_naked(lo)));
} else { ret none; }
} else { ret none; } } else { ret none; }
} else { ret none; } }
}
// Parse attributes that appear before an item // Parse attributes that appear before an item
fn parse_outer_attributes(p: parser) -> [ast::attribute] { fn parse_outer_attributes() -> [ast::attribute] {
let mut attrs: [ast::attribute] = []; let mut attrs: [ast::attribute] = [];
while p.token == token::POUND && p.look_ahead(1u) == token::LBRACKET { while self.token == token::POUND
attrs += [parse_attribute(p, ast::attr_outer)]; && self.look_ahead(1u) == token::LBRACKET {
attrs += [self.parse_attribute(ast::attr_outer)];
}
ret attrs;
} }
ret attrs;
}
fn parse_attribute(p: parser, style: ast::attr_style) -> ast::attribute { fn parse_attribute(style: ast::attr_style) -> ast::attribute {
let lo = p.span.lo; let lo = self.span.lo;
p.expect(token::POUND); self.expect(token::POUND);
ret parse_attribute_naked(p, style, lo); ret self.parse_attribute_naked(style, lo);
} }
fn parse_attribute_naked(p: parser, style: ast::attr_style, lo: uint) -> fn parse_attribute_naked(style: ast::attr_style, lo: uint) ->
ast::attribute { ast::attribute {
p.expect(token::LBRACKET); self.expect(token::LBRACKET);
let meta_item = parse_meta_item(p); let meta_item = self.parse_meta_item();
p.expect(token::RBRACKET); self.expect(token::RBRACKET);
let mut hi = p.span.hi; let mut hi = self.span.hi;
ret spanned(lo, hi, {style: style, value: *meta_item}); ret spanned(lo, hi, {style: style, value: *meta_item});
} }
// Parse attributes that appear after the opening of an item, each terminated // Parse attributes that appear after the opening of an item, each
// by a semicolon. In addition to a vector of inner attributes, this function // terminated by a semicolon. In addition to a vector of inner attributes,
// also returns a vector that may contain the first outer attribute of the // this function also returns a vector that may contain the first outer
// next item (since we can't know whether the attribute is an inner attribute // attribute of the next item (since we can't know whether the attribute
// of the containing item or an outer attribute of the first contained item // is an inner attribute of the containing item or an outer attribute of
// until we see the semi). // the first contained item until we see the semi).
fn parse_inner_attrs_and_next(p: parser) -> fn parse_inner_attrs_and_next() ->
{inner: [ast::attribute], next: [ast::attribute]} { {inner: [ast::attribute], next: [ast::attribute]} {
let mut inner_attrs: [ast::attribute] = []; let mut inner_attrs: [ast::attribute] = [];
let mut next_outer_attrs: [ast::attribute] = []; let mut next_outer_attrs: [ast::attribute] = [];
while p.token == token::POUND { while self.token == token::POUND {
if p.look_ahead(1u) != token::LBRACKET { if self.look_ahead(1u) != token::LBRACKET {
// This is an extension // This is an extension
break; break;
}
let attr = self.parse_attribute(ast::attr_inner);
if self.token == token::SEMI {
self.bump();
inner_attrs += [attr];
} else {
// It's not really an inner attribute
let outer_attr =
spanned(attr.span.lo, attr.span.hi,
{style: ast::attr_outer, value: attr.node.value});
next_outer_attrs += [outer_attr];
break;
}
} }
let attr = parse_attribute(p, ast::attr_inner); ret {inner: inner_attrs, next: next_outer_attrs};
if p.token == token::SEMI { }
p.bump();
inner_attrs += [attr]; fn parse_meta_item() -> @ast::meta_item {
} else { let lo = self.span.lo;
// It's not really an inner attribute let ident = self.parse_ident();
let outer_attr = alt self.token {
spanned(attr.span.lo, attr.span.hi, token::EQ {
{style: ast::attr_outer, value: attr.node.value}); self.bump();
next_outer_attrs += [outer_attr]; let lit = self.parse_lit();
break; let mut hi = self.span.hi;
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
}
token::LPAREN {
let inner_items = self.parse_meta_seq();
let mut hi = self.span.hi;
ret @spanned(lo, hi, ast::meta_list(ident, inner_items));
}
_ {
let mut hi = self.span.hi;
ret @spanned(lo, hi, ast::meta_word(ident));
}
} }
} }
ret {inner: inner_attrs, next: next_outer_attrs};
}
fn parse_meta_item(p: parser) -> @ast::meta_item { fn parse_meta_seq() -> [@ast::meta_item] {
let lo = p.span.lo; ret self.parse_seq(token::LPAREN, token::RPAREN,
let ident = p.parse_ident(); seq_sep(token::COMMA),
alt p.token { {|p| p.parse_meta_item()}).node;
token::EQ {
p.bump();
let lit = p.parse_lit();
let mut hi = p.span.hi;
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
}
token::LPAREN {
let inner_items = parse_meta_seq(p);
let mut hi = p.span.hi;
ret @spanned(lo, hi, ast::meta_list(ident, inner_items));
}
_ {
let mut hi = p.span.hi;
ret @spanned(lo, hi, ast::meta_word(ident));
}
} }
}
fn parse_meta_seq(p: parser) -> [@ast::meta_item] { fn parse_optional_meta() -> [@ast::meta_item] {
ret p.parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA), alt self.token { token::LPAREN { ret self.parse_meta_seq(); }
{|p| parse_meta_item(p)}).node; _ { ret []; } }
}
} }
fn parse_optional_meta(p: parser) -> [@ast::meta_item] { //
alt p.token { token::LPAREN { ret parse_meta_seq(p); } _ { ret []; } } // Local Variables:
} // mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
import parser::{parser, SOURCE_FILE}; import parser::{parser, SOURCE_FILE};
import attr::parse_inner_attrs_and_next; import attr::parser_attr;
export eval_crate_directives_to_mod; export eval_crate_directives_to_mod;
...@@ -65,7 +65,7 @@ fn file_exists(path: str) -> bool { ...@@ -65,7 +65,7 @@ fn file_exists(path: str) -> bool {
if file_exists(modpath) { if file_exists(modpath) {
#debug("found companion mod"); #debug("found companion mod");
let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath, SOURCE_FILE); let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath, SOURCE_FILE);
let inner_attrs = parse_inner_attrs_and_next(p0); let inner_attrs = p0.parse_inner_attrs_and_next();
let first_item_outer_attrs = inner_attrs.next; let first_item_outer_attrs = inner_attrs.next;
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
cx.sess.chpos = p0.reader.chpos; cx.sess.chpos = p0.reader.chpos;
...@@ -97,7 +97,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, ...@@ -97,7 +97,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
} else { prefix + path::path_sep() + file_path }; } else { prefix + path::path_sep() + file_path };
let p0 = let p0 =
new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE); new_parser_from_file(cx.sess, cx.cfg, full_path, SOURCE_FILE);
let inner_attrs = parse_inner_attrs_and_next(p0); let inner_attrs = p0.parse_inner_attrs_and_next();
let mod_attrs = attrs + inner_attrs.inner; let mod_attrs = attrs + inner_attrs.inner;
let first_item_outer_attrs = inner_attrs.next; let first_item_outer_attrs = inner_attrs.next;
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
......
...@@ -8,10 +8,7 @@ ...@@ -8,10 +8,7 @@
import ast::*; import ast::*;
import lexer::reader; import lexer::reader;
import prec::{as_prec, token_to_binop}; import prec::{as_prec, token_to_binop};
import attr::{parse_outer_attrs_or_ext, import attr::parser_attr;
parse_inner_attrs_and_next,
parse_outer_attributes,
parse_optional_meta};
import common::*; import common::*;
import dvec::{dvec, extensions}; import dvec::{dvec, extensions};
...@@ -168,7 +165,7 @@ fn parse_ty_fn() -> fn_decl { ...@@ -168,7 +165,7 @@ fn parse_ty_fn() -> fn_decl {
fn parse_ty_methods() -> [ty_method] { fn parse_ty_methods() -> [ty_method] {
(self.parse_seq(token::LBRACE, token::RBRACE, seq_sep_none()) { |p| (self.parse_seq(token::LBRACE, token::RBRACE, seq_sep_none()) { |p|
let attrs = parse_outer_attributes(p); let attrs = p.parse_outer_attributes();
let flo = p.span.lo; let flo = p.span.lo;
let pur = p.parse_fn_purity(); let pur = p.parse_fn_purity();
let ident = p.parse_method_name(); let ident = p.parse_method_name();
...@@ -1529,7 +1526,7 @@ fn check_expected_item(p: parser, current_attrs: [attribute]) { ...@@ -1529,7 +1526,7 @@ fn check_expected_item(p: parser, current_attrs: [attribute]) {
ret @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id())); ret @spanned(lo, decl.span.hi, stmt_decl(decl, self.get_id()));
} else { } else {
let mut item_attrs; let mut item_attrs;
alt parse_outer_attrs_or_ext(self, first_item_attrs) { alt self.parse_outer_attrs_or_ext(first_item_attrs) {
none { item_attrs = []; } none { item_attrs = []; }
some(left(attrs)) { item_attrs = attrs; } some(left(attrs)) { item_attrs = attrs; }
some(right(ext)) { some(right(ext)) {
...@@ -1575,7 +1572,7 @@ fn parse_inner_attrs_and_block(parse_attrs: bool) -> ([attribute], blk) { ...@@ -1575,7 +1572,7 @@ fn parse_inner_attrs_and_block(parse_attrs: bool) -> ([attribute], blk) {
fn maybe_parse_inner_attrs_and_next(p: parser, parse_attrs: bool) -> fn maybe_parse_inner_attrs_and_next(p: parser, parse_attrs: bool) ->
{inner: [attribute], next: [attribute]} { {inner: [attribute], next: [attribute]} {
if parse_attrs { if parse_attrs {
parse_inner_attrs_and_next(p) p.parse_inner_attrs_and_next()
} else { } else {
{inner: [], next: []} {inner: [], next: []}
} }
...@@ -1832,7 +1829,7 @@ fn parse_method_name() -> ident { ...@@ -1832,7 +1829,7 @@ fn parse_method_name() -> ident {
} }
fn parse_method(pr: visibility) -> @method { fn parse_method(pr: visibility) -> @method {
let attrs = parse_outer_attributes(self); let attrs = self.parse_outer_attributes();
let lo = self.span.lo, pur = self.parse_fn_purity(); let lo = self.span.lo, pur = self.parse_fn_purity();
let ident = self.parse_method_name(); let ident = self.parse_method_name();
let tps = self.parse_ty_params(); let tps = self.parse_ty_params();
...@@ -2072,7 +2069,7 @@ fn parse_mod_items(term: token::token, ...@@ -2072,7 +2069,7 @@ fn parse_mod_items(term: token::token,
let mut items: [@item] = []; let mut items: [@item] = [];
let mut first = true; let mut first = true;
while self.token != term { while self.token != term {
let mut attrs = parse_outer_attributes(self); let mut attrs = self.parse_outer_attributes();
if first { attrs = attrs_remaining + attrs; first = false; } if first { attrs = attrs_remaining + attrs; first = false; }
#debug["parse_mod_items: parse_item(attrs=%?)", attrs]; #debug["parse_mod_items: parse_item(attrs=%?)", attrs];
let vis = self.parse_visibility(private); let vis = self.parse_visibility(private);
...@@ -2107,7 +2104,7 @@ fn parse_item_const() -> item_info { ...@@ -2107,7 +2104,7 @@ fn parse_item_const() -> item_info {
fn parse_item_mod() -> item_info { fn parse_item_mod() -> item_info {
let id = self.parse_ident(); let id = self.parse_ident();
self.expect(token::LBRACE); self.expect(token::LBRACE);
let inner_attrs = parse_inner_attrs_and_next(self); let inner_attrs = self.parse_inner_attrs_and_next();
let m = self.parse_mod_items(token::RBRACE, inner_attrs.next); let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
self.expect(token::RBRACE); self.expect(token::RBRACE);
(id, item_mod(m), some(inner_attrs.inner)) (id, item_mod(m), some(inner_attrs.inner))
...@@ -2152,7 +2149,7 @@ fn parse_native_mod_items(+first_item_attrs: [attribute]) -> ...@@ -2152,7 +2149,7 @@ fn parse_native_mod_items(+first_item_attrs: [attribute]) ->
let mut items: [@native_item] = []; let mut items: [@native_item] = [];
let mut initial_attrs = attrs_remaining; let mut initial_attrs = attrs_remaining;
while self.token != token::RBRACE { while self.token != token::RBRACE {
let attrs = initial_attrs + parse_outer_attributes(self); let attrs = initial_attrs + self.parse_outer_attributes();
initial_attrs = []; initial_attrs = [];
items += [self.parse_native_item(attrs)]; items += [self.parse_native_item(attrs)];
} }
...@@ -2164,7 +2161,7 @@ fn parse_item_native_mod() -> item_info { ...@@ -2164,7 +2161,7 @@ fn parse_item_native_mod() -> item_info {
self.expect_keyword("mod"); self.expect_keyword("mod");
let id = self.parse_ident(); let id = self.parse_ident();
self.expect(token::LBRACE); self.expect(token::LBRACE);
let more_attrs = parse_inner_attrs_and_next(self); let more_attrs = self.parse_inner_attrs_and_next();
let m = self.parse_native_mod_items(more_attrs.next); let m = self.parse_native_mod_items(more_attrs.next);
self.expect(token::RBRACE); self.expect(token::RBRACE);
(id, item_native_mod(m), some(more_attrs.inner)) (id, item_native_mod(m), some(more_attrs.inner))
...@@ -2221,7 +2218,7 @@ fn parse_item_enum(default_vis: visibility) -> item_info { ...@@ -2221,7 +2218,7 @@ fn parse_item_enum(default_vis: visibility) -> item_info {
let mut all_nullary = true, have_disr = false; let mut all_nullary = true, have_disr = false;
while self.token != token::RBRACE { while self.token != token::RBRACE {
let variant_attrs = parse_outer_attributes(self); let variant_attrs = self.parse_outer_attributes();
let vlo = self.span.lo; let vlo = self.span.lo;
let vis = self.parse_visibility(default_vis); let vis = self.parse_visibility(default_vis);
let ident = self.parse_value_ident(); let ident = self.parse_value_ident();
...@@ -2331,7 +2328,7 @@ fn parse_item(+attrs: [attribute], vis: visibility) ...@@ -2331,7 +2328,7 @@ fn parse_item(+attrs: [attribute], vis: visibility)
fn parse_use() -> view_item_ { fn parse_use() -> view_item_ {
let ident = self.parse_ident(); let ident = self.parse_ident();
let metadata = parse_optional_meta(self); let metadata = self.parse_optional_meta();
ret view_item_use(ident, metadata, self.get_id()); ret view_item_use(ident, metadata, self.get_id());
} }
...@@ -2439,12 +2436,12 @@ fn parse_view_item(+attrs: [attribute]) -> @view_item { ...@@ -2439,12 +2436,12 @@ fn parse_view_item(+attrs: [attribute]) -> @view_item {
fn parse_view(+first_item_attrs: [attribute], fn parse_view(+first_item_attrs: [attribute],
only_imports: bool) -> {attrs_remaining: [attribute], only_imports: bool) -> {attrs_remaining: [attribute],
view_items: [@view_item]} { view_items: [@view_item]} {
let mut attrs = first_item_attrs + parse_outer_attributes(self); let mut attrs = first_item_attrs + self.parse_outer_attributes();
let mut items = []; let mut items = [];
while if only_imports { self.is_keyword("import") } while if only_imports { self.is_keyword("import") }
else { self.is_view_item() } { else { self.is_view_item() } {
items += [self.parse_view_item(attrs)]; items += [self.parse_view_item(attrs)];
attrs = parse_outer_attributes(self); attrs = self.parse_outer_attributes();
} }
{attrs_remaining: attrs, view_items: items} {attrs_remaining: attrs, view_items: items}
} }
...@@ -2452,7 +2449,7 @@ fn parse_view(+first_item_attrs: [attribute], ...@@ -2452,7 +2449,7 @@ fn parse_view(+first_item_attrs: [attribute],
// Parses a source module as a crate // Parses a source module as a crate
fn parse_crate_mod(_cfg: crate_cfg) -> @crate { fn parse_crate_mod(_cfg: crate_cfg) -> @crate {
let lo = self.span.lo; let lo = self.span.lo;
let crate_attrs = parse_inner_attrs_and_next(self); let crate_attrs = self.parse_inner_attrs_and_next();
let first_item_outer_attrs = crate_attrs.next; let first_item_outer_attrs = crate_attrs.next;
let m = self.parse_mod_items(token::EOF, first_item_outer_attrs); let m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
ret @spanned(lo, self.span.lo, ret @spanned(lo, self.span.lo,
...@@ -2481,7 +2478,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) -> ...@@ -2481,7 +2478,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) ->
crate_directive { crate_directive {
// Collect the next attributes // Collect the next attributes
let outer_attrs = first_outer_attr + parse_outer_attributes(self); let outer_attrs = first_outer_attr + self.parse_outer_attributes();
// In a crate file outer attributes are only going to apply to mods // In a crate file outer attributes are only going to apply to mods
let expect_mod = vec::len(outer_attrs) > 0u; let expect_mod = vec::len(outer_attrs) > 0u;
...@@ -2499,7 +2496,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) -> ...@@ -2499,7 +2496,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) ->
// mod x = "foo_dir" { ...directives... } // mod x = "foo_dir" { ...directives... }
token::LBRACE { token::LBRACE {
self.bump(); self.bump();
let inner_attrs = parse_inner_attrs_and_next(self); let inner_attrs = self.parse_inner_attrs_and_next();
let mod_attrs = outer_attrs + inner_attrs.inner; let mod_attrs = outer_attrs + inner_attrs.inner;
let next_outer_attr = inner_attrs.next; let next_outer_attr = inner_attrs.next;
let cdirs = self.parse_crate_directives(token::RBRACE, let cdirs = self.parse_crate_directives(token::RBRACE,
......
...@@ -23,6 +23,7 @@ mod test { ...@@ -23,6 +23,7 @@ mod test {
fn parse_attributes(source: str) -> [ast::attribute] { fn parse_attributes(source: str) -> [ast::attribute] {
import syntax::parse; import syntax::parse;
import parse::parser; import parse::parser;
import parse::attr::parser_attr;
import syntax::codemap; import syntax::codemap;
import syntax::diagnostic; import syntax::diagnostic;
...@@ -38,7 +39,7 @@ fn parse_attributes(source: str) -> [ast::attribute] { ...@@ -38,7 +39,7 @@ fn parse_attributes(source: str) -> [ast::attribute] {
let parser = parse::new_parser_from_source_str( let parser = parse::new_parser_from_source_str(
parse_sess, [], "-", codemap::fss_none, @source); parse_sess, [], "-", codemap::fss_none, @source);
parse::attr::parse_outer_attributes(parser) parser.parse_outer_attributes()
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册