170 lines
5.7 KiB
Rust
Raw Normal View History

2012-04-19 21:33:51 -07:00
#[doc = "The main parser interface"];
export parse_sess;
export next_node_id;
export new_parser_from_file;
export new_parser_from_source_str;
export parse_crate_from_file;
export parse_crate_from_crate_file;
export parse_crate_from_source_str;
export parse_expr_from_source_str;
export parse_from_source_str;
import parser::parser;
import ast::node_id;
import util::interner;
import lexer::reader;
type parse_sess = @{
cm: codemap::codemap,
mut next_id: node_id,
span_diagnostic: diagnostic::span_handler,
// these two must be kept up to date
mut chpos: uint,
mut byte_pos: uint
};
2012-04-19 21:33:51 -07:00
fn parse_crate_from_file(input: str, cfg: ast::crate_cfg, sess: parse_sess) ->
@ast::crate {
if str::ends_with(input, ".rc") {
parse_crate_from_crate_file(input, cfg, sess)
} else if str::ends_with(input, ".rs") {
parse_crate_from_source_file(input, cfg, sess)
} else {
sess.span_diagnostic.handler().fatal("unknown input file type: " +
input)
}
}
fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::crate {
let p = new_parser_from_file(sess, cfg, input, parser::CRATE_FILE);
let lo = p.span.lo;
let prefix = path::dirname(p.reader.filemap.name);
let leading_attrs = attr::parse_inner_attrs_and_next(p);
let crate_attrs = leading_attrs.inner;
let first_cdir_attr = leading_attrs.next;
let cdirs = parser::parse_crate_directives(
p, token::EOF, first_cdir_attr);
sess.chpos = p.reader.chpos;
sess.byte_pos = sess.byte_pos + p.reader.pos;
let cx =
@{p: p,
sess: sess,
cfg: p.cfg};
let (companionmod, _) = path::splitext(path::basename(input));
let (m, attrs) = eval::eval_crate_directives_to_mod(
cx, cdirs, prefix, option::some(companionmod));
let mut hi = p.span.hi;
parser::expect(p, token::EOF);
ret @ast_util::respan(ast_util::mk_sp(lo, hi),
{directives: cdirs,
module: m,
attrs: crate_attrs + attrs,
config: p.cfg});
}
fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::crate {
let p = new_parser_from_file(sess, cfg, input, parser::SOURCE_FILE);
let r = parser::parse_crate_mod(p, cfg);
sess.chpos = p.reader.chpos;
sess.byte_pos = sess.byte_pos + p.reader.pos;
ret r;
}
2012-04-19 21:33:51 -07:00
fn parse_crate_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::crate {
let p = new_parser_from_source_str(
sess, cfg, name, codemap::fss_none, source);
2012-04-19 21:33:51 -07:00
let r = parser::parse_crate_mod(p, cfg);
sess.chpos = p.reader.chpos;
sess.byte_pos = sess.byte_pos + p.reader.pos;
ret r;
}
2012-04-19 21:33:51 -07:00
fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::expr {
let p = new_parser_from_source_str(
sess, cfg, name, codemap::fss_none, source);
2012-04-19 21:33:51 -07:00
let r = parser::parse_expr(p);
sess.chpos = p.reader.chpos;
sess.byte_pos = sess.byte_pos + p.reader.pos;
ret r;
}
fn parse_from_source_str<T>(f: fn (p: parser) -> T,
name: str, ss: codemap::file_substr,
source: @str, cfg: ast::crate_cfg,
sess: parse_sess)
-> T
{
let p = new_parser_from_source_str(sess, cfg, name, ss, source);
let r = f(p);
if !p.reader.is_eof() {
p.reader.fatal("expected end-of-string");
}
sess.chpos = p.reader.chpos;
sess.byte_pos = sess.byte_pos + p.reader.pos;
ret r;
}
2012-04-19 21:33:51 -07:00
fn next_node_id(sess: parse_sess) -> node_id {
let rv = sess.next_id;
sess.next_id += 1;
// ID 0 is reserved for the crate and doesn't actually exist in the AST
assert rv != 0;
ret rv;
}
fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
ftype: parser::file_type) -> parser {
let tok0 = lexer::next_token(rdr);
let span0 = ast_util::mk_sp(tok0.chpos, rdr.chpos);
@{sess: sess,
cfg: cfg,
file_type: ftype,
mut token: tok0.tok,
mut span: span0,
mut last_span: span0,
mut buffer: [],
mut restriction: parser::UNRESTRICTED,
reader: rdr,
binop_precs: prec::binop_prec_table(),
keywords: token::keyword_table(),
bad_expr_words: token::bad_expr_word_table()}
}
fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
name: str, ss: codemap::file_substr,
source: @str) -> parser {
let ftype = parser::SOURCE_FILE;
let filemap = codemap::new_filemap_w_substr
(name, ss, source, sess.chpos, sess.byte_pos);
sess.cm.files += [filemap];
let itr = @interner::mk(str::hash, str::eq);
let rdr = lexer::new_reader(sess.span_diagnostic,
filemap, itr);
ret new_parser(sess, cfg, rdr, ftype);
}
fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
ftype: parser::file_type) ->
parser {
let src = alt io::read_whole_file_str(path) {
result::ok(src) {
// FIXME: This copy is unfortunate
@src
}
result::err(e) {
sess.span_diagnostic.handler().fatal(e)
}
};
let filemap = codemap::new_filemap(path, src,
sess.chpos, sess.byte_pos);
sess.cm.files += [filemap];
let itr = @interner::mk(str::hash, str::eq);
let rdr = lexer::new_reader(sess.span_diagnostic, filemap, itr);
ret new_parser(sess, cfg, rdr, ftype);
}