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

Access parse/attrs.rs with an impl.

上级 09652c8f
......@@ -13,6 +13,7 @@
export parse_from_source_str;
import parser::parser;
import attr::parser_attr;
import common::parser_common;
import ast::node_id;
import util::interner;
......@@ -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 lo = p.span.lo;
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 first_cdir_attr = leading_attrs.next;
let cdirs = p.parse_crate_directives(token::EOF, first_cdir_attr);
......
......@@ -3,116 +3,130 @@
import common::{parser_common, seq_sep};
export attr_or_ext;
export parse_outer_attributes;
export parse_outer_attrs_or_ext;
export parse_inner_attrs_and_next;
export parse_optional_meta;
export parser_attr;
// A type to distingush between the parsing of item attributes or syntax
// extensions, which both begin with token.POUND
type attr_or_ext = option<either<[ast::attribute], @ast::expr>>;
fn parse_outer_attrs_or_ext(
p: parser,
first_item_attrs: [ast::attribute]) -> attr_or_ext {
let expect_item_next = vec::is_not_empty(first_item_attrs);
if p.token == token::POUND {
let lo = p.span.lo;
if p.look_ahead(1u) == token::LBRACKET {
p.bump();
let first_attr = parse_attribute_naked(p, ast::attr_outer, lo);
ret some(left([first_attr] + parse_outer_attributes(p)));
} else if !(p.look_ahead(1u) == token::LT
|| p.look_ahead(1u) == token::LBRACKET
|| expect_item_next) {
p.bump();
ret some(right(p.parse_syntax_ext_naked(lo)));
impl parser_attr for parser {
fn parse_outer_attrs_or_ext(first_item_attrs: [ast::attribute])
-> attr_or_ext
{
let expect_item_next = vec::is_not_empty(first_item_attrs);
if self.token == token::POUND {
let lo = self.span.lo;
if self.look_ahead(1u) == token::LBRACKET {
self.bump();
let first_attr =
self.parse_attribute_naked(ast::attr_outer, lo);
ret some(left([first_attr] + self.parse_outer_attributes()));
} else if !(self.look_ahead(1u) == token::LT
|| 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; }
}
}
// Parse attributes that appear before an item
fn parse_outer_attributes(p: parser) -> [ast::attribute] {
let mut attrs: [ast::attribute] = [];
while p.token == token::POUND && p.look_ahead(1u) == token::LBRACKET {
attrs += [parse_attribute(p, ast::attr_outer)];
// Parse attributes that appear before an item
fn parse_outer_attributes() -> [ast::attribute] {
let mut attrs: [ast::attribute] = [];
while self.token == token::POUND
&& 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 {
let lo = p.span.lo;
p.expect(token::POUND);
ret parse_attribute_naked(p, style, lo);
}
fn parse_attribute(style: ast::attr_style) -> ast::attribute {
let lo = self.span.lo;
self.expect(token::POUND);
ret self.parse_attribute_naked(style, lo);
}
fn parse_attribute_naked(p: parser, style: ast::attr_style, lo: uint) ->
ast::attribute {
p.expect(token::LBRACKET);
let meta_item = parse_meta_item(p);
p.expect(token::RBRACKET);
let mut hi = p.span.hi;
ret spanned(lo, hi, {style: style, value: *meta_item});
}
fn parse_attribute_naked(style: ast::attr_style, lo: uint) ->
ast::attribute {
self.expect(token::LBRACKET);
let meta_item = self.parse_meta_item();
self.expect(token::RBRACKET);
let mut hi = self.span.hi;
ret spanned(lo, hi, {style: style, value: *meta_item});
}
// Parse attributes that appear after the opening of an item, each terminated
// by a semicolon. In addition to a vector of inner attributes, this function
// also returns a vector that may contain the first outer attribute of the
// next item (since we can't know whether the attribute is an inner attribute
// of the containing item or an outer attribute of the first contained item
// until we see the semi).
fn parse_inner_attrs_and_next(p: parser) ->
{inner: [ast::attribute], next: [ast::attribute]} {
let mut inner_attrs: [ast::attribute] = [];
let mut next_outer_attrs: [ast::attribute] = [];
while p.token == token::POUND {
if p.look_ahead(1u) != token::LBRACKET {
// This is an extension
break;
// Parse attributes that appear after the opening of an item, each
// terminated by a semicolon. In addition to a vector of inner attributes,
// this function also returns a vector that may contain the first outer
// attribute of the next item (since we can't know whether the attribute
// is an inner attribute of the containing item or an outer attribute of
// the first contained item until we see the semi).
fn parse_inner_attrs_and_next() ->
{inner: [ast::attribute], next: [ast::attribute]} {
let mut inner_attrs: [ast::attribute] = [];
let mut next_outer_attrs: [ast::attribute] = [];
while self.token == token::POUND {
if self.look_ahead(1u) != token::LBRACKET {
// This is an extension
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);
if p.token == token::SEMI {
p.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;
ret {inner: inner_attrs, next: next_outer_attrs};
}
fn parse_meta_item() -> @ast::meta_item {
let lo = self.span.lo;
let ident = self.parse_ident();
alt self.token {
token::EQ {
self.bump();
let lit = self.parse_lit();
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 {
let lo = p.span.lo;
let ident = p.parse_ident();
alt p.token {
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() -> [@ast::meta_item] {
ret self.parse_seq(token::LPAREN, token::RPAREN,
seq_sep(token::COMMA),
{|p| p.parse_meta_item()}).node;
}
}
fn parse_meta_seq(p: parser) -> [@ast::meta_item] {
ret p.parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA),
{|p| parse_meta_item(p)}).node;
fn parse_optional_meta() -> [@ast::meta_item] {
alt self.token { token::LPAREN { ret self.parse_meta_seq(); }
_ { 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 attr::parse_inner_attrs_and_next;
import attr::parser_attr;
export eval_crate_directives_to_mod;
......@@ -65,7 +65,7 @@ fn file_exists(path: str) -> bool {
if file_exists(modpath) {
#debug("found companion mod");
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 m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
cx.sess.chpos = p0.reader.chpos;
......@@ -97,7 +97,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str,
} else { prefix + path::path_sep() + file_path };
let p0 =
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 first_item_outer_attrs = inner_attrs.next;
let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
......
......@@ -8,10 +8,7 @@
import ast::*;
import lexer::reader;
import prec::{as_prec, token_to_binop};
import attr::{parse_outer_attrs_or_ext,
parse_inner_attrs_and_next,
parse_outer_attributes,
parse_optional_meta};
import attr::parser_attr;
import common::*;
import dvec::{dvec, extensions};
......@@ -168,7 +165,7 @@ fn parse_ty_fn() -> fn_decl {
fn parse_ty_methods() -> [ty_method] {
(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 pur = p.parse_fn_purity();
let ident = p.parse_method_name();
......@@ -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()));
} else {
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 = []; }
some(left(attrs)) { item_attrs = attrs; }
some(right(ext)) {
......@@ -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) ->
{inner: [attribute], next: [attribute]} {
if parse_attrs {
parse_inner_attrs_and_next(p)
p.parse_inner_attrs_and_next()
} else {
{inner: [], next: []}
}
......@@ -1832,7 +1829,7 @@ fn parse_method_name() -> ident {
}
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 ident = self.parse_method_name();
let tps = self.parse_ty_params();
......@@ -2072,7 +2069,7 @@ fn parse_mod_items(term: token::token,
let mut items: [@item] = [];
let mut first = true;
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; }
#debug["parse_mod_items: parse_item(attrs=%?)", attrs];
let vis = self.parse_visibility(private);
......@@ -2107,7 +2104,7 @@ fn parse_item_const() -> item_info {
fn parse_item_mod() -> item_info {
let id = self.parse_ident();
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);
self.expect(token::RBRACE);
(id, item_mod(m), some(inner_attrs.inner))
......@@ -2152,7 +2149,7 @@ fn parse_native_mod_items(+first_item_attrs: [attribute]) ->
let mut items: [@native_item] = [];
let mut initial_attrs = attrs_remaining;
while self.token != token::RBRACE {
let attrs = initial_attrs + parse_outer_attributes(self);
let attrs = initial_attrs + self.parse_outer_attributes();
initial_attrs = [];
items += [self.parse_native_item(attrs)];
}
......@@ -2164,7 +2161,7 @@ fn parse_item_native_mod() -> item_info {
self.expect_keyword("mod");
let id = self.parse_ident();
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);
self.expect(token::RBRACE);
(id, item_native_mod(m), some(more_attrs.inner))
......@@ -2221,7 +2218,7 @@ fn parse_item_enum(default_vis: visibility) -> item_info {
let mut all_nullary = true, have_disr = false;
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 vis = self.parse_visibility(default_vis);
let ident = self.parse_value_ident();
......@@ -2331,7 +2328,7 @@ fn parse_item(+attrs: [attribute], vis: visibility)
fn parse_use() -> view_item_ {
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());
}
......@@ -2439,12 +2436,12 @@ fn parse_view_item(+attrs: [attribute]) -> @view_item {
fn parse_view(+first_item_attrs: [attribute],
only_imports: bool) -> {attrs_remaining: [attribute],
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 = [];
while if only_imports { self.is_keyword("import") }
else { self.is_view_item() } {
items += [self.parse_view_item(attrs)];
attrs = parse_outer_attributes(self);
attrs = self.parse_outer_attributes();
}
{attrs_remaining: attrs, view_items: items}
}
......@@ -2452,7 +2449,7 @@ fn parse_view(+first_item_attrs: [attribute],
// Parses a source module as a crate
fn parse_crate_mod(_cfg: crate_cfg) -> @crate {
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 m = self.parse_mod_items(token::EOF, first_item_outer_attrs);
ret @spanned(lo, self.span.lo,
......@@ -2481,7 +2478,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) ->
crate_directive {
// 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
let expect_mod = vec::len(outer_attrs) > 0u;
......@@ -2499,7 +2496,7 @@ fn parse_crate_directive(first_outer_attr: [attribute]) ->
// mod x = "foo_dir" { ...directives... }
token::LBRACE {
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 next_outer_attr = inner_attrs.next;
let cdirs = self.parse_crate_directives(token::RBRACE,
......
......@@ -23,6 +23,7 @@ mod test {
fn parse_attributes(source: str) -> [ast::attribute] {
import syntax::parse;
import parse::parser;
import parse::attr::parser_attr;
import syntax::codemap;
import syntax::diagnostic;
......@@ -38,7 +39,7 @@ fn parse_attributes(source: str) -> [ast::attribute] {
let parser = parse::new_parser_from_source_str(
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.
先完成此消息的编辑!
想要评论请 注册