Fix some panics on parsing error paths

This commit is contained in:
Nick Fitzgerald
2021-09-28 16:12:07 -07:00
committed by Chris Fallin
parent 6a523938de
commit f2b6244b9c

View File

@@ -51,8 +51,10 @@ impl<'a> Parser<'a> {
} }
} }
fn pos(&self) -> Option<Pos> { fn pos(&self) -> Pos {
self.lexer.peek().map(|(pos, _)| *pos) self.lexer
.peek()
.map_or_else(|| self.lexer.pos(), |(pos, _)| *pos)
} }
fn is_lparen(&self) -> bool { fn is_lparen(&self) -> bool {
@@ -137,7 +139,7 @@ impl<'a> Parser<'a> {
"extractor" => Def::Extractor(self.parse_etor()?), "extractor" => Def::Extractor(self.parse_etor()?),
"extern" => Def::Extern(self.parse_extern()?), "extern" => Def::Extern(self.parse_extern()?),
s => { s => {
return Err(self.error(pos.unwrap(), format!("Unexpected identifier: {}", s))); return Err(self.error(pos, format!("Unexpected identifier: {}", s)));
} }
}; };
self.rparen()?; self.rparen()?;
@@ -170,7 +172,7 @@ impl<'a> Parser<'a> {
fn parse_ident(&mut self) -> ParseResult<Ident> { fn parse_ident(&mut self) -> ParseResult<Ident> {
let pos = self.pos(); let pos = self.pos();
let s = self.symbol()?; let s = self.symbol()?;
self.str_to_ident(pos.unwrap(), &s) self.str_to_ident(pos, &s)
} }
fn parse_const(&mut self) -> ParseResult<Ident> { fn parse_const(&mut self) -> ParseResult<Ident> {
@@ -181,7 +183,7 @@ impl<'a> Parser<'a> {
Ok(Ident(s.to_string(), ident.1)) Ok(Ident(s.to_string(), ident.1))
} else { } else {
Err(self.error( Err(self.error(
pos.unwrap(), pos,
"Not a constant identifier; must start with a '$'".to_string(), "Not a constant identifier; must start with a '$'".to_string(),
)) ))
} }
@@ -200,7 +202,7 @@ impl<'a> Parser<'a> {
name, name,
is_extern, is_extern,
ty, ty,
pos: pos.unwrap(), pos,
}) })
} }
@@ -211,7 +213,6 @@ impl<'a> Parser<'a> {
self.symbol()?; self.symbol()?;
let primitive_ident = self.parse_ident()?; let primitive_ident = self.parse_ident()?;
self.rparen()?; self.rparen()?;
let pos = pos.unwrap();
Ok(TypeValue::Primitive(primitive_ident, pos)) Ok(TypeValue::Primitive(primitive_ident, pos))
} else if self.is_sym_str("enum") { } else if self.is_sym_str("enum") {
self.symbol()?; self.symbol()?;
@@ -221,16 +222,15 @@ impl<'a> Parser<'a> {
variants.push(variant); variants.push(variant);
} }
self.rparen()?; self.rparen()?;
let pos = pos.unwrap();
Ok(TypeValue::Enum(variants, pos)) Ok(TypeValue::Enum(variants, pos))
} else { } else {
Err(self.error(pos.unwrap(), "Unknown type definition".to_string())) Err(self.error(pos, "Unknown type definition".to_string()))
} }
} }
fn parse_type_variant(&mut self) -> ParseResult<Variant> { fn parse_type_variant(&mut self) -> ParseResult<Variant> {
if self.is_sym() { if self.is_sym() {
let pos = self.pos().unwrap(); let pos = self.pos();
let name = self.parse_ident()?; let name = self.parse_ident()?;
Ok(Variant { Ok(Variant {
name, name,
@@ -246,7 +246,6 @@ impl<'a> Parser<'a> {
fields.push(self.parse_type_field()?); fields.push(self.parse_type_field()?);
} }
self.rparen()?; self.rparen()?;
let pos = pos.unwrap();
Ok(Variant { name, fields, pos }) Ok(Variant { name, fields, pos })
} }
} }
@@ -257,7 +256,6 @@ impl<'a> Parser<'a> {
let name = self.parse_ident()?; let name = self.parse_ident()?;
let ty = self.parse_ident()?; let ty = self.parse_ident()?;
self.rparen()?; self.rparen()?;
let pos = pos.unwrap();
Ok(Field { name, ty, pos }) Ok(Field { name, ty, pos })
} }
@@ -278,7 +276,7 @@ impl<'a> Parser<'a> {
term, term,
arg_tys, arg_tys,
ret_ty, ret_ty,
pos: pos.unwrap(), pos,
}) })
} }
@@ -288,11 +286,7 @@ impl<'a> Parser<'a> {
self.symbol()?; self.symbol()?;
let term = self.parse_ident()?; let term = self.parse_ident()?;
let func = self.parse_ident()?; let func = self.parse_ident()?;
Ok(Extern::Constructor { Ok(Extern::Constructor { term, func, pos })
term,
func,
pos: pos.unwrap(),
})
} else if self.is_sym_str("extractor") { } else if self.is_sym_str("extractor") {
self.symbol()?; self.symbol()?;
@@ -317,9 +311,7 @@ impl<'a> Parser<'a> {
self.symbol()?; self.symbol()?;
pol.push(ArgPolarity::Output); pol.push(ArgPolarity::Output);
} else { } else {
return Err( return Err(self.error(pos, "Invalid argument polarity".to_string()));
self.error(pos.unwrap(), "Invalid argument polarity".to_string())
);
} }
} }
self.rparen()?; self.rparen()?;
@@ -330,7 +322,7 @@ impl<'a> Parser<'a> {
Ok(Extern::Extractor { Ok(Extern::Extractor {
term, term,
func, func,
pos: pos.unwrap(), pos,
arg_polarity, arg_polarity,
infallible, infallible,
}) })
@@ -339,14 +331,10 @@ impl<'a> Parser<'a> {
let pos = self.pos(); let pos = self.pos();
let name = self.parse_const()?; let name = self.parse_const()?;
let ty = self.parse_ident()?; let ty = self.parse_ident()?;
Ok(Extern::Const { Ok(Extern::Const { name, ty, pos })
name,
ty,
pos: pos.unwrap(),
})
} else { } else {
Err(self.error( Err(self.error(
pos.unwrap(), pos,
"Invalid extern: must be (extern constructor ...) or (extern extractor ...)" "Invalid extern: must be (extern constructor ...) or (extern extractor ...)"
.to_string(), .to_string(),
)) ))
@@ -367,7 +355,7 @@ impl<'a> Parser<'a> {
term, term,
args, args,
template, template,
pos: pos.unwrap(), pos,
}) })
} }
@@ -383,7 +371,7 @@ impl<'a> Parser<'a> {
Ok(Rule { Ok(Rule {
pattern, pattern,
expr, expr,
pos: pos.unwrap(), pos,
prio, prio,
}) })
} }
@@ -391,21 +379,17 @@ impl<'a> Parser<'a> {
fn parse_pattern(&mut self) -> ParseResult<Pattern> { fn parse_pattern(&mut self) -> ParseResult<Pattern> {
let pos = self.pos(); let pos = self.pos();
if self.is_int() { if self.is_int() {
let pos = pos.unwrap();
Ok(Pattern::ConstInt { Ok(Pattern::ConstInt {
val: self.int()?, val: self.int()?,
pos, pos,
}) })
} else if self.is_const() { } else if self.is_const() {
let pos = pos.unwrap();
let val = self.parse_const()?; let val = self.parse_const()?;
Ok(Pattern::ConstPrim { val, pos }) Ok(Pattern::ConstPrim { val, pos })
} else if self.is_sym_str("_") { } else if self.is_sym_str("_") {
let pos = pos.unwrap();
self.symbol()?; self.symbol()?;
Ok(Pattern::Wildcard { pos }) Ok(Pattern::Wildcard { pos })
} else if self.is_sym() { } else if self.is_sym() {
let pos = pos.unwrap();
let s = self.symbol()?; let s = self.symbol()?;
if s.starts_with("=") { if s.starts_with("=") {
let s = &s[1..]; let s = &s[1..];
@@ -426,7 +410,6 @@ impl<'a> Parser<'a> {
} }
} }
} else if self.is_lparen() { } else if self.is_lparen() {
let pos = pos.unwrap();
self.lparen()?; self.lparen()?;
if self.is_sym_str("and") { if self.is_sym_str("and") {
self.symbol()?; self.symbol()?;
@@ -446,7 +429,7 @@ impl<'a> Parser<'a> {
Ok(Pattern::Term { sym, args, pos }) Ok(Pattern::Term { sym, args, pos })
} }
} else { } else {
Err(self.error(pos.unwrap(), "Unexpected pattern".into())) Err(self.error(pos, "Unexpected pattern".into()))
} }
} }
@@ -462,7 +445,6 @@ impl<'a> Parser<'a> {
fn parse_expr(&mut self) -> ParseResult<Expr> { fn parse_expr(&mut self) -> ParseResult<Expr> {
let pos = self.pos(); let pos = self.pos();
if self.is_lparen() { if self.is_lparen() {
let pos = pos.unwrap();
self.lparen()?; self.lparen()?;
if self.is_sym_str("let") { if self.is_sym_str("let") {
self.symbol()?; self.symbol()?;
@@ -486,34 +468,28 @@ impl<'a> Parser<'a> {
Ok(Expr::Term { sym, args, pos }) Ok(Expr::Term { sym, args, pos })
} }
} else if self.is_sym_str("#t") { } else if self.is_sym_str("#t") {
let pos = pos.unwrap();
self.symbol()?; self.symbol()?;
Ok(Expr::ConstInt { val: 1, pos }) Ok(Expr::ConstInt { val: 1, pos })
} else if self.is_sym_str("#f") { } else if self.is_sym_str("#f") {
let pos = pos.unwrap();
self.symbol()?; self.symbol()?;
Ok(Expr::ConstInt { val: 0, pos }) Ok(Expr::ConstInt { val: 0, pos })
} else if self.is_const() { } else if self.is_const() {
let pos = pos.unwrap();
let val = self.parse_const()?; let val = self.parse_const()?;
Ok(Expr::ConstPrim { val, pos }) Ok(Expr::ConstPrim { val, pos })
} else if self.is_sym() { } else if self.is_sym() {
let pos = pos.unwrap();
let name = self.parse_ident()?; let name = self.parse_ident()?;
Ok(Expr::Var { name, pos }) Ok(Expr::Var { name, pos })
} else if self.is_int() { } else if self.is_int() {
let pos = pos.unwrap();
let val = self.int()?; let val = self.int()?;
Ok(Expr::ConstInt { val, pos }) Ok(Expr::ConstInt { val, pos })
} else { } else {
Err(self.error(pos.unwrap(), "Invalid expression".into())) Err(self.error(pos, "Invalid expression".into()))
} }
} }
fn parse_letdef(&mut self) -> ParseResult<LetDef> { fn parse_letdef(&mut self) -> ParseResult<LetDef> {
let pos = self.pos(); let pos = self.pos();
self.lparen()?; self.lparen()?;
let pos = pos.unwrap();
let var = self.parse_ident()?; let var = self.parse_ident()?;
let ty = self.parse_ident()?; let ty = self.parse_ident()?;
let val = Box::new(self.parse_expr()?); let val = Box::new(self.parse_expr()?);