This commit is contained in:
Adolfo Ochagavía 2015-01-18 17:18:29 +01:00
parent dcaeb6aa23
commit e3d099de6f

View File

@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use ast::{TokenTree, TtDelimited, TtSequence, TtToken}; use ast::{self, TokenTree, TtDelimited, TtSequence, TtToken};
use ast;
use codemap::{Span, DUMMY_SP}; use codemap::{Span, DUMMY_SP};
use ext::base::{ExtCtxt, MacResult, SyntaxExtension}; use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
use ext::base::{NormalTT, TTMacroExpander}; use ext::base::{NormalTT, TTMacroExpander};
@ -19,9 +18,8 @@ use ext::tt::macro_parser::{parse, parse_or_else};
use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag}; use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
use parse::parser::Parser; use parse::parser::Parser;
use parse::attr::ParserAttr; use parse::attr::ParserAttr;
use parse::token::{special_idents, gensym_ident, NtTT, Token}; use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
use parse::token::Token::*; use parse::token::Token::*;
use parse::token;
use print; use print;
use ptr::P; use ptr::P;
@ -333,16 +331,20 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() }; let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
// If T' is in the set FOLLOW(NT), continue. Else, reject. // If T' is in the set FOLLOW(NT), continue. Else, reject.
match &next_token { match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
&Eof => return Some((sp, tok.clone())), (&Eof, _) => return Some((sp, tok.clone())),
_ if is_in_follow(cx, &next_token, frag_spec.as_str()) => continue, (_, Ok(true)) => continue,
next => { (next, Ok(false)) => {
cx.span_err(sp, format!("`${0}:{1}` is followed by `{2}`, which \ cx.span_err(sp, format!("`${0}:{1}` is followed by `{2}`, which \
is not allowed for `{1}` fragments", is not allowed for `{1}` fragments",
name.as_str(), frag_spec.as_str(), name.as_str(), frag_spec.as_str(),
token_to_string(next)).as_slice()); token_to_string(next)).as_slice());
continue continue
}, },
(_, Err(msg)) => {
cx.span_err(sp, msg.as_slice());
continue
}
} }
}, },
TtSequence(sp, ref seq) => { TtSequence(sp, ref seq) => {
@ -409,12 +411,12 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
last last
} }
fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool { fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result<bool, String> {
if let &CloseDelim(_) = tok { if let &CloseDelim(_) = tok {
return true; return Ok(true);
} }
match frag { Ok(match frag {
"item" => { "item" => {
// since items *must* be followed by either a `;` or a `}`, we can // since items *must* be followed by either a `;` or a `}`, we can
// accept anything after them // accept anything after them
@ -453,7 +455,6 @@ fn is_in_follow(cx: &ExtCtxt, tok: &Token, frag: &str) -> bool {
// harmless // harmless
true true
}, },
_ => cx.bug(format!("unrecognized builtin nonterminal {}", _ => return Err(format!("unrecognized builtin nonterminal `{}`", frag)),
frag).as_slice()), })
}
} }