about summary refs log tree commit diff
path: root/src/comp/syntax/parse/parser.rs
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-02-17 23:05:20 -0800
committerGraydon Hoare <graydon@mozilla.com>2012-02-17 23:05:20 -0800
commitef6f6285893ca2546d740771b4c8046bfa68f668 (patch)
tree78c00965b1b06d7920ab4a64097bbf9c8b635b78 /src/comp/syntax/parse/parser.rs
parent6f708968549b346611e8172b02612f3c32ca4feb (diff)
downloadrust-ef6f6285893ca2546d740771b4c8046bfa68f668.tar.gz
rust-ef6f6285893ca2546d740771b4c8046bfa68f668.zip
Refactor view_path to parse (but not yet process) export globs, unify code paths.
Diffstat (limited to 'src/comp/syntax/parse/parser.rs')
-rw-r--r--src/comp/syntax/parse/parser.rs183
1 files changed, 64 insertions, 119 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 1e21dff0b34..eb34fb4b89d 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -202,7 +202,7 @@ fn parse_ident(p: parser) -> ast::ident {
     }
 }
 
-fn parse_import_ident(p: parser) -> ast::import_ident {
+fn parse_path_list_ident(p: parser) -> ast::path_list_ident {
     let lo = p.span.lo;
     let ident = parse_ident(p);
     let hi = p.span.hi;
@@ -2421,139 +2421,80 @@ fn parse_use(p: parser) -> ast::view_item_ {
     ret ast::view_item_use(ident, metadata, p.get_id());
 }
 
-fn parse_rest_import_name(p: parser, first: ast::ident,
-                          def_ident: option<ast::ident>) ->
-   ast::view_item_ {
-    let identifiers: [ast::ident] = [first];
-    let glob: bool = false;
-    let from_idents = option::none::<[ast::import_ident]>;
-    while true {
-        alt p.token {
-          token::SEMI { break; }
-          token::MOD_SEP {
-            if glob { p.fatal("cannot path into a glob"); }
-            if option::is_some(from_idents) {
-                p.fatal("cannot path into import list");
-            }
+fn parse_view_path(p: parser) -> @ast::view_path {
+    let lo = p.span.lo;
+    let first_ident = parse_ident(p);
+    let path = [first_ident];
+    #debug("parsed view_path: %s", first_ident);
+    alt p.token {
+      token::EQ {
+        // x = foo::bar
+        p.bump();
+        path = [parse_ident(p)];
+        while p.token == token::MOD_SEP {
             p.bump();
-          }
-          _ { p.fatal("expecting '::' or ';'"); }
+            let id = parse_ident(p);
+            path += [id];
         }
-        alt p.token {
-          token::IDENT(_, _) { identifiers += [parse_ident(p)]; }
-
-
-
-
+        let hi = p.span.hi;
+        ret @spanned(lo, hi,
+                     ast::view_path_simple(first_ident,
+                                           @path, p.get_id()));
+      }
 
-          //the lexer can't tell the different kinds of stars apart ) :
-          token::BINOP(token::STAR) {
-            glob = true;
+      token::MOD_SEP {
+        // foo::bar or foo::{a,b,c} or foo::*
+        while p.token == token::MOD_SEP {
             p.bump();
-          }
 
+            alt p.token {
 
+              token::IDENT(i, _) {
+                p.bump();
+                path += [p.get_str(i)];
+              }
 
+              // foo::bar::{a,b,c}
+              token::LBRACE {
+                let idents =
+                    parse_seq(token::LBRACE, token::RBRACE,
+                              seq_sep(token::COMMA),
+                              parse_path_list_ident, p).node;
+                let hi = p.span.hi;
+                ret @spanned(lo, hi,
+                             ast::view_path_list(@path, idents,
+                                                 p.get_id()));
+              }
 
+              // foo::bar::*
+              token::BINOP(token::STAR) {
+                p.bump();
+                let hi = p.span.hi;
+                ret @spanned(lo, hi,
+                             ast::view_path_glob(@path,
+                                                 p.get_id()));
+              }
 
-          token::LBRACE {
-            let from_idents_ =
-                parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA),
-                          parse_import_ident, p).node;
-            if vec::is_empty(from_idents_) {
-                p.fatal("at least one import is required");
+              _ { break; }
             }
-            from_idents = some(from_idents_);
-          }
-
-
-
-
-
-          _ {
-            p.fatal("expecting an identifier, or '*'");
-          }
-        }
-    }
-    alt def_ident {
-      some(i) {
-        if glob { p.fatal("globbed imports can't be renamed"); }
-        if option::is_some(from_idents) {
-            p.fatal("can't rename import list");
-        }
-        ret ast::view_item_import(i, @identifiers, p.get_id());
-      }
-      _ {
-        if glob {
-            ret ast::view_item_import_glob(@identifiers, p.get_id());
-        } else if option::is_some(from_idents) {
-            ret ast::view_item_import_from(@identifiers,
-                                           option::get(from_idents),
-                                           p.get_id());
-        } else {
-            let len = vec::len(identifiers);
-            ret ast::view_item_import(identifiers[len - 1u], @identifiers,
-                                      p.get_id());
         }
       }
+      _ { }
     }
+    let hi = p.span.hi;
+    let last = path[vec::len(path) - 1u];
+    ret @spanned(lo, hi,
+                 ast::view_path_simple(last, @path,
+                                       p.get_id()));
 }
 
-fn parse_full_import_name(p: parser, def_ident: ast::ident) ->
-   ast::view_item_ {
-    alt p.token {
-      token::IDENT(i, _) {
+fn parse_view_paths(p: parser) -> [@ast::view_path] {
+    let vp = [parse_view_path(p)];
+    while p.token == token::COMMA {
         p.bump();
-        ret parse_rest_import_name(p, p.get_str(i), some(def_ident));
-      }
-      _ { p.fatal("expecting an identifier"); }
-    }
-}
-
-fn parse_import(p: parser) -> ast::view_item_ {
-    alt p.token {
-      token::IDENT(i, _) {
-        p.bump();
-        alt p.token {
-          token::EQ {
-            p.bump();
-            ret parse_full_import_name(p, p.get_str(i));
-          }
-          _ { ret parse_rest_import_name(p, p.get_str(i), none); }
-        }
-      }
-      _ { p.fatal("expecting an identifier"); }
-    }
-}
-
-fn parse_enum_export(p:parser, tyname:ast::ident) -> ast::view_item_ {
-    let enumnames:[ast::import_ident] =
-        parse_seq(token::LBRACE, token::RBRACE,
-             seq_sep(token::COMMA), {|p| parse_import_ident(p) }, p).node;
-    let id = p.get_id();
-    if vec::is_empty(enumnames) {
-       ret ast::view_item_export_enum_none(tyname, id);
-    }
-    else {
-       ret ast::view_item_export_enum_some(tyname, enumnames, id);
-    }
-}
-
-fn parse_export(p: parser) -> ast::view_item_ {
-    let first = parse_ident(p);
-    alt p.token {
-       token::MOD_SEP {
-           p.bump();
-           ret parse_enum_export(p, first);
-       }
-       t {
-           if t == token::COMMA { p.bump(); }
-           let ids =
-               parse_seq_to_before_end(token::SEMI, seq_sep(token::COMMA),
-                                       parse_ident, p);
-           ret ast::view_item_export(vec::concat([[first], ids]), p.get_id());
-       }
+        vp += [parse_view_path(p)];
     }
+    ret vp;
 }
 
 fn parse_view_item(p: parser) -> @ast::view_item {
@@ -2562,8 +2503,12 @@ fn parse_view_item(p: parser) -> @ast::view_item {
         if eat_word(p, "use") {
             parse_use(p)
         } else if eat_word(p, "import") {
-            parse_import(p)
-        } else if eat_word(p, "export") { parse_export(p) } else { fail };
+            ast::view_item_import(parse_view_paths(p))
+        } else if eat_word(p, "export") {
+            ast::view_item_export(parse_view_paths(p))
+        } else {
+            fail
+    };
     let hi = p.span.lo;
     expect(p, token::SEMI);
     ret @spanned(lo, hi, the_item);