From bcbcbad7746cdab8465d2df1d9296cd74e30082f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 19 Apr 2012 21:18:33 -0700 Subject: [PATCH] syntax: Extract some functions into mod common --- src/librustsyntax/parse/attr.rs | 6 +- src/librustsyntax/parse/common.rs | 201 +++++++++++++++++++++++++++++ src/librustsyntax/parse/parser.rs | 204 +----------------------------- src/librustsyntax/rustsyntax.rc | 3 + 4 files changed, 208 insertions(+), 206 deletions(-) create mode 100644 src/librustsyntax/parse/common.rs diff --git a/src/librustsyntax/parse/attr.rs b/src/librustsyntax/parse/attr.rs index 7994ba00b1d..b7caa00a2af 100644 --- a/src/librustsyntax/parse/attr.rs +++ b/src/librustsyntax/parse/attr.rs @@ -1,11 +1,11 @@ import either::{either, left, right}; -import parser::{parse_seq, +import common::{parse_seq, seq_sep, expect, - parse_lit, parse_ident, - parse_syntax_ext_naked, spanned}; +import parser::{parse_lit, + parse_syntax_ext_naked}; export attr_or_ext; export parse_outer_attributes; diff --git a/src/librustsyntax/parse/common.rs b/src/librustsyntax/parse/common.rs new file mode 100644 index 00000000000..ba0d4530cff --- /dev/null +++ b/src/librustsyntax/parse/common.rs @@ -0,0 +1,201 @@ +import std::map::{hashmap}; +import ast::spanned; +import parser::parser; + +fn token_to_str(reader: reader, token: token::token) -> str { + token::to_str(*reader.interner, token) +} + +fn unexpected_last(p: parser, t: token::token) -> ! { + p.span_fatal(p.last_span, + "unexpected token: '" + token_to_str(p.reader, t) + "'"); +} + +fn unexpected(p: parser) -> ! { + p.fatal("unexpected token: '" + token_to_str(p.reader, p.token) + "'"); +} + +fn expect(p: parser, t: token::token) { + if p.token == t { + p.bump(); + } else { + let mut s: str = "expecting '"; + s += token_to_str(p.reader, t); + s += "' but found '"; + s += token_to_str(p.reader, p.token); + p.fatal(s + "'"); + } +} + +fn spanned(lo: uint, hi: uint, node: T) -> spanned { + ret {node: node, span: ast_util::mk_sp(lo, hi)}; +} + +fn parse_ident(p: parser) -> ast::ident { + alt p.token { + token::IDENT(i, _) { p.bump(); ret p.get_str(i); } + _ { p.fatal("expecting ident, found " + + token_to_str(p.reader, p.token)); } + } +} + +fn parse_path_list_ident(p: parser) -> ast::path_list_ident { + let lo = p.span.lo; + let ident = parse_ident(p); + let hi = p.span.hi; + ret spanned(lo, hi, {name: ident, id: p.get_id()}); +} + +fn parse_value_ident(p: parser) -> ast::ident { + check_bad_word(p); + ret parse_ident(p); +} + +fn eat(p: parser, tok: token::token) -> bool { + ret if p.token == tok { p.bump(); true } else { false }; +} + +// A sanity check that the word we are asking for is a known keyword +fn require_keyword(p: parser, word: str) { + if !p.keywords.contains_key(word) { + p.bug(#fmt("unknown keyword: %s", word)); + } +} + +fn is_word(p: parser, word: str) -> bool { + require_keyword(p, word); + ret alt p.token { + token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) } + _ { false } + }; +} + +fn eat_word(p: parser, word: str) -> bool { + require_keyword(p, word); + alt p.token { + token::IDENT(sid, false) { + if str::eq(word, p.get_str(sid)) { + p.bump(); + ret true; + } else { ret false; } + } + _ { ret false; } + } +} + +fn expect_word(p: parser, word: str) { + require_keyword(p, word); + if !eat_word(p, word) { + p.fatal("expecting " + word + ", found " + + token_to_str(p.reader, p.token)); + } +} + +fn check_bad_word(p: parser) { + if token::is_bad_expr_word(p.token, p.bad_expr_words, + *p.reader.interner) { + let w = token_to_str(p.reader, p.token); + p.fatal("found " + w + " in expression position"); + } +} + +fn expect_gt(p: parser) { + if p.token == token::GT { + p.bump(); + } else if p.token == token::BINOP(token::LSR) { + p.swap(token::GT, p.span.lo + 1u, p.span.hi); + } else if p.token == token::BINOP(token::ASR) { + p.swap(token::BINOP(token::LSR), p.span.lo + 1u, p.span.hi); + } else { + let mut s: str = "expecting "; + s += token_to_str(p.reader, token::GT); + s += ", found "; + s += token_to_str(p.reader, p.token); + p.fatal(s); + } +} + +fn parse_seq_to_before_gt(sep: option, + f: fn(parser) -> T, + p: parser) -> [T] { + let mut first = true; + let mut v = []; + while p.token != token::GT && p.token != token::BINOP(token::LSR) && + p.token != token::BINOP(token::ASR) { + alt sep { + some(t) { if first { first = false; } else { expect(p, t); } } + _ { } + } + v += [f(p)]; + } + + ret v; +} + +fn parse_seq_to_gt(sep: option, + f: fn(parser) -> T, p: parser) -> [T] { + let v = parse_seq_to_before_gt(sep, f, p); + expect_gt(p); + + ret v; +} + +fn parse_seq_lt_gt(sep: option, + f: fn(parser) -> T, + p: parser) -> spanned<[T]> { + let lo = p.span.lo; + expect(p, token::LT); + let result = parse_seq_to_before_gt::(sep, f, p); + let hi = p.span.hi; + expect_gt(p); + ret spanned(lo, hi, result); +} + +fn parse_seq_to_end(ket: token::token, sep: seq_sep, + f: fn(parser) -> T, p: parser) -> [T] { + let val = parse_seq_to_before_end(ket, sep, f, p); + p.bump(); + ret val; +} + +type seq_sep = { + sep: option, + trailing_opt: bool // is trailing separator optional? +}; + +fn seq_sep(t: token::token) -> seq_sep { + ret {sep: option::some(t), trailing_opt: false}; +} +fn seq_sep_opt(t: token::token) -> seq_sep { + ret {sep: option::some(t), trailing_opt: true}; +} +fn seq_sep_none() -> seq_sep { + ret {sep: option::none, trailing_opt: false}; +} + +fn parse_seq_to_before_end(ket: token::token, + sep: seq_sep, + f: fn(parser) -> T, p: parser) -> [T] { + let mut first: bool = true; + let mut v: [T] = []; + while p.token != ket { + alt sep.sep { + some(t) { if first { first = false; } else { expect(p, t); } } + _ { } + } + if sep.trailing_opt && p.token == ket { break; } + v += [f(p)]; + } + ret v; +} + +fn parse_seq(bra: token::token, ket: token::token, + sep: seq_sep, f: fn(parser) -> T, + p: parser) -> spanned<[T]> { + let lo = p.span.lo; + expect(p, bra); + let result = parse_seq_to_before_end::(ket, sep, f, p); + let hi = p.span.hi; + p.bump(); + ret spanned(lo, hi, result); +} diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs index 013357dff15..2a8e683dee5 100644 --- a/src/librustsyntax/parse/parser.rs +++ b/src/librustsyntax/parse/parser.rs @@ -12,6 +12,7 @@ import attr::{parse_outer_attrs_or_ext, parse_inner_attrs_and_next, parse_outer_attributes, parse_optional_meta}; +import common::*; export expect; export file_type; @@ -27,11 +28,7 @@ export parse_pat; export parse_seq; export parse_stmt; export parse_ty; - -export spanned; -export seq_sep; export parse_lit; -export parse_ident; export parse_syntax_ext_naked; // FIXME: #ast expects to find this here but it's actually defined in `parse` @@ -108,119 +105,6 @@ impl parser for parser { fn get_id() -> node_id { next_node_id(self.sess) } } -fn token_to_str(reader: reader, token: token::token) -> str { - token::to_str(*reader.interner, token) -} - -fn unexpected_last(p: parser, t: token::token) -> ! { - p.span_fatal(p.last_span, - "unexpected token: '" + token_to_str(p.reader, t) + "'"); -} - -fn unexpected(p: parser) -> ! { - p.fatal("unexpected token: '" + token_to_str(p.reader, p.token) + "'"); -} - -fn expect(p: parser, t: token::token) { - if p.token == t { - p.bump(); - } else { - let mut s: str = "expecting '"; - s += token_to_str(p.reader, t); - s += "' but found '"; - s += token_to_str(p.reader, p.token); - p.fatal(s + "'"); - } -} - -fn expect_gt(p: parser) { - if p.token == token::GT { - p.bump(); - } else if p.token == token::BINOP(token::LSR) { - p.swap(token::GT, p.span.lo + 1u, p.span.hi); - } else if p.token == token::BINOP(token::ASR) { - p.swap(token::BINOP(token::LSR), p.span.lo + 1u, p.span.hi); - } else { - let mut s: str = "expecting "; - s += token_to_str(p.reader, token::GT); - s += ", found "; - s += token_to_str(p.reader, p.token); - p.fatal(s); - } -} - -fn spanned(lo: uint, hi: uint, node: T) -> spanned { - ret {node: node, span: ast_util::mk_sp(lo, hi)}; -} - -fn parse_ident(p: parser) -> ast::ident { - alt p.token { - token::IDENT(i, _) { p.bump(); ret p.get_str(i); } - _ { p.fatal("expecting ident, found " - + token_to_str(p.reader, p.token)); } - } -} - -fn parse_path_list_ident(p: parser) -> ast::path_list_ident { - let lo = p.span.lo; - let ident = parse_ident(p); - let hi = p.span.hi; - ret spanned(lo, hi, {name: ident, id: p.get_id()}); -} - -fn parse_value_ident(p: parser) -> ast::ident { - check_bad_word(p); - ret parse_ident(p); -} - -fn eat(p: parser, tok: token::token) -> bool { - ret if p.token == tok { p.bump(); true } else { false }; -} - -// A sanity check that the word we are asking for is a known keyword -fn require_keyword(p: parser, word: str) { - if !p.keywords.contains_key(word) { - p.bug(#fmt("unknown keyword: %s", word)); - } -} - -fn is_word(p: parser, word: str) -> bool { - require_keyword(p, word); - ret alt p.token { - token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) } - _ { false } - }; -} - -fn eat_word(p: parser, word: str) -> bool { - require_keyword(p, word); - alt p.token { - token::IDENT(sid, false) { - if str::eq(word, p.get_str(sid)) { - p.bump(); - ret true; - } else { ret false; } - } - _ { ret false; } - } -} - -fn expect_word(p: parser, word: str) { - require_keyword(p, word); - if !eat_word(p, word) { - p.fatal("expecting " + word + ", found " + - token_to_str(p.reader, p.token)); - } -} - -fn check_bad_word(p: parser) { - if token::is_bad_expr_word(p.token, p.bad_expr_words, - *p.reader.interner) { - let w = token_to_str(p.reader, p.token); - p.fatal("found " + w + " in expression position"); - } -} - fn parse_ty_fn(p: parser) -> ast::fn_decl { fn parse_fn_input_ty(p: parser) -> ast::arg { let mode = parse_arg_mode(p); @@ -557,92 +441,6 @@ fn parse_fn_block_arg(p: parser) -> ast::arg { ret {mode: m, ty: t, ident: i, id: p.get_id()}; } -fn parse_seq_to_before_gt(sep: option, - f: fn(parser) -> T, - p: parser) -> [T] { - let mut first = true; - let mut v = []; - while p.token != token::GT && p.token != token::BINOP(token::LSR) && - p.token != token::BINOP(token::ASR) { - alt sep { - some(t) { if first { first = false; } else { expect(p, t); } } - _ { } - } - v += [f(p)]; - } - - ret v; -} - -fn parse_seq_to_gt(sep: option, - f: fn(parser) -> T, p: parser) -> [T] { - let v = parse_seq_to_before_gt(sep, f, p); - expect_gt(p); - - ret v; -} - -fn parse_seq_lt_gt(sep: option, - f: fn(parser) -> T, - p: parser) -> spanned<[T]> { - let lo = p.span.lo; - expect(p, token::LT); - let result = parse_seq_to_before_gt::(sep, f, p); - let hi = p.span.hi; - expect_gt(p); - ret spanned(lo, hi, result); -} - -fn parse_seq_to_end(ket: token::token, sep: seq_sep, - f: fn(parser) -> T, p: parser) -> [T] { - let val = parse_seq_to_before_end(ket, sep, f, p); - p.bump(); - ret val; -} - -type seq_sep = { - sep: option, - trailing_opt: bool // is trailing separator optional? -}; - -fn seq_sep(t: token::token) -> seq_sep { - ret {sep: option::some(t), trailing_opt: false}; -} -fn seq_sep_opt(t: token::token) -> seq_sep { - ret {sep: option::some(t), trailing_opt: true}; -} -fn seq_sep_none() -> seq_sep { - ret {sep: option::none, trailing_opt: false}; -} - -fn parse_seq_to_before_end(ket: token::token, - sep: seq_sep, - f: fn(parser) -> T, p: parser) -> [T] { - let mut first: bool = true; - let mut v: [T] = []; - while p.token != ket { - alt sep.sep { - some(t) { if first { first = false; } else { expect(p, t); } } - _ { } - } - if sep.trailing_opt && p.token == ket { break; } - v += [f(p)]; - } - ret v; -} - - -fn parse_seq(bra: token::token, ket: token::token, - sep: seq_sep, f: fn(parser) -> T, - p: parser) -> spanned<[T]> { - let lo = p.span.lo; - expect(p, bra); - let result = parse_seq_to_before_end::(ket, sep, f, p); - let hi = p.span.hi; - p.bump(); - ret spanned(lo, hi, result); -} - fn have_dollar(p: parser) -> option { alt p.token { token::DOLLAR_NUM(num) { diff --git a/src/librustsyntax/rustsyntax.rc b/src/librustsyntax/rustsyntax.rc index 5a479269244..2e560eb01c1 100644 --- a/src/librustsyntax/rustsyntax.rc +++ b/src/librustsyntax/rustsyntax.rc @@ -37,6 +37,9 @@ mod parse { mod comments; mod attr; + #[doc = "Common routines shared by parser mods"] + mod common; + #[doc = "Functions dealing with operator precedence"] mod prec;