Reduced parser boilerplate

This commit is contained in:
ondra05 2021-07-15 21:39:01 +02:00 committed by GitHub
parent f6e6f8cea1
commit ffcbdc258b

View file

@ -49,6 +49,15 @@ impl<'source> Parser<'source> {
Ok(ast) Ok(ast)
} }
/// Get next item
///
/// If EOF, return Error instead of None
fn checked_next(&mut self) -> Result<Token, Error> {
self.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))
}
/// Parse a token /// Parse a token
/// ///
/// This function will route to corresponding flow functions /// This function will route to corresponding flow functions
@ -120,11 +129,7 @@ impl<'source> Parser<'source> {
/// Get an Identifier /// Get an Identifier
fn get_iden(&mut self) -> Result<Iden, Error> { fn get_iden(&mut self) -> Result<Iden, Error> {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::Identifier(iden) => Ok(Iden { Token::Identifier(iden) => Ok(Iden {
iden: if self.tdark { iden: if self.tdark {
iden.replace("lang", "script") iden.replace("lang", "script")
@ -203,10 +208,7 @@ impl<'source> Parser<'source> {
Token::Not => Ok(Expr::new( Token::Not => Ok(Expr::new(
{ {
let next = self let next = self.checked_next()?;
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?;
ExprKind::Not(Box::new(self.parse_expr(next, buf)?)) ExprKind::Not(Box::new(self.parse_expr(next, buf)?))
}, },
start..self.lexer.span().end, start..self.lexer.span().end,
@ -242,11 +244,7 @@ impl<'source> Parser<'source> {
fn expr_flow(&mut self, terminate: Token) -> Result<Expr, Error> { fn expr_flow(&mut self, terminate: Token) -> Result<Expr, Error> {
let mut buf = None; let mut buf = None;
Ok(loop { Ok(loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
t if t == terminate => { t if t == terminate => {
break buf.take().ok_or_else(|| { break buf.take().ok_or_else(|| {
Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span()) Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())
@ -263,11 +261,7 @@ impl<'source> Parser<'source> {
let mut block = vec![]; let mut block = vec![];
loop { loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::RightCurly => break, Token::RightCurly => break,
t => block.push(self.parse(t)?), t => block.push(self.parse(t)?),
} }
@ -281,11 +275,7 @@ impl<'source> Parser<'source> {
fn value_flow(&mut self, init: Token) -> Result<StmtKind, Error> { fn value_flow(&mut self, init: Token) -> Result<StmtKind, Error> {
let mut buf = Some(self.parse_expr(init, &mut None)?); let mut buf = Some(self.parse_expr(init, &mut None)?);
let r = loop { let r = loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
// Print to stdout // Print to stdout
Token::Print => { Token::Print => {
let stmt = StmtKind::Print(buf.take().ok_or_else(|| { let stmt = StmtKind::Print(buf.take().ok_or_else(|| {
@ -360,21 +350,13 @@ impl<'source> Parser<'source> {
let mut params = vec![]; let mut params = vec![];
loop { loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::RightParen => break, Token::RightParen => break,
Token::Identifier(i) => { Token::Identifier(i) => {
params.push(Iden::new(i, self.lexer.span())); params.push(Iden::new(i, self.lexer.span()));
// Require comma (next) or right paren (end) after identifier // Require comma (next) or right paren (end) after identifier
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::Comma => continue, Token::Comma => continue,
Token::RightParen => break, Token::RightParen => break,
t => { t => {
@ -400,11 +382,7 @@ impl<'source> Parser<'source> {
fn bff_flow(&mut self) -> Result<StmtKind, Error> { fn bff_flow(&mut self) -> Result<StmtKind, Error> {
let iden = self.get_iden()?; let iden = self.get_iden()?;
let tape_len = match self let tape_len = match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::LeftParen => { Token::LeftParen => {
let len = Some(self.expr_flow(Token::RightParen)?); let len = Some(self.expr_flow(Token::RightParen)?);
self.require(Token::LeftCurly)?; self.require(Token::LeftCurly)?;
@ -421,11 +399,7 @@ impl<'source> Parser<'source> {
let mut code: Vec<u8> = vec![]; let mut code: Vec<u8> = vec![];
loop { loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::Plus Token::Plus
| Token::Minus | Token::Minus
| Token::Dot | Token::Dot
@ -451,11 +425,7 @@ impl<'source> Parser<'source> {
let mut args = vec![]; let mut args = vec![];
let mut buf = None; let mut buf = None;
loop { loop {
match self match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
// End of argument list // End of argument list
Token::RightParen => { Token::RightParen => {
if let Some(expr) = buf.take() { if let Some(expr) = buf.take() {
@ -486,11 +456,7 @@ impl<'source> Parser<'source> {
/// Parse variable declaration /// Parse variable declaration
fn var_flow(&mut self) -> Result<StmtKind, Error> { fn var_flow(&mut self) -> Result<StmtKind, Error> {
let iden = self.get_iden()?; let iden = self.get_iden()?;
let init = match self let init = match self.checked_next()? {
.lexer
.next()
.ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))?
{
Token::Equal => Some(self.expr_flow(Token::Semicolon)?), Token::Equal => Some(self.expr_flow(Token::Semicolon)?),
Token::Semicolon => None, Token::Semicolon => None,
t => return Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())), t => return Err(Error::new(ErrorKind::UnexpectedToken(t), self.lexer.span())),