1
Fork 0

commenting parser

This commit is contained in:
John Clements 2013-03-08 10:19:19 -08:00
parent 2b07f0fb00
commit 556143c488
4 changed files with 50 additions and 4 deletions

View file

@ -159,6 +159,9 @@ pub impl Parser {
} }
} }
// if the given word is not a keyword, signal an error.
// if the next token is the given keyword, eat it and return
// true. Otherwise, return false.
fn eat_keyword(&self, word: &~str) -> bool { fn eat_keyword(&self, word: &~str) -> bool {
self.require_keyword(word); self.require_keyword(word);
let is_kw = match *self.token { let is_kw = match *self.token {
@ -169,6 +172,9 @@ pub impl Parser {
is_kw is_kw
} }
// if the given word is not a keyword, signal an error.
// if the next token is not the given word, signal an error.
// otherwise, eat it.
fn expect_keyword(&self, word: &~str) { fn expect_keyword(&self, word: &~str) {
self.require_keyword(word); self.require_keyword(word);
if !self.eat_keyword(word) { if !self.eat_keyword(word) {
@ -182,10 +188,12 @@ pub impl Parser {
} }
} }
// return true if the given string is a strict keyword
fn is_strict_keyword(&self, word: &~str) -> bool { fn is_strict_keyword(&self, word: &~str) -> bool {
self.strict_keywords.contains(word) self.strict_keywords.contains(word)
} }
// signal an error if the current token is a strict keyword
fn check_strict_keywords(&self) { fn check_strict_keywords(&self) {
match *self.token { match *self.token {
token::IDENT(_, false) => { token::IDENT(_, false) => {
@ -196,16 +204,19 @@ pub impl Parser {
} }
} }
// signal an error if the given string is a strict keyword
fn check_strict_keywords_(&self, w: &~str) { fn check_strict_keywords_(&self, w: &~str) {
if self.is_strict_keyword(w) { if self.is_strict_keyword(w) {
self.fatal(fmt!("found `%s` in ident position", *w)); self.fatal(fmt!("found `%s` in ident position", *w));
} }
} }
// return true if this is a reserved keyword
fn is_reserved_keyword(&self, word: &~str) -> bool { fn is_reserved_keyword(&self, word: &~str) -> bool {
self.reserved_keywords.contains(word) self.reserved_keywords.contains(word)
} }
// signal an error if the current token is a reserved keyword
fn check_reserved_keywords(&self) { fn check_reserved_keywords(&self) {
match *self.token { match *self.token {
token::IDENT(_, false) => { token::IDENT(_, false) => {
@ -216,6 +227,7 @@ pub impl Parser {
} }
} }
// signal an error if the given string is a reserved keyword
fn check_reserved_keywords_(&self, w: &~str) { fn check_reserved_keywords_(&self, w: &~str) {
if self.is_reserved_keyword(w) { if self.is_reserved_keyword(w) {
self.fatal(fmt!("`%s` is a reserved keyword", *w)); self.fatal(fmt!("`%s` is a reserved keyword", *w));
@ -223,7 +235,8 @@ pub impl Parser {
} }
// expect and consume a GT. if a >> is seen, replace it // expect and consume a GT. if a >> is seen, replace it
// with a single > and continue. // with a single > and continue. If a GT is not seen,
// signal an error.
fn expect_gt(&self) { fn expect_gt(&self) {
if *self.token == token::GT { if *self.token == token::GT {
self.bump(); self.bump();

View file

@ -80,7 +80,8 @@ pub fn new_low_level_string_reader(span_diagnostic: @span_handler,
last_pos: filemap.start_pos, last_pos: filemap.start_pos,
col: CharPos(0), col: CharPos(0),
curr: initial_char, curr: initial_char,
filemap: filemap, interner: itr, filemap: filemap,
interner: itr,
/* dummy values; not read */ /* dummy values; not read */
peek_tok: token::EOF, peek_tok: token::EOF,
peek_span: codemap::dummy_sp() peek_span: codemap::dummy_sp()
@ -150,6 +151,7 @@ impl reader for TtReader {
} }
// EFFECT: advance peek_tok and peek_span to refer to the next token. // EFFECT: advance peek_tok and peek_span to refer to the next token.
// EFFECT: update the interner, maybe.
fn string_advance_token(r: @mut StringReader) { fn string_advance_token(r: @mut StringReader) {
match (consume_whitespace_and_comments(r)) { match (consume_whitespace_and_comments(r)) {
Some(comment) => { Some(comment) => {
@ -539,6 +541,9 @@ fn ident_continue(c: char) -> bool {
|| (c > 'z' && char::is_XID_continue(c)) || (c > 'z' && char::is_XID_continue(c))
} }
// return the next token from the string
// EFFECT: advances the input past that token
// EFFECT: updates the interner
fn next_token_inner(rdr: @mut StringReader) -> token::Token { fn next_token_inner(rdr: @mut StringReader) -> token::Token {
let mut accum_str = ~""; let mut accum_str = ~"";
let mut c = rdr.curr; let mut c = rdr.curr;

View file

@ -45,10 +45,14 @@ pub mod classify;
/// Reporting obsolete syntax /// Reporting obsolete syntax
pub mod obsolete; pub mod obsolete;
// info about a parsing session.
// This structure and the reader both have
// an interner associated with them. If they're
// not the same, bad things can happen.
pub struct ParseSess { pub struct ParseSess {
cm: @codemap::CodeMap, cm: @codemap::CodeMap, // better be the same as the one in the reader!
next_id: node_id, next_id: node_id,
span_diagnostic: @span_handler, span_diagnostic: @span_handler, // better be the same as the one in the reader!
interner: @ident_interner, interner: @ident_interner,
} }

View file

@ -246,6 +246,7 @@ pub fn Parser(sess: @mut ParseSess,
} }
} }
// ooh, nasty mutable fields everywhere....
pub struct Parser { pub struct Parser {
sess: @mut ParseSess, sess: @mut ParseSess,
cfg: crate_cfg, cfg: crate_cfg,
@ -338,6 +339,7 @@ pub impl Parser {
self.sess.interner.get(id) self.sess.interner.get(id)
} }
// is this one of the keywords that signals a closure type?
fn token_is_closure_keyword(&self, tok: &token::Token) -> bool { fn token_is_closure_keyword(&self, tok: &token::Token) -> bool {
self.token_is_keyword(&~"pure", tok) || self.token_is_keyword(&~"pure", tok) ||
self.token_is_keyword(&~"unsafe", tok) || self.token_is_keyword(&~"unsafe", tok) ||
@ -345,6 +347,7 @@ pub impl Parser {
self.token_is_keyword(&~"fn", tok) self.token_is_keyword(&~"fn", tok)
} }
// parse a ty_bare_fun type:
fn parse_ty_bare_fn(&self) -> ty_ fn parse_ty_bare_fn(&self) -> ty_
{ {
/* /*
@ -372,6 +375,7 @@ pub impl Parser {
}); });
} }
// parse a ty_closure type
fn parse_ty_closure(&self, fn parse_ty_closure(&self,
sigil: ast::Sigil, sigil: ast::Sigil,
region: Option<@ast::Lifetime>) -> ty_ region: Option<@ast::Lifetime>) -> ty_
@ -430,6 +434,7 @@ pub impl Parser {
} }
} }
// parse a function type (following the 'fn')
fn parse_ty_fn_decl(&self) -> (fn_decl, OptVec<ast::Lifetime>) { fn parse_ty_fn_decl(&self) -> (fn_decl, OptVec<ast::Lifetime>) {
/* /*
@ -541,12 +546,14 @@ pub impl Parser {
} }
// parse a possibly mutable type
fn parse_mt(&self) -> mt { fn parse_mt(&self) -> mt {
let mutbl = self.parse_mutability(); let mutbl = self.parse_mutability();
let t = self.parse_ty(false); let t = self.parse_ty(false);
mt { ty: t, mutbl: mutbl } mt { ty: t, mutbl: mutbl }
} }
// parse [mut/const/imm] ID : TY
fn parse_ty_field(&self) -> ty_field { fn parse_ty_field(&self) -> ty_field {
let lo = self.span.lo; let lo = self.span.lo;
let mutbl = self.parse_mutability(); let mutbl = self.parse_mutability();
@ -563,6 +570,7 @@ pub impl Parser {
) )
} }
// parse optional return type [ -> TY ] in function decl
fn parse_ret_ty(&self) -> (ret_style, @Ty) { fn parse_ret_ty(&self) -> (ret_style, @Ty) {
return if self.eat(&token::RARROW) { return if self.eat(&token::RARROW) {
let lo = self.span.lo; let lo = self.span.lo;
@ -591,6 +599,7 @@ pub impl Parser {
} }
} }
// parse a type.
// Useless second parameter for compatibility with quasiquote macros. // Useless second parameter for compatibility with quasiquote macros.
// Bleh! // Bleh!
fn parse_ty(&self, _: bool) -> @Ty { fn parse_ty(&self, _: bool) -> @Ty {
@ -627,15 +636,19 @@ pub impl Parser {
t t
} }
} else if *self.token == token::AT { } else if *self.token == token::AT {
// MANAGED POINTER
self.bump(); self.bump();
self.parse_box_or_uniq_pointee(ManagedSigil, ty_box) self.parse_box_or_uniq_pointee(ManagedSigil, ty_box)
} else if *self.token == token::TILDE { } else if *self.token == token::TILDE {
// OWNED POINTER
self.bump(); self.bump();
self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq) self.parse_box_or_uniq_pointee(OwnedSigil, ty_uniq)
} else if *self.token == token::BINOP(token::STAR) { } else if *self.token == token::BINOP(token::STAR) {
// STAR POINTER (bare pointer?)
self.bump(); self.bump();
ty_ptr(self.parse_mt()) ty_ptr(self.parse_mt())
} else if *self.token == token::LBRACE { } else if *self.token == token::LBRACE {
// STRUCTURAL RECORD (remove?)
let elems = self.parse_unspanned_seq( let elems = self.parse_unspanned_seq(
&token::LBRACE, &token::LBRACE,
&token::RBRACE, &token::RBRACE,
@ -648,6 +661,7 @@ pub impl Parser {
self.obsolete(*self.last_span, ObsoleteRecordType); self.obsolete(*self.last_span, ObsoleteRecordType);
ty_nil ty_nil
} else if *self.token == token::LBRACKET { } else if *self.token == token::LBRACKET {
// VECTOR
self.expect(&token::LBRACKET); self.expect(&token::LBRACKET);
let mt = self.parse_mt(); let mt = self.parse_mt();
if mt.mutbl == m_mutbl { // `m_const` too after snapshot if mt.mutbl == m_mutbl { // `m_const` too after snapshot
@ -663,16 +677,20 @@ pub impl Parser {
self.expect(&token::RBRACKET); self.expect(&token::RBRACKET);
t t
} else if *self.token == token::BINOP(token::AND) { } else if *self.token == token::BINOP(token::AND) {
// BORROWED POINTER
self.bump(); self.bump();
self.parse_borrowed_pointee() self.parse_borrowed_pointee()
} else if self.eat_keyword(&~"extern") { } else if self.eat_keyword(&~"extern") {
// EXTERN FUNCTION
self.parse_ty_bare_fn() self.parse_ty_bare_fn()
} else if self.token_is_closure_keyword(&copy *self.token) { } else if self.token_is_closure_keyword(&copy *self.token) {
// CLOSURE
let result = self.parse_ty_closure(ast::BorrowedSigil, None); let result = self.parse_ty_closure(ast::BorrowedSigil, None);
self.obsolete(*self.last_span, ObsoleteBareFnType); self.obsolete(*self.last_span, ObsoleteBareFnType);
result result
} else if *self.token == token::MOD_SEP } else if *self.token == token::MOD_SEP
|| is_ident_or_path(&*self.token) { || is_ident_or_path(&*self.token) {
// NAMED TYPE
let path = self.parse_path_with_tps(false); let path = self.parse_path_with_tps(false);
ty_path(path, self.get_id()) ty_path(path, self.get_id())
} else { } else {
@ -881,6 +899,8 @@ pub impl Parser {
let global = self.eat(&token::MOD_SEP); let global = self.eat(&token::MOD_SEP);
let mut ids = ~[]; let mut ids = ~[];
loop { loop {
// if there's a ::< coming, stop processing
// the path.
let is_not_last = let is_not_last =
self.look_ahead(2u) != token::LT self.look_ahead(2u) != token::LT
&& self.look_ahead(1u) == token::MOD_SEP; && self.look_ahead(1u) == token::MOD_SEP;
@ -900,6 +920,9 @@ pub impl Parser {
types: ~[] } types: ~[] }
} }
// parse a path optionally with type parameters. If 'colons'
// is true, then type parameters must be preceded by colons,
// as in a::t::<t1,t2>
fn parse_path_with_tps(&self, colons: bool) -> @ast::path { fn parse_path_with_tps(&self, colons: bool) -> @ast::path {
debug!("parse_path_with_tps(colons=%b)", colons); debug!("parse_path_with_tps(colons=%b)", colons);
@ -1067,6 +1090,7 @@ pub impl Parser {
self.token_is_keyword(&~"const", tok) self.token_is_keyword(&~"const", tok)
} }
// parse mutability declaration (mut/const/imm)
fn parse_mutability(&self) -> mutability { fn parse_mutability(&self) -> mutability {
if self.eat_keyword(&~"mut") { if self.eat_keyword(&~"mut") {
m_mutbl m_mutbl