Skip to content

Commit b9ae0c5

Browse files
committed
syntax: Funnel all words through a single keyword table
1 parent f641dce commit b9ae0c5

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

src/librustsyntax/parse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
7777
mut restriction: parser::UNRESTRICTED,
7878
reader: rdr,
7979
binop_precs: prec::binop_prec_table(),
80+
keywords: token::keyword_table(),
8081
bad_expr_words: token::bad_expr_word_table()}
8182
}
8283

src/librustsyntax/parse/parser.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type parser = @{
4949
mut restriction: restriction,
5050
reader: reader,
5151
binop_precs: @[op_spec],
52+
keywords: hashmap<str, ()>,
5253
bad_expr_words: hashmap<str, ()>
5354
};
5455

@@ -83,6 +84,9 @@ impl parser for parser {
8384
fn span_fatal(sp: span, m: str) -> ! {
8485
self.sess.span_diagnostic.span_fatal(sp, m)
8586
}
87+
fn bug(m: str) -> ! {
88+
self.sess.span_diagnostic.span_bug(self.span, m)
89+
}
8690
fn warn(m: str) {
8791
self.sess.span_diagnostic.span_warn(self.span, m)
8892
}
@@ -161,14 +165,23 @@ fn eat(p: parser, tok: token::token) -> bool {
161165
ret if p.token == tok { p.bump(); true } else { false };
162166
}
163167

168+
// A sanity check that the word we are asking for is a known keyword
169+
fn require_keyword(p: parser, word: str) {
170+
if !p.keywords.contains_key(word) {
171+
p.bug(#fmt("unknown keyword: %s", word));
172+
}
173+
}
174+
164175
fn is_word(p: parser, word: str) -> bool {
176+
require_keyword(p, word);
165177
ret alt p.token {
166178
token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
167179
_ { false }
168180
};
169181
}
170182

171183
fn eat_word(p: parser, word: str) -> bool {
184+
require_keyword(p, word);
172185
alt p.token {
173186
token::IDENT(sid, false) {
174187
if str::eq(word, p.get_str(sid)) {
@@ -181,6 +194,7 @@ fn eat_word(p: parser, word: str) -> bool {
181194
}
182195

183196
fn expect_word(p: parser, word: str) {
197+
require_keyword(p, word);
184198
if !eat_word(p, word) {
185199
p.fatal("expecting " + word + ", found " +
186200
token_to_str(p.reader, p.token));
@@ -386,6 +400,9 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
386400
fn region_from_name(p: parser, s: option<str>) -> ast::region {
387401
let r = alt s {
388402
some (string) {
403+
// FIXME: To be consistent with our type resolution the
404+
// static region should probably be resolved during type
405+
// checking, not in the parser.
389406
if string == "static" {
390407
ast::re_static
391408
} else {
@@ -2578,14 +2595,7 @@ fn parse_view_item(p: parser) -> @ast::view_item {
25782595
}
25792596

25802597
fn is_view_item(p: parser) -> bool {
2581-
alt p.token {
2582-
token::IDENT(sid, false) {
2583-
let st = p.get_str(sid);
2584-
ret str::eq(st, "use") || str::eq(st, "import") ||
2585-
str::eq(st, "export");
2586-
}
2587-
_ { ret false; }
2588-
}
2598+
is_word(p, "use") || is_word(p, "import") || is_word(p, "export")
25892599
}
25902600

25912601
fn maybe_parse_view(

src/librustsyntax/parse/token.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,38 @@ fn is_bad_expr_word(t: token,
217217
}
218218
}
219219

220+
#[doc = "
221+
All the valid words that have meaning in the Rust language. Some of these are
222+
nonetheless valid as identifiers becasue they are unambiguous.
223+
"]
224+
fn keyword_table() -> hashmap<str, ()> {
225+
let keywords = str_hash();
226+
bad_expr_word_table().keys() {|word|
227+
keywords.insert(word, ());
228+
}
229+
let other_keywords = [
230+
"as",
231+
"bind",
232+
"else",
233+
"false",
234+
"implements",
235+
"move",
236+
"of",
237+
"priv",
238+
"self",
239+
"send",
240+
"static",
241+
"to",
242+
"true",
243+
"use",
244+
"with"
245+
];
246+
for other_keywords.each {|word|
247+
keywords.insert(word, ());
248+
}
249+
ret keywords;
250+
}
251+
220252
#[doc = "
221253
These are the words that shouldn't be allowed as value identifiers,
222254
because, if used at the start of a line, they will cause the line to be
@@ -228,8 +260,8 @@ fn bad_expr_word_table() -> hashmap<str, ()> {
228260
"class", "const", "cont", "copy", "crust", "do", "else",
229261
"enum", "export", "fail", "fn", "for", "if", "iface",
230262
"impl", "import", "let", "log", "loop", "mod",
231-
"mut", "native", "pure", "resource", "ret", "trait",
232-
"type", "unchecked", "unsafe", "while", "new"];
263+
"mut", "mutable", "native", "new", "pure", "resource",
264+
"ret", "trait", "type", "unchecked", "unsafe", "while"];
233265
for keys.each {|word|
234266
words.insert(word, ());
235267
}

0 commit comments

Comments
 (0)