1
Fork 0

Work towards a non-panicing parser (libsyntax)

- Functions in parser.rs return PResult<> rather than panicing
- Other functions in libsyntax call panic! explicitly for now if they rely on panicing behaviour.
- 'panictry!' macro added as scaffolding while converting panicing functions.
  (This does the same as 'unwrap()' but is easier to grep for and turn into try!())
- Leaves panicing wrappers for the following functions so that the
  quote_* macros behave the same:
  - parse_expr, parse_item, parse_pat, parse_arm, parse_ty, parse_stmt
This commit is contained in:
Phil Dawes 2015-03-28 21:58:51 +00:00
parent f73f3233f1
commit b2bcb7229a
23 changed files with 1412 additions and 1315 deletions

View file

@ -226,10 +226,10 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
}
Occupied(..) => {
let string = token::get_ident(bind_name);
p_s.span_diagnostic
panic!(p_s.span_diagnostic
.span_fatal(sp,
&format!("duplicated bind name: {}",
&string))
&string)))
}
}
}
@ -260,10 +260,10 @@ pub fn parse_or_else(sess: &ParseSess,
match parse(sess, cfg, rdr, &ms[..]) {
Success(m) => m,
Failure(sp, str) => {
sess.span_diagnostic.span_fatal(sp, &str[..])
panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
}
Error(sp, str) => {
sess.span_diagnostic.span_fatal(sp, &str[..])
panic!(sess.span_diagnostic.span_fatal(sp, &str[..]))
}
}
}
@ -512,46 +512,46 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
match name {
"tt" => {
p.quote_depth += 1; //but in theory, non-quoted tts might be useful
let res = token::NtTT(P(p.parse_token_tree()));
let res = token::NtTT(P(panictry!(p.parse_token_tree())));
p.quote_depth -= 1;
return res;
}
_ => {}
}
// check at the beginning and the parser checks after each bump
p.check_unknown_macro_variable();
panictry!(p.check_unknown_macro_variable());
match name {
"item" => match p.parse_item() {
Some(i) => token::NtItem(i),
None => p.fatal("expected an item keyword")
None => panic!(p.fatal("expected an item keyword"))
},
"block" => token::NtBlock(p.parse_block()),
"block" => token::NtBlock(panictry!(p.parse_block())),
"stmt" => match p.parse_stmt() {
Some(s) => token::NtStmt(s),
None => p.fatal("expected a statement")
None => panic!(p.fatal("expected a statement"))
},
"pat" => token::NtPat(p.parse_pat()),
"expr" => token::NtExpr(p.parse_expr()),
"ty" => token::NtTy(p.parse_ty()),
// this could be handled like a token, since it is one
"ident" => match p.token {
token::Ident(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(box sn,b) }
_ => {
let token_str = pprust::token_to_string(&p.token);
p.fatal(&format!("expected ident, found {}",
&token_str[..]))
panic!(p.fatal(&format!("expected ident, found {}",
&token_str[..])))
}
},
"path" => {
token::NtPath(box p.parse_path(LifetimeAndTypesWithoutColons))
token::NtPath(box panictry!(p.parse_path(LifetimeAndTypesWithoutColons)))
}
"meta" => token::NtMeta(p.parse_meta_item()),
_ => {
p.span_fatal_help(sp,
panic!(p.span_fatal_help(sp,
&format!("invalid fragment specifier `{}`", name),
"valid fragment specifiers are `ident`, `block`, \
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
and `item`")
and `item`"))
}
}
}