Skip to content

Commit 62db570

Browse files
committed
Start letting the parser catch interpolated ASTs.
1 parent f940653 commit 62db570

File tree

6 files changed

+95
-6
lines changed

6 files changed

+95
-6
lines changed

src/libsyntax/ext/tt/earley_parser.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,11 @@ fn parse_nt(p: parser, name: str) -> whole_nt {
259259
"expr" { token::w_expr(p.parse_expr()) }
260260
"ty" { token::w_ty(p.parse_ty(false /* no need to disambiguate*/)) }
261261
// this could be handled like a token, since it is one
262-
"ident" { token::w_ident(p.parse_ident()) }
262+
"ident" { alt copy p.token {
263+
token::IDENT(sn,b) { p.bump(); token::w_ident(sn,b) }
264+
_ { p.fatal("expected ident, found "
265+
+ token::to_str(*p.reader.interner(), copy p.token)) }
266+
} }
263267
"path" { token::w_path(p.parse_path_with_tps(false)) }
264268
_ { p.fatal("Unsupported builtin nonterminal parser: " + name)}
265269
}

src/libsyntax/ext/tt/transcribe.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import diagnostic::span_handler;
33
import ast::{token_tree,tt_delim,tt_flat,tt_dotdotdot,tt_interpolate,ident};
44
import earley_parser::{arb_depth,seq,leaf};
55
import codemap::span;
6-
import parse::token::{EOF,ACTUALLY,token};
6+
import parse::token::{EOF,ACTUALLY,IDENT,token,w_ident};
77
import std::map::{hashmap,box_str_hash};
88

99
export tt_reader, new_tt_reader, dup_tt_reader, tt_next_token;
@@ -193,8 +193,17 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
193193
// TODO: think about span stuff here
194194
tt_interpolate(sp, ident) {
195195
alt *lookup_cur_ad(r, ident) {
196+
/* sidestep the interpolation tricks for ident because
197+
(a) idents can be in lots of places, so it'd be a pain
198+
(b) we actually can, since it's a token. */
199+
leaf(w_ident(sn,b)) {
200+
r.cur_span = sp; r.cur_tok = IDENT(sn,b);
201+
r.cur.idx += 1u;
202+
ret ret_val;
203+
}
196204
leaf(w_nt) {
197205
r.cur_span = sp; r.cur_tok = ACTUALLY(w_nt);
206+
r.cur.idx += 1u;
198207
ret ret_val;
199208
}
200209
seq(*) {

src/libsyntax/parse/common.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ impl parser_common for parser {
5050
fn parse_ident() -> ast::ident {
5151
alt copy self.token {
5252
token::IDENT(i, _) { self.bump(); ret self.get_str(i); }
53+
token::ACTUALLY(token::w_ident(*)) { self.bug(
54+
"ident interpolation not converted to real token"); }
5355
_ { self.fatal("expecting ident, found "
5456
+ token_to_str(self.reader, self.token)); }
5557
}

src/libsyntax/parse/lexer.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,7 @@ fn next_token_inner(rdr: string_reader) -> token::token {
459459
let is_mod_name = c == ':' && nextch(rdr) == ':';
460460

461461
// FIXME: perform NFKC normalization here. (Issue #2253)
462-
ret token::IDENT(intern(*rdr.interner,
463-
@accum_str), is_mod_name);
462+
ret token::IDENT(intern(*rdr.interner, @accum_str), is_mod_name);
464463
}
465464
if is_dec_digit(c) {
466465
ret scan_number(c, rdr);

src/libsyntax/parse/parser.rs

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import result::result;
22
import either::{either, left, right};
33
import std::map::{hashmap, str_hash};
4-
import token::{can_begin_expr, is_ident, is_plain_ident};
4+
import token::{can_begin_expr, is_ident, is_plain_ident, ACTUALLY};
55
import codemap::{span,fss_none};
66
import util::interner;
77
import ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec};
@@ -59,6 +59,78 @@ enum class_contents { ctor_decl(fn_decl, blk, codemap::span),
5959
type arg_or_capture_item = either<arg, capture_item>;
6060
type item_info = (ident, item_, option<~[attribute]>);
6161

62+
fn dummy() {
63+
64+
/* We need to position the macros to capture the ACTUALLY tokens before they
65+
get bumped away. So two bumps in a row is bad. (the first lookahead also
66+
counts as a bump).
67+
68+
Events happen L to R; 'B' indicates a bump before hand:
69+
._____________________________.________________________.
70+
↓ B| |
71+
parse_expr -> parse_expr_res -> parse_assign_expr |
72+
↓ |
73+
parse_binops -> parse_more_binops |
74+
↓ B↓ B|
75+
parse_prefix_expr B-> parse_dot_or_call_expr
76+
B|_↑ ↓
77+
parse_bottom_expr
78+
B↓
79+
⋯->parse_ident
80+
...so we've hit parse_prefix_expr, parse_more_binops, and parse_bottom_expr.
81+
*/
82+
83+
#macro[[#maybe_whole_item[p],
84+
alt copy p.token {
85+
ACTUALLY(token::w_item(i)) { p.bump(); ret i; }
86+
_ {} }]];
87+
#macro[[#maybe_whole_block[p],
88+
alt copy p.token {
89+
ACTUALLY(token::w_block(b)) { p.bump(); ret b; }
90+
_ {} }]];
91+
#macro[[#maybe_whole_stmt[p],
92+
alt copy p.token {
93+
ACTUALLY(token::w_stmt(s)) { p.bump(); ret s; }
94+
_ {} }]];
95+
#macro[[#maybe_whole_pat[p],
96+
alt copy p.token {
97+
ACTUALLY(token::w_pat(pt)) { p.bump(); ret pt; }
98+
_ {} }]];
99+
#macro[[#maybe_whole_expr[p],
100+
alt copy p.token {
101+
ACTUALLY(token::w_expr(e)) {
102+
p.bump();
103+
ret e;
104+
}
105+
ACTUALLY(token::w_path(pt)) {
106+
p.bump();
107+
ret p.mk_expr(p.span.lo, p.span.lo,
108+
expr_path(pt));
109+
}
110+
_ {} }]];
111+
#macro[[#maybe_whole_expr_pexpr[p], /* ack! */
112+
alt copy p.token {
113+
ACTUALLY(token::w_expr(e)) {
114+
p.bump();
115+
ret pexpr(e);
116+
}
117+
ACTUALLY(token::w_path(pt)) {
118+
p.bump();
119+
ret p.mk_pexpr(p.span.lo, p.span.lo,
120+
expr_path(pt));
121+
}
122+
_ {} }]];
123+
#macro[[#maybe_whole_ty[p],
124+
alt copy p.token {
125+
ACTUALLY(token::w_ty(t)) { p.bump(); ret t; }
126+
_ {} }]];
127+
/* ident is handled by common.rs */
128+
#macro[[#maybe_whole_path[p],
129+
alt p.token {
130+
ACTUALLY(token::w_path(pt)) { p.bump(); ret pt; }
131+
_ {} }]];
132+
}
133+
62134
class parser {
63135
let sess: parse_sess;
64136
let cfg: crate_cfg;
@@ -718,6 +790,7 @@ class parser {
718790
}
719791

720792
fn parse_bottom_expr() -> pexpr {
793+
#maybe_whole_expr_pexpr[self];
721794
let lo = self.span.lo;
722795
let mut hi = self.span.hi;
723796

@@ -1181,6 +1254,7 @@ class parser {
11811254

11821255

11831256
fn parse_prefix_expr() -> pexpr {
1257+
#maybe_whole_expr_pexpr[self];
11841258
let lo = self.span.lo;
11851259
let mut hi;
11861260

@@ -1258,6 +1332,7 @@ class parser {
12581332

12591333
fn parse_more_binops(plhs: pexpr, min_prec: uint) ->
12601334
@expr {
1335+
#maybe_whole_expr[self];
12611336
let lhs = self.to_expr(plhs);
12621337
if self.expr_is_complete(plhs) { ret lhs; }
12631338
let peeked = self.token;

src/libsyntax/parse/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ enum whole_nt {
9494
w_pat( @ast::pat),
9595
w_expr(@ast::expr),
9696
w_ty( @ast::ty),
97-
w_ident(ast::ident),
97+
w_ident(str_num, bool),
9898
w_path(@ast::path),
9999
}
100100

0 commit comments

Comments
 (0)