Fix some panics on parsing error paths
This commit is contained in:
committed by
Chris Fallin
parent
6a523938de
commit
f2b6244b9c
@@ -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()?);
|
||||||
|
|||||||
Reference in New Issue
Block a user