rollup merge of #19430: pczarn/interp_tt-cleanup
Conflicts: src/libsyntax/parse/parser.rs
This commit is contained in:
commit
0631b466c2
12 changed files with 170 additions and 103 deletions
|
|
@ -506,6 +506,17 @@ pub fn parse(sess: &ParseSess,
|
|||
}
|
||||
|
||||
pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
|
||||
match name {
|
||||
"tt" => {
|
||||
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
|
||||
let res = token::NtTT(P(p.parse_token_tree()));
|
||||
p.quote_depth -= 1u;
|
||||
return res;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// check at the beginning and the parser checks after each bump
|
||||
p.check_unknown_macro_variable();
|
||||
match name {
|
||||
"item" => match p.parse_item(Vec::new()) {
|
||||
Some(i) => token::NtItem(i),
|
||||
|
|
@ -529,12 +540,6 @@ pub fn parse_nt(p: &mut Parser, name: &str) -> Nonterminal {
|
|||
token::NtPath(box p.parse_path(LifetimeAndTypesWithoutColons))
|
||||
}
|
||||
"meta" => token::NtMeta(p.parse_meta_item()),
|
||||
"tt" => {
|
||||
p.quote_depth += 1u; //but in theory, non-quoted tts might be useful
|
||||
let res = token::NtTT(P(p.parse_token_tree()));
|
||||
p.quote_depth -= 1u;
|
||||
res
|
||||
}
|
||||
_ => {
|
||||
p.fatal(format!("unsupported builtin nonterminal parser: {}", name).index(&FullRange))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use ext::base::{NormalTT, TTMacroExpander};
|
|||
use ext::tt::macro_parser::{Success, Error, Failure};
|
||||
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
|
||||
use ext::tt::macro_parser::{parse, parse_or_else};
|
||||
use parse::lexer::new_tt_reader;
|
||||
use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
|
||||
use parse::parser::Parser;
|
||||
use parse::attr::ParserAttr;
|
||||
use parse::token::{special_idents, gensym_ident};
|
||||
|
|
@ -158,13 +158,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
|
|||
_ => cx.span_fatal(sp, "malformed macro lhs")
|
||||
};
|
||||
// `None` is because we're not interpolating
|
||||
let mut arg_rdr = new_tt_reader(&cx.parse_sess().span_diagnostic,
|
||||
None,
|
||||
None,
|
||||
arg.iter()
|
||||
.map(|x| (*x).clone())
|
||||
.collect());
|
||||
arg_rdr.desugar_doc_comments = true;
|
||||
let arg_rdr = new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
|
||||
None,
|
||||
None,
|
||||
arg.iter()
|
||||
.map(|x| (*x).clone())
|
||||
.collect(),
|
||||
true);
|
||||
match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
|
||||
Success(named_matches) => {
|
||||
let rhs = match *rhses[i] {
|
||||
|
|
@ -183,7 +183,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
|
|||
Some(named_matches),
|
||||
imported_from,
|
||||
rhs);
|
||||
let p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
|
||||
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
|
||||
p.check_unknown_macro_variable();
|
||||
// Let the context choose how to interpret the result.
|
||||
// Weird, but useful for X-macros.
|
||||
return box ParserAnyMacro {
|
||||
|
|
|
|||
|
|
@ -53,13 +53,28 @@ pub struct TtReader<'a> {
|
|||
}
|
||||
|
||||
/// This can do Macro-By-Example transcription. On the other hand, if
|
||||
/// `src` contains no `TtSequence`s and `TtNonterminal`s, `interp` can (and
|
||||
/// should) be none.
|
||||
/// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
|
||||
/// (and should) be None.
|
||||
pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
|
||||
interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
|
||||
imported_from: Option<Ident>,
|
||||
src: Vec<ast::TokenTree> )
|
||||
src: Vec<ast::TokenTree>)
|
||||
-> TtReader<'a> {
|
||||
new_tt_reader_with_doc_flag(sp_diag, interp, imported_from, src, false)
|
||||
}
|
||||
|
||||
/// The extra `desugar_doc_comments` flag enables reading doc comments
|
||||
/// like any other attribute which consists of `meta` and surrounding #[ ] tokens.
|
||||
///
|
||||
/// This can do Macro-By-Example transcription. On the other hand, if
|
||||
/// `src` contains no `TtSequence`s, `MatchNt`s or `SubstNt`s, `interp` can
|
||||
/// (and should) be None.
|
||||
pub fn new_tt_reader_with_doc_flag<'a>(sp_diag: &'a SpanHandler,
|
||||
interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
|
||||
imported_from: Option<Ident>,
|
||||
src: Vec<ast::TokenTree>,
|
||||
desugar_doc_comments: bool)
|
||||
-> TtReader<'a> {
|
||||
let mut r = TtReader {
|
||||
sp_diag: sp_diag,
|
||||
stack: vec!(TtFrame {
|
||||
|
|
@ -80,7 +95,7 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
|
|||
crate_name_next: None,
|
||||
repeat_idx: Vec::new(),
|
||||
repeat_len: Vec::new(),
|
||||
desugar_doc_comments: false,
|
||||
desugar_doc_comments: desugar_doc_comments,
|
||||
/* dummy values, never read: */
|
||||
cur_tok: token::Eof,
|
||||
cur_span: DUMMY_SP,
|
||||
|
|
@ -266,18 +281,15 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
|
|||
}
|
||||
// FIXME #2887: think about span stuff here
|
||||
TtToken(sp, SubstNt(ident, namep)) => {
|
||||
r.stack.last_mut().unwrap().idx += 1;
|
||||
match lookup_cur_matched(r, ident) {
|
||||
None => {
|
||||
r.stack.push(TtFrame {
|
||||
forest: TtToken(sp, SubstNt(ident, namep)),
|
||||
idx: 0,
|
||||
dotdotdoted: false,
|
||||
sep: None
|
||||
});
|
||||
r.cur_span = sp;
|
||||
r.cur_tok = SubstNt(ident, namep);
|
||||
return ret_val;
|
||||
// this can't be 0 length, just like TtDelimited
|
||||
}
|
||||
Some(cur_matched) => {
|
||||
r.stack.last_mut().unwrap().idx += 1;
|
||||
match *cur_matched {
|
||||
// sidestep the interpolation tricks for ident because
|
||||
// (a) idents can be in lots of places, so it'd be a pain
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue