about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-07-05 17:33:39 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-07-05 18:09:31 -0700
commita8112f3b348645f6f487aaa1ae0918b719045f1b (patch)
treeba0e8358bfc4e18eadeb0b13d6164f20ff102681 /src/libsyntax
parent7f9b1fbe350ee16008f16f13254420da3679f60d (diff)
Allow soft failure of the macro parser.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/tt/earley_parser.rs29
-rw-r--r--src/libsyntax/parse/parser.rs8
2 files changed, 23 insertions, 14 deletions
diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs
index df988cd1a73..26db2842ef7 100644
--- a/src/libsyntax/ext/tt/earley_parser.rs
+++ b/src/libsyntax/ext/tt/earley_parser.rs
@@ -96,8 +96,13 @@ fn nameize(&&p_s: parse_sess, ms: ~[matcher], &&res: ~[@arb_depth])
     ret ret_val;
 }
 
+enum parse_result {
+    success(hashmap<ident, @arb_depth>),
+    failure(codemap::span, str)
+}
+
 fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
-    -> hashmap<ident,@arb_depth> {
+    -> parse_result {
     let mut cur_eis = ~[];
     vec::push(cur_eis, new_matcher_pos(ms, none, rdr.peek().sp.lo));
 
@@ -195,13 +200,14 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
 
         /* error messages here could be improved with links to orig. rules */
         if tok == EOF {
-            if eof_eis.len() == 1u { /* success */
-                ret nameize(sess, ms,
-                            vec::map(eof_eis[0u].matches, |dv| dv.pop()));
+            if eof_eis.len() == 1u {
+                ret success(
+                    nameize(sess, ms,
+                            vec::map(eof_eis[0u].matches, |dv| dv.pop())));
             } else if eof_eis.len() > 1u {
-                rdr.fatal("Ambiguity: multiple successful parses");
+                ret failure(sp, "Ambiguity: multiple successful parses");
             } else {
-                rdr.fatal("Unexpected end of macro invocation");
+                ret failure(sp, "Unexpected end of macro invocation");
             }
         } else {
             if (bb_eis.len() > 0u && next_eis.len() > 0u)
@@ -210,12 +216,13 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
                     alt ei.elts[ei.idx].node
                         { mtc_bb(_,name,_) { *name } _ { fail; } }
                 }), " or ");
-                rdr.fatal(#fmt["Local ambiguity: multiple parsing options: \
-                                built-in NTs %s or %u other options.",
-                              nts, next_eis.len()]);
+                ret failure(sp, #fmt[
+                    "Local ambiguity: multiple parsing options: \
+                     built-in NTs %s or %u other options.",
+                    nts, next_eis.len()]);
             } else if (bb_eis.len() == 0u && next_eis.len() == 0u) {
-                rdr.fatal("No rules expected the token "
-                          + to_str(*rdr.interner(), tok));
+                failure(sp, "No rules expected the token "
+                        + to_str(*rdr.interner(), tok));
             } else if (next_eis.len() > 0u) {
                 /* Now process the next token */
                 while(next_eis.len() > 0u) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ae3cbc141c2..8bac3e0d751 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1210,7 +1210,7 @@ class parser {
 
     /* temporary */
     fn parse_tt_mac_demo() -> @expr {
-
+        import ext::tt::earley_parser::{parse,success,failure};
         let name_idx = @mut 0u;
         let ms = self.parse_seq(token::LBRACE, token::RBRACE,
                                 common::seq_sep_none(),
@@ -1225,8 +1225,10 @@ class parser {
                                            self.reader.interner(), none, tts)
                 as reader;
 
-            let matches = ext::tt::earley_parser::parse
-                (self.sess, self.cfg, rdr, ms);
+            let matches = alt parse(self.sess, self.cfg, rdr, ms) {
+                  success(m) { m }
+                  failure(sp, msg) { self.span_fatal(sp,msg); }
+                };
 
             let transcriber = ext::tt::transcribe::new_tt_reader
                 (self.reader.span_diag(), self.reader.interner(),