Skip to content

Commit 39590d8

Browse files
committed
Some rearranging in perparation for MBE-style TT transcription.
1 parent 74c2266 commit 39590d8

File tree

8 files changed

+198
-123
lines changed

8 files changed

+198
-123
lines changed

src/libsyntax/ast.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,17 @@ enum blk_sort {
374374
*/
375375

376376
#[auto_serialize]
377+
#[doc="For macro invocations; parsing is delegated to the macro"]
377378
enum token_tree {
378-
/* for macro invocations; parsing is the macro's job */
379379
tt_delim(~[token_tree]),
380-
tt_flat(span, token::token)
380+
tt_flat(span, token::token),
381+
/* These only make sense for right-hand-sides of MBE macros*/
382+
tt_dotdotdot(~[token_tree]),
383+
tt_interpolate(ident)
381384
}
382385

386+
387+
383388
#[auto_serialize]
384389
type matcher = spanned<matcher_>;
385390

src/libsyntax/ext/earley_parser.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// Earley-like parser for macros.
22
import parse::token;
33
import parse::token::{token, EOF, to_str, whole_nt};
4-
import parse::lexer::{reader, tt_reader, tt_reader_as_reader};
4+
import parse::lexer::*; //resolve bug?
5+
//import parse::lexer::{reader, tt_reader, tt_reader_as_reader};
56
import parse::parser::{parser,SOURCE_FILE};
6-
import parse::common::parser_common;
7+
//import parse::common::parser_common;
8+
import parse::common::*; //resolve bug?
79
import parse::parse_sess;
810
import dvec::{dvec, extensions};
9-
import ast::{matcher, mtc_tok, mtc_rep, mtc_bb};
11+
import ast::{matcher, mtc_tok, mtc_rep, mtc_bb, ident};
12+
import std::map::{hashmap, box_str_hash};
1013

1114
/* This is an Earley-like parser, without support for nonterminals. This
1215
means that there are no completer or predictor rules, and therefore no need to
@@ -66,8 +69,31 @@ enum arb_depth { leaf(whole_nt), seq(~[@arb_depth]) }
6669
type earley_item = matcher_pos;
6770

6871

72+
fn nameize(&&p_s: parse_sess, ms: ~[matcher], &&res: ~[@arb_depth])
73+
-> hashmap<ident,@arb_depth> {
74+
fn n_rec(&&p_s: parse_sess, &&m: matcher, &&res: ~[@arb_depth],
75+
&&ret_val: hashmap<ident, @arb_depth>) {
76+
alt m {
77+
{node: mtc_tok(_), span: _} { }
78+
{node: mtc_rep(more_ms, _, _), span: _} {
79+
for more_ms.each() |next_m| { n_rec(p_s, next_m, res, ret_val) };
80+
}
81+
{node: mtc_bb(bind_name, _, idx), span: sp} {
82+
if ret_val.contains_key(bind_name) {
83+
p_s.span_diagnostic.span_fatal(sp, "Duplicated bind name: "
84+
+ *bind_name)
85+
}
86+
ret_val.insert(bind_name, res[idx]);
87+
}
88+
}
89+
}
90+
let ret_val = box_str_hash::<@arb_depth>();
91+
for ms.each() |m| { n_rec(p_s, m, res, ret_val) };
92+
ret ret_val;
93+
}
94+
6995
fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
70-
-> ~[@arb_depth] {
96+
-> hashmap<ident,@arb_depth> {
7197
let mut cur_eis = ~[];
7298
vec::push(cur_eis, new_matcher_pos(ms, none));
7399

@@ -164,9 +190,9 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
164190

165191
/* error messages here could be improved with links to orig. rules */
166192
if tok == EOF {
167-
if eof_eis.len() == 1u {
168-
let ret_val = vec::map(eof_eis[0u].matches, |dv| dv.pop());
169-
ret ret_val; /* success */
193+
if eof_eis.len() == 1u { /* success */
194+
ret nameize(sess, ms,
195+
vec::map(eof_eis[0u].matches, |dv| dv.pop()));
170196
} else if eof_eis.len() > 1u {
171197
rdr.fatal("Ambiguity: multiple successful parses");
172198
} else {

src/libsyntax/ext/tt/transcribe.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import util::interner::interner;
2+
import diagnostic::span_handler;
3+
import ast::{tt_delim,tt_flat,tt_dotdotdot,tt_interpolate,ident};
4+
import ext::earley_parser::arb_depth;
5+
import codemap::span;
6+
import parse::token::{EOF,token};
7+
8+
export tt_reader, new_tt_reader, dup_tt_reader, tt_next_token;
9+
10+
enum tt_frame_up { /* to break a circularity */
11+
tt_frame_up(option<tt_frame>)
12+
}
13+
14+
/* TODO: figure out how to have a uniquely linked stack, and change to `~` */
15+
///an unzipping of `token_tree`s
16+
type tt_frame = @{
17+
readme: [ast::token_tree]/~,
18+
mut idx: uint,
19+
up: tt_frame_up
20+
};
21+
22+
type tt_reader = @{
23+
span_diagnostic: span_handler,
24+
interner: @interner<@str>,
25+
mut cur: tt_frame,
26+
/* for MBE-style macro transcription */
27+
interpolations: std::map::hashmap<ident, @arb_depth>,
28+
/* cached: */
29+
mut cur_tok: token,
30+
mut cur_span: span
31+
};
32+
33+
/** This can do Macro-By-Example transcription. On the other hand, if
34+
* `doc` contains no `tt_dotdotdot`s and `tt_interpolate`s, `interp` can (and
35+
* should) be none. */
36+
fn new_tt_reader(span_diagnostic: span_handler, itr: @interner<@str>,
37+
interp: option<std::map::hashmap<ident,@arb_depth>>,
38+
src: [ast::token_tree]/~)
39+
-> tt_reader {
40+
let r = @{span_diagnostic: span_diagnostic, interner: itr,
41+
mut cur: @{readme: src, mut idx: 0u,
42+
up: tt_frame_up(option::none)},
43+
interpolations: alt interp { /* just a convienience */
44+
none { std::map::box_str_hash::<@arb_depth>() }
45+
some(x) { x }
46+
},
47+
/* dummy values, never read: */
48+
mut cur_tok: EOF,
49+
mut cur_span: ast_util::mk_sp(0u,0u)
50+
};
51+
tt_next_token(r); /* get cur_tok and cur_span set up */
52+
ret r;
53+
}
54+
55+
pure fn dup_tt_frame(&&f: tt_frame) -> tt_frame {
56+
@{readme: f.readme, mut idx: f.idx,
57+
up: alt f.up {
58+
tt_frame_up(some(up_frame)) {
59+
tt_frame_up(some(dup_tt_frame(up_frame)))
60+
}
61+
tt_frame_up(none) { tt_frame_up(none) }
62+
}
63+
}
64+
}
65+
66+
pure fn dup_tt_reader(&&r: tt_reader) -> tt_reader {
67+
@{span_diagnostic: r.span_diagnostic, interner: r.interner,
68+
mut cur: dup_tt_frame(r.cur),
69+
interpolations: r.interpolations,
70+
mut cur_tok: r.cur_tok, mut cur_span: r.cur_span}
71+
}
72+
73+
74+
fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} {
75+
let ret_val = { tok: r.cur_tok, sp: r.cur_span };
76+
if r.cur.idx >= vec::len(r.cur.readme) {
77+
/* done with this set; pop */
78+
alt r.cur.up {
79+
tt_frame_up(none) {
80+
r.cur_tok = EOF;
81+
ret ret_val;
82+
}
83+
tt_frame_up(some(tt_f)) {
84+
r.cur = tt_f;
85+
/* the above `if` would need to be a `while` if we didn't know
86+
that the last thing in a `tt_delim` is always a `tt_flat` */
87+
r.cur.idx += 1u;
88+
}
89+
}
90+
}
91+
/* if `tt_delim`s could be 0-length, we'd need to be able to switch
92+
between popping and pushing until we got to an actual `tt_flat` */
93+
loop { /* because it's easiest, this handles `tt_delim` not starting
94+
with a `tt_flat`, even though it won't happen */
95+
alt copy r.cur.readme[r.cur.idx] {
96+
tt_delim(tts) {
97+
r.cur = @{readme: tts, mut idx: 0u,
98+
up: tt_frame_up(option::some(r.cur)) };
99+
}
100+
tt_flat(sp, tok) {
101+
r.cur_span = sp; r.cur_tok = tok;
102+
r.cur.idx += 1u;
103+
ret ret_val;
104+
}
105+
tt_dotdotdot(tts) {
106+
fail;
107+
}
108+
tt_interpolate(ident) {
109+
fail;
110+
}
111+
}
112+
}
113+
114+
}

src/libsyntax/parse.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ export parse_expr_from_source_str, parse_item_from_source_str;
1313
export parse_from_source_str;
1414

1515
import parser::parser;
16-
import attr::parser_attr;
17-
import common::parser_common;
16+
//import attr::parser_attr;
17+
import attr::*; //resolve bug?
18+
//import common::parser_common;
19+
import common::*; //resolve bug?
1820
import ast::node_id;
1921
import util::interner;
2022
// FIXME (#1935): resolve badness
@@ -199,6 +201,7 @@ fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, +path: str,
199201

200202
fn new_parser_from_tt(sess: parse_sess, cfg: ast::crate_cfg,
201203
tt: ~[ast::token_tree]) -> parser {
202-
let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner, tt);
204+
let trdr = lexer::new_tt_reader(sess.span_diagnostic, sess.interner,
205+
none, tt);
203206
ret parser(sess, cfg, trdr as reader, parser::SOURCE_FILE)
204207
}

src/libsyntax/parse/attr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import either::{either, left, right};
22
import ast_util::spanned;
3-
import common::{parser_common, seq_sep_trailing_disallowed};
3+
import common::*; //resolve bug?
4+
//import common::{parser_common, seq_sep_trailing_disallowed};
45

56
export attr_or_ext;
67
export parser_attr;

0 commit comments

Comments
 (0)