1
Fork 0

Allow soft failure of the macro parser.

This commit is contained in:
Paul Stansifer 2012-07-05 17:33:39 -07:00
parent 7f9b1fbe35
commit a8112f3b34
2 changed files with 23 additions and 14 deletions

View file

@ -96,8 +96,13 @@ fn nameize(&&p_s: parse_sess, ms: ~[matcher], &&res: ~[@arb_depth])
ret ret_val; 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]) fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
-> hashmap<ident,@arb_depth> { -> parse_result {
let mut cur_eis = ~[]; let mut cur_eis = ~[];
vec::push(cur_eis, new_matcher_pos(ms, none, rdr.peek().sp.lo)); 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 */ /* error messages here could be improved with links to orig. rules */
if tok == EOF { if tok == EOF {
if eof_eis.len() == 1u { /* success */ if eof_eis.len() == 1u {
ret nameize(sess, ms, ret success(
vec::map(eof_eis[0u].matches, |dv| dv.pop())); nameize(sess, ms,
vec::map(eof_eis[0u].matches, |dv| dv.pop())));
} else if eof_eis.len() > 1u { } else if eof_eis.len() > 1u {
rdr.fatal("Ambiguity: multiple successful parses"); ret failure(sp, "Ambiguity: multiple successful parses");
} else { } else {
rdr.fatal("Unexpected end of macro invocation"); ret failure(sp, "Unexpected end of macro invocation");
} }
} else { } else {
if (bb_eis.len() > 0u && next_eis.len() > 0u) if (bb_eis.len() > 0u && next_eis.len() > 0u)
@ -210,11 +216,12 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
alt ei.elts[ei.idx].node alt ei.elts[ei.idx].node
{ mtc_bb(_,name,_) { *name } _ { fail; } } { mtc_bb(_,name,_) { *name } _ { fail; } }
}), " or "); }), " or ");
rdr.fatal(#fmt["Local ambiguity: multiple parsing options: \ ret failure(sp, #fmt[
"Local ambiguity: multiple parsing options: \
built-in NTs %s or %u other options.", built-in NTs %s or %u other options.",
nts, next_eis.len()]); nts, next_eis.len()]);
} else if (bb_eis.len() == 0u && next_eis.len() == 0u) { } else if (bb_eis.len() == 0u && next_eis.len() == 0u) {
rdr.fatal("No rules expected the token " failure(sp, "No rules expected the token "
+ to_str(*rdr.interner(), tok)); + to_str(*rdr.interner(), tok));
} else if (next_eis.len() > 0u) { } else if (next_eis.len() > 0u) {
/* Now process the next token */ /* Now process the next token */

View file

@ -1210,7 +1210,7 @@ class parser {
/* temporary */ /* temporary */
fn parse_tt_mac_demo() -> @expr { fn parse_tt_mac_demo() -> @expr {
import ext::tt::earley_parser::{parse,success,failure};
let name_idx = @mut 0u; let name_idx = @mut 0u;
let ms = self.parse_seq(token::LBRACE, token::RBRACE, let ms = self.parse_seq(token::LBRACE, token::RBRACE,
common::seq_sep_none(), common::seq_sep_none(),
@ -1225,8 +1225,10 @@ class parser {
self.reader.interner(), none, tts) self.reader.interner(), none, tts)
as reader; as reader;
let matches = ext::tt::earley_parser::parse let matches = alt parse(self.sess, self.cfg, rdr, ms) {
(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 let transcriber = ext::tt::transcribe::new_tt_reader
(self.reader.span_diag(), self.reader.interner(), (self.reader.span_diag(), self.reader.interner(),