diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-04-19 20:51:31 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-04-19 21:58:45 -0700 |
| commit | 628e80d525392ebbcb889bb5d9b37e73c82d335a (patch) | |
| tree | 214d3f46dcb90a112012cacf6764e6ced9f092a4 /src | |
| parent | 3d6c79109e869de58d6545f683b3e796237039fb (diff) | |
| download | rust-628e80d525392ebbcb889bb5d9b37e73c82d335a.tar.gz rust-628e80d525392ebbcb889bb5d9b37e73c82d335a.zip | |
syntax: Extract attribute parsing to its own mod
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustsyntax/parse.rs | 2 | ||||
| -rw-r--r-- | src/librustsyntax/parse/attr.rs | 123 | ||||
| -rw-r--r-- | src/librustsyntax/parse/eval.rs | 5 | ||||
| -rw-r--r-- | src/librustsyntax/parse/parser.rs | 122 | ||||
| -rw-r--r-- | src/librustsyntax/rustsyntax.rc | 2 | ||||
| -rw-r--r-- | src/rustdoc/attr_parser.rs | 2 |
6 files changed, 140 insertions, 116 deletions
diff --git a/src/librustsyntax/parse.rs b/src/librustsyntax/parse.rs index dd8caa9a5cc..6482e28a0c8 100644 --- a/src/librustsyntax/parse.rs +++ b/src/librustsyntax/parse.rs @@ -86,7 +86,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 = parser::parse_inner_attrs_and_next(p); + let leading_attrs = attr::parse_inner_attrs_and_next(p); let crate_attrs = leading_attrs.inner; let first_cdir_attr = leading_attrs.next; let cdirs = parser::parse_crate_directives( diff --git a/src/librustsyntax/parse/attr.rs b/src/librustsyntax/parse/attr.rs new file mode 100644 index 00000000000..7994ba00b1d --- /dev/null +++ b/src/librustsyntax/parse/attr.rs @@ -0,0 +1,123 @@ +import either::{either, left, right}; +import parser::{parse_seq, + seq_sep, + expect, + parse_lit, + parse_ident, + parse_syntax_ext_naked, + spanned}; + +export attr_or_ext; +export parse_outer_attributes; +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 +// 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(parse_syntax_ext_naked(p, lo))); + } 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 { + attrs += [parse_attribute(p, ast::attr_outer)]; + } + ret attrs; +} + +fn parse_attribute(p: parser, style: ast::attr_style) -> ast::attribute { + let lo = p.span.lo; + expect(p, token::POUND); + ret parse_attribute_naked(p, style, lo); +} + +fn parse_attribute_naked(p: parser, style: ast::attr_style, lo: uint) -> + ast::attribute { + expect(p, token::LBRACKET); + let meta_item = parse_meta_item(p); + expect(p, token::RBRACKET); + let mut hi = p.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; + } + 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(p: parser) -> @ast::meta_item { + let lo = p.span.lo; + let ident = parse_ident(p); + alt p.token { + token::EQ { + p.bump(); + let lit = parse_lit(p); + 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] { + ret parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA), + parse_meta_item, p).node; +} + +fn parse_optional_meta(p: parser) -> [@ast::meta_item] { + alt p.token { token::LPAREN { ret parse_meta_seq(p); } _ { ret []; } } +} diff --git a/src/librustsyntax/parse/eval.rs b/src/librustsyntax/parse/eval.rs index d518c93a8ba..bf4e9f798d6 100644 --- a/src/librustsyntax/parse/eval.rs +++ b/src/librustsyntax/parse/eval.rs @@ -1,7 +1,6 @@ -import attr; import parser::{parser, - parse_inner_attrs_and_next, parse_mod_items, SOURCE_FILE}; +import attr::parse_inner_attrs_and_next; export eval_crate_directives_to_mod; @@ -81,7 +80,7 @@ fn parse_companion_mod(cx: ctx, prefix: str, suffix: option<str>) } fn cdir_path_opt(id: str, attrs: [ast::attribute]) -> str { - alt attr::first_attr_value_str_by_name(attrs, "path") { + alt ::attr::first_attr_value_str_by_name(attrs, "path") { some(d) { ret d; } diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs index d891275db5d..013357dff15 100644 --- a/src/librustsyntax/parse/parser.rs +++ b/src/librustsyntax/parse/parser.rs @@ -8,6 +8,10 @@ import ast::spanned; import ast_util::{mk_sp, ident_to_path}; import lexer::reader; import prec::{op_spec, as_prec}; +import attr::{parse_outer_attrs_or_ext, + parse_inner_attrs_and_next, + parse_outer_attributes, + parse_optional_meta}; export expect; export file_type; @@ -17,14 +21,19 @@ export parser; export parse_crate_directives; export parse_crate_mod; export parse_expr; -export parse_inner_attrs_and_next; export parse_item; export parse_mod_items; -export parse_outer_attributes; export parse_pat; +export parse_seq; export parse_stmt; export parse_ty; +export spanned; +export seq_sep; +export parse_lit; +export parse_ident; +export parse_syntax_ext_naked; + // FIXME: #ast expects to find this here but it's actually defined in `parse` // Fixing this will be easier when we have export decls on individual items -- // then parse can export this publicly, and everything else crate-visibly. @@ -2385,115 +2394,6 @@ fn parse_item(p: parser, attrs: [ast::attribute]) -> option<@ast::item> { else { ret none; } } -// 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(parse_syntax_ext_naked(p, lo))); - } 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 { - attrs += [parse_attribute(p, ast::attr_outer)]; - } - ret attrs; -} - -fn parse_attribute(p: parser, style: ast::attr_style) -> ast::attribute { - let lo = p.span.lo; - expect(p, token::POUND); - ret parse_attribute_naked(p, style, lo); -} - -fn parse_attribute_naked(p: parser, style: ast::attr_style, lo: uint) -> - ast::attribute { - expect(p, token::LBRACKET); - let meta_item = parse_meta_item(p); - expect(p, token::RBRACKET); - let mut hi = p.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; - } - 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(p: parser) -> @ast::meta_item { - let lo = p.span.lo; - let ident = parse_ident(p); - alt p.token { - token::EQ { - p.bump(); - let lit = parse_lit(p); - 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] { - ret parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA), - parse_meta_item, p).node; -} - -fn parse_optional_meta(p: parser) -> [@ast::meta_item] { - alt p.token { token::LPAREN { ret parse_meta_seq(p); } _ { ret []; } } -} - fn parse_use(p: parser) -> ast::view_item_ { let ident = parse_ident(p); let metadata = parse_optional_meta(p); diff --git a/src/librustsyntax/rustsyntax.rc b/src/librustsyntax/rustsyntax.rc index 68a41985aa6..5a479269244 100644 --- a/src/librustsyntax/rustsyntax.rc +++ b/src/librustsyntax/rustsyntax.rc @@ -28,12 +28,14 @@ mod parse { export comments; export prec; export classify; + export attr; mod eval; mod lexer; mod parser; mod token; mod comments; + mod attr; #[doc = "Functions dealing with operator precedence"] mod prec; diff --git a/src/rustdoc/attr_parser.rs b/src/rustdoc/attr_parser.rs index aa3b8c550dd..73bd801c1cc 100644 --- a/src/rustdoc/attr_parser.rs +++ b/src/rustdoc/attr_parser.rs @@ -38,7 +38,7 @@ mod test { let parser = parse::new_parser_from_source_str( parse_sess, [], "-", codemap::fss_none, @source); - parser::parse_outer_attributes(parser) + parse::attr::parse_outer_attributes(parser) } } |
