refactor(ast): Improve error type, remove unnecessary eof judge

This commit is contained in:
2026-06-12 11:11:31 +08:00
parent 4dabf32c2a
commit ef3dcb41aa
8 changed files with 62 additions and 231 deletions
+11
View File
@@ -0,0 +1,11 @@
use thiserror::Error;
use crate::lexer::types::TokenValue;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum ParseError {
#[error("expected {} before {}", .1, .0)]
ExpectedBefore(TokenValue, &'static str),
#[error("expected identifier after {}", .0)]
ExpectedIdentAfter(TokenValue),
}
+1
View File
@@ -1,3 +1,4 @@
pub mod err;
pub mod graph; pub mod graph;
pub mod parser; pub mod parser;
pub mod types; pub mod types;
+12 -41
View File
@@ -1,12 +1,10 @@
use crate::{ use crate::{
ast::err::ParseError,
ast::types::{ ast::types::{
ArrayDimension, CompileUnit, FuncDeclStmt, GlobalDeclStmt, Param, VarDeclStmt, VarDeclStmtValue, ArrayDimension, CompileUnit, FuncDeclStmt, GlobalDeclStmt, Param, VarDeclStmt, VarDeclStmtValue,
}, },
diagnostic::span::Span, diagnostic::span::Span,
lexer::{ lexer::types::{TokenValue, TypeIdent},
err::ParseError,
types::{TokenValue, TypeIdent},
},
}; };
use super::{ParseProcessError, ParseType, Parser}; use super::{ParseProcessError, ParseType, Parser};
@@ -25,7 +23,6 @@ impl Parser {
} }
fn parse_global_decl_stmt(&mut self) -> Option<GlobalDeclStmt> { fn parse_global_decl_stmt(&mut self) -> Option<GlobalDeclStmt> {
assert!(!self.is_eof());
match self.parse_func_decl_stmt() { match self.parse_func_decl_stmt() {
Ok(func_decl) => return Some(GlobalDeclStmt::FuncDecl(func_decl)), Ok(func_decl) => return Some(GlobalDeclStmt::FuncDecl(func_decl)),
Err(ParseProcessError::ErrorInMatch) => { Err(ParseProcessError::ErrorInMatch) => {
@@ -42,7 +39,7 @@ impl Parser {
} }
let token = self.next().clone(); let token = self.next().clone();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "ident"), ParseError::ExpectedBefore(token.value, "ident"),
token.span, token.span,
); );
None None
@@ -58,7 +55,6 @@ impl Parser {
// } // }
// } // }
fn parse_type_and_name(&mut self, parse_type: ParseType) -> Result<(TypeIdent, String, Span, Span), ParseProcessError> { fn parse_type_and_name(&mut self, parse_type: ParseType) -> Result<(TypeIdent, String, Span, Span), ParseProcessError> {
assert!(!self.is_eof());
let type_token = self.peek().clone(); let type_token = self.peek().clone();
let type_ident = match self.peek().value.as_type_ident() { let type_ident = match self.peek().value.as_type_ident() {
Some(ti) => ti, Some(ti) => ti,
@@ -66,7 +62,7 @@ impl Parser {
if matches!(parse_type, ParseType::MustParse) { if matches!(parse_type, ParseType::MustParse) {
let token = self.next().clone(); let token = self.next().clone();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "type ident"), ParseError::ExpectedBefore(token.value, "type ident"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -77,17 +73,10 @@ impl Parser {
let type_span = type_token.span; let type_span = type_token.span;
self.advance(1); self.advance(1);
let name = match self.peek().value.as_ident() { let name = match self.peek().value.as_ident() {
None if self.is_eof() => {
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("ident"),
type_span,
);
return Err(ParseProcessError::ErrorInMatch);
},
None => { None => {
let next_span = self.peek().span; let next_span = self.peek().span;
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::CantCombineWith(type_token.value), ParseError::ExpectedIdentAfter(type_token.value),
next_span next_span
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -99,7 +88,6 @@ impl Parser {
Ok((type_ident, name, type_span, name_span)) Ok((type_ident, name, type_span, name_span))
} }
fn parse_func_decl_stmt(&mut self) -> Result<FuncDeclStmt, ParseProcessError> { fn parse_func_decl_stmt(&mut self) -> Result<FuncDeclStmt, ParseProcessError> {
assert!(!self.is_eof());
let (return_type, name, ret_type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?; let (return_type, name, ret_type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?;
if matches!(self.peek().value, TokenValue::LParen) { if matches!(self.peek().value, TokenValue::LParen) {
} else { } else {
@@ -108,14 +96,7 @@ impl Parser {
} }
// from here we can be sure it's a function declaration, so we can report error if the syntax is wrong // from here we can be sure it's a function declaration, so we can report error if the syntax is wrong
let params = self.parse_param_list()?; let params = self.parse_param_list()?;
let body = if self.is_eof() { let body = self.parse_block_stmt(ParseType::MustParse)?;
let span = self.next().span;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("function body"), span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_block_stmt(ParseType::MustParse)?
};
Ok(FuncDeclStmt { Ok(FuncDeclStmt {
return_type: return_type.into(), return_type: return_type.into(),
name, name,
@@ -126,11 +107,10 @@ impl Parser {
}) })
} }
fn parse_param_list(&mut self) -> Result<Vec<Param>, ParseProcessError> { fn parse_param_list(&mut self) -> Result<Vec<Param>, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::LParen { if self.peek().value != TokenValue::LParen {
let token = self.next().clone(); let token = self.next().clone();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`(`"), ParseError::ExpectedBefore(token.value, "`(`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -163,7 +143,6 @@ impl Parser {
Ok(params) Ok(params)
} }
fn parse_param(&mut self) -> Result<Param, ParseProcessError> { fn parse_param(&mut self) -> Result<Param, ParseProcessError> {
assert!(!self.is_eof());
let (param_type, name, type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?; let (param_type, name, type_span, name_span) = self.parse_type_and_name(ParseType::MustParse)?;
Ok(Param { Ok(Param {
param_type: param_type.into(), param_type: param_type.into(),
@@ -183,7 +162,7 @@ impl Parser {
// } else { // } else {
// let token = self.next().clone(); // let token = self.next().clone();
// self.diagnostics // self.diagnostics
// .add_from_frontend_error(ParseError::UnexpectedToken(token.value, "`;`"), token.span); // .add_from_frontend_error(ParseError::ExpectedBefore(token.value, "`;`"), token.span);
// while let Some(t) = self.peek() { // while let Some(t) = self.peek() {
// if matches!(t.value, TokenValue::Semicolon) { // if matches!(t.value, TokenValue::Semicolon) {
// self.advance(1); // self.advance(1);
@@ -202,7 +181,6 @@ impl Parser {
} }
pub(super) fn parse_var_decl_stmt_inner(&mut self, parse_type: ParseType, consume_semicolon: bool) -> Result<VarDeclStmt, ParseProcessError> { pub(super) fn parse_var_decl_stmt_inner(&mut self, parse_type: ParseType, consume_semicolon: bool) -> Result<VarDeclStmt, ParseProcessError> {
assert!(!self.is_eof());
let mut values = vec![]; let mut values = vec![];
let (var_type, name, type_span, name_span) = match self.parse_type_and_name(parse_type) { let (var_type, name, type_span, name_span) = match self.parse_type_and_name(parse_type) {
Ok(res) => res, Ok(res) => res,
@@ -231,13 +209,6 @@ impl Parser {
self.must_match_token(&TokenValue::Comma, "`,` or `;`")?; self.must_match_token(&TokenValue::Comma, "`,` or `;`")?;
last_name = false; last_name = false;
} }
// check eof again
if self.is_eof() {
let span = self.last().span;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("`,` or `;`"), span);
break;
}
if let Some(ident) = self.peek().value.as_ident() { if let Some(ident) = self.peek().value.as_ident() {
let span = self.next().span; let span = self.next().span;
let dimensions = self.parse_array_dimensions(false)?; let dimensions = self.parse_array_dimensions(false)?;
@@ -252,7 +223,7 @@ impl Parser {
} else { } else {
let token = self.next().clone(); let token = self.next().clone();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::CantCombineWith(TokenValue::TypeIdent(var_type)), ParseError::ExpectedIdentAfter(TokenValue::TypeIdent(var_type)),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -272,7 +243,7 @@ impl Parser {
if !allow_empty_first || !dimensions.is_empty() { if !allow_empty_first || !dimensions.is_empty() {
let span = self.peek().span; let span = self.peek().span;
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(TokenValue::RBracket, "array dimension expression"), ParseError::ExpectedBefore(TokenValue::RBracket, "array dimension expression"),
span, span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -288,13 +259,13 @@ impl Parser {
span span
} }
TokenValue::Eof => { TokenValue::Eof => {
self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), start_span); self.diagnostics.add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`]`"), start_span);
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
} }
_ => { _ => {
let token = self.next(); let token = self.next();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`]`"), ParseError::ExpectedBefore(token.value, "`]`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
+28 -145
View File
@@ -1,32 +1,14 @@
use crate::{ use crate::{
ast::err::ParseError,
ast::types::{BinaryOp, Expr, ExprValue, IncDecOp, UnaryOp}, ast::types::{BinaryOp, Expr, ExprValue, IncDecOp, UnaryOp},
diagnostic::span::Span, diagnostic::span::Span,
lexer::{ lexer::types::TokenValue,
err::ParseError,
types::TokenValue,
},
}; };
use super::{ParseProcessError, Parser}; use super::{ParseProcessError, Parser};
impl Parser { impl Parser {
// fn parse_expr_tail(&mut self, left: Expr) -> Option<Expr> {
// match self.peek() {
// None => Some(left),
// Some(t1) => {
// // TODO: add delimiter judge to support better error recovery
// let op = BinaryOp::from_token_value(&t1.value)?;
// match op {
// BinaryOp::Add
// }
// let right = self.parse_term()?;
// let expr = Expr { value: ExprValue::BinaryOp { lhs: Box::new(left), op, rhs: Box::new(right) }, span: Span::from_two(left.span, right.span) };
// self.parse_expr_tail(expr)
// }
// }
// }
fn parse_primary_atom(&mut self) -> Result<Expr, ParseProcessError> { fn parse_primary_atom(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let token = self.next().clone(); let token = self.next().clone();
match token.value { match token.value {
TokenValue::Ident(name) => { TokenValue::Ident(name) => {
@@ -45,7 +27,7 @@ impl Parser {
} }
TokenValue::Eof => { TokenValue::Eof => {
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("`)`"), ParseError::ExpectedBefore(TokenValue::Eof, "`)`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -67,7 +49,7 @@ impl Parser {
} }
TokenValue::Eof => { TokenValue::Eof => {
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("`)`"), ParseError::ExpectedBefore(TokenValue::Eof, "`)`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -75,7 +57,7 @@ impl Parser {
_ => { _ => {
let token = self.next(); let token = self.next();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`,` or `)`"), ParseError::ExpectedBefore(token.value, "`,` or `)`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -93,15 +75,7 @@ impl Parser {
span: token.span, span: token.span,
}), }),
TokenValue::LParen => { TokenValue::LParen => {
let expr = if self.is_eof() { let expr = self.parse_expr()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_expr()?
};
match &self.peek().value { match &self.peek().value {
TokenValue::RParen => { TokenValue::RParen => {
let end_span = self.peek().span; let end_span = self.peek().span;
@@ -113,13 +87,13 @@ impl Parser {
} }
TokenValue::Eof => { TokenValue::Eof => {
self.diagnostics self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("`)`"), expr.span); .add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`)`"), expr.span);
Err(ParseProcessError::ErrorInMatch) Err(ParseProcessError::ErrorInMatch)
} }
_ => { _ => {
let token = self.next(); let token = self.next();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`)`"), ParseError::ExpectedBefore(token.value, "`)`"),
token.span, token.span,
); );
Err(ParseProcessError::ErrorInMatch) Err(ParseProcessError::ErrorInMatch)
@@ -128,7 +102,7 @@ impl Parser {
} }
_ => { _ => {
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "expression"), ParseError::ExpectedBefore(token.value, "expression"),
token.span, token.span,
); );
Err(ParseProcessError::ErrorInMatch) Err(ParseProcessError::ErrorInMatch)
@@ -141,12 +115,7 @@ impl Parser {
if self.peek().value == TokenValue::LBracket { if self.peek().value == TokenValue::LBracket {
let start_span = expr.span; let start_span = expr.span;
self.advance(1); self.advance(1);
let index = if self.is_eof() { let index = self.parse_expr()?;
self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("array index expression"), start_span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_expr()?
};
let end_span = match &self.peek().value { let end_span = match &self.peek().value {
TokenValue::RBracket => { TokenValue::RBracket => {
let span = self.peek().span; let span = self.peek().span;
@@ -154,13 +123,13 @@ impl Parser {
span span
} }
TokenValue::Eof => { TokenValue::Eof => {
self.diagnostics.add_from_frontend_error(ParseError::ExpectButEof("`]`"), index.span); self.diagnostics.add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`]`"), index.span);
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
} }
_ => { _ => {
let token = self.next(); let token = self.next();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`]`"), ParseError::ExpectedBefore(token.value, "`]`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -198,21 +167,12 @@ impl Parser {
Ok(expr) Ok(expr)
} }
fn parse_unary(&mut self) -> Result<Expr, ParseProcessError> { fn parse_unary(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let token = self.peek().clone(); let token = self.peek().clone();
match token.value { match token.value {
TokenValue::Plus => { TokenValue::Plus => {
if self.peek_n(1).value == TokenValue::Plus { if self.peek_n(1).value == TokenValue::Plus {
self.advance(2); self.advance(2);
let expr = if self.is_eof() { let expr = self.parse_unary()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(token.span, expr.span); let span = Span::from_two(token.span, expr.span);
return Ok(Expr { return Ok(Expr {
value: ExprValue::IncDec { value: ExprValue::IncDec {
@@ -224,15 +184,7 @@ impl Parser {
}); });
} }
self.advance(1); self.advance(1);
let expr = if self.is_eof() { let expr = self.parse_unary()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(token.span, expr.span); let span = Span::from_two(token.span, expr.span);
Ok(Expr { Ok(Expr {
value: ExprValue::UnaryOp { value: ExprValue::UnaryOp {
@@ -245,15 +197,7 @@ impl Parser {
TokenValue::Minus => { TokenValue::Minus => {
if self.peek_n(1).value == TokenValue::Minus { if self.peek_n(1).value == TokenValue::Minus {
self.advance(2); self.advance(2);
let rhs = if self.is_eof() { let rhs = self.parse_unary()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(token.span, rhs.span); let span = Span::from_two(token.span, rhs.span);
return Ok(Expr { return Ok(Expr {
value: ExprValue::IncDec { value: ExprValue::IncDec {
@@ -265,15 +209,7 @@ impl Parser {
}); });
} }
self.advance(1); self.advance(1);
let rhs = if self.is_eof() { let rhs = self.parse_unary()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(token.span, rhs.span); let span = Span::from_two(token.span, rhs.span);
Ok(Expr { Ok(Expr {
value: ExprValue::UnaryOp { value: ExprValue::UnaryOp {
@@ -285,15 +221,7 @@ impl Parser {
} }
TokenValue::Not => { TokenValue::Not => {
self.advance(1); self.advance(1);
let rhs = if self.is_eof() { let rhs = self.parse_unary()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
token.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(token.span, rhs.span); let span = Span::from_two(token.span, rhs.span);
Ok(Expr { Ok(Expr {
value: ExprValue::UnaryOp { value: ExprValue::UnaryOp {
@@ -307,9 +235,8 @@ impl Parser {
} }
} }
fn parse_multiplicative(&mut self) -> Result<Expr, ParseProcessError> { fn parse_multiplicative(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let mut left = self.parse_unary()?; let mut left = self.parse_unary()?;
while !self.is_eof() { loop {
let op = match self.peek().value { let op = match self.peek().value {
TokenValue::Star => BinaryOp::Mul, TokenValue::Star => BinaryOp::Mul,
TokenValue::Slash => BinaryOp::Div, TokenValue::Slash => BinaryOp::Div,
@@ -317,13 +244,7 @@ impl Parser {
_ => break, _ => break,
}; };
self.advance(1); self.advance(1);
let right = if self.is_eof() { let right = self.parse_unary()?;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_unary()?
};
let span = Span::from_two(left.span, right.span); let span = Span::from_two(left.span, right.span);
left = Expr { left = Expr {
value: ExprValue::BinaryOp { value: ExprValue::BinaryOp {
@@ -337,22 +258,15 @@ impl Parser {
Ok(left) Ok(left)
} }
fn parse_additive(&mut self) -> Result<Expr, ParseProcessError> { fn parse_additive(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let mut left = self.parse_multiplicative()?; let mut left = self.parse_multiplicative()?;
while !self.is_eof() { loop {
let op = match self.peek().value { let op = match self.peek().value {
TokenValue::Plus => BinaryOp::Add, TokenValue::Plus => BinaryOp::Add,
TokenValue::Minus => BinaryOp::Sub, TokenValue::Minus => BinaryOp::Sub,
_ => break, _ => break,
}; };
self.advance(1); self.advance(1);
let right = if self.is_eof() { let right = self.parse_multiplicative()?;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_multiplicative()?
};
let span = Span::from_two(left.span, right.span); let span = Span::from_two(left.span, right.span);
left = Expr { left = Expr {
value: ExprValue::BinaryOp { value: ExprValue::BinaryOp {
@@ -366,9 +280,8 @@ impl Parser {
Ok(left) Ok(left)
} }
fn parse_relational(&mut self) -> Result<Expr, ParseProcessError> { fn parse_relational(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let mut left = self.parse_additive()?; let mut left = self.parse_additive()?;
while !self.is_eof() { loop {
let op = match self.peek().value { let op = match self.peek().value {
TokenValue::Less => BinaryOp::Less, TokenValue::Less => BinaryOp::Less,
TokenValue::Greater => BinaryOp::Greater, TokenValue::Greater => BinaryOp::Greater,
@@ -379,13 +292,7 @@ impl Parser {
_ => break, _ => break,
}; };
self.advance(1); self.advance(1);
let right = if self.is_eof() { let right = self.parse_additive()?;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_additive()?
};
let span = Span::from_two(left.span, right.span); let span = Span::from_two(left.span, right.span);
left = Expr { left = Expr {
value: ExprValue::BinaryOp { value: ExprValue::BinaryOp {
@@ -399,21 +306,14 @@ impl Parser {
Ok(left) Ok(left)
} }
fn parse_logical_and(&mut self) -> Result<Expr, ParseProcessError> { fn parse_logical_and(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let mut left = self.parse_relational()?; let mut left = self.parse_relational()?;
while !self.is_eof() { loop {
let op = match self.peek().value { let op = match self.peek().value {
TokenValue::And => BinaryOp::And, TokenValue::And => BinaryOp::And,
_ => break, _ => break,
}; };
self.advance(1); self.advance(1);
let right = if self.is_eof() { let right = self.parse_relational()?;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_relational()?
};
let span = Span::from_two(left.span, right.span); let span = Span::from_two(left.span, right.span);
left = Expr { left = Expr {
value: ExprValue::BinaryOp { value: ExprValue::BinaryOp {
@@ -427,21 +327,14 @@ impl Parser {
Ok(left) Ok(left)
} }
fn parse_logical_or(&mut self) -> Result<Expr, ParseProcessError> { fn parse_logical_or(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let mut left = self.parse_logical_and()?; let mut left = self.parse_logical_and()?;
while !self.is_eof() { loop {
let op = match self.peek().value { let op = match self.peek().value {
TokenValue::Or => BinaryOp::Or, TokenValue::Or => BinaryOp::Or,
_ => break, _ => break,
}; };
self.advance(1); self.advance(1);
let right = if self.is_eof() { let right = self.parse_logical_and()?;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("expression"), left.span);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_logical_and()?
};
let span = Span::from_two(left.span, right.span); let span = Span::from_two(left.span, right.span);
left = Expr { left = Expr {
value: ExprValue::BinaryOp { value: ExprValue::BinaryOp {
@@ -455,21 +348,12 @@ impl Parser {
Ok(left) Ok(left)
} }
fn parse_assign(&mut self) -> Result<Expr, ParseProcessError> { fn parse_assign(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
let lvalue = self.parse_logical_or()?; let lvalue = self.parse_logical_or()?;
if self.peek().value != TokenValue::Equal { if self.peek().value != TokenValue::Equal {
return Ok(lvalue); return Ok(lvalue);
} }
self.advance(1); self.advance(1);
let rvalue = if self.is_eof() { let rvalue = self.parse_assign()?;
self.diagnostics.add_from_frontend_error(
ParseError::ExpectButEof("expression"),
lvalue.span,
);
return Err(ParseProcessError::ErrorInMatch);
} else {
self.parse_assign()?
};
let span = Span::from_two(lvalue.span, rvalue.span); let span = Span::from_two(lvalue.span, rvalue.span);
Ok(Expr { Ok(Expr {
value: ExprValue::Assign { value: ExprValue::Assign {
@@ -480,7 +364,6 @@ impl Parser {
}) })
} }
pub(super) fn parse_expr(&mut self) -> Result<Expr, ParseProcessError> { pub(super) fn parse_expr(&mut self) -> Result<Expr, ParseProcessError> {
assert!(!self.is_eof());
self.parse_assign() self.parse_assign()
} }
} }
+4 -11
View File
@@ -1,10 +1,8 @@
use crate::{ use crate::{
ast::err::ParseError,
ast::types::CompileUnit, ast::types::CompileUnit,
diagnostic::{Diagnositics, span::Span}, diagnostic::{Diagnositics, span::Span},
lexer::{ lexer::types::{Token, TokenValue},
err::ParseError,
types::{Token, TokenValue},
},
}; };
mod decl; mod decl;
@@ -83,15 +81,10 @@ impl Parser {
if &self.peek().value == expected { if &self.peek().value == expected {
self.advance(1); self.advance(1);
Ok(()) Ok(())
} else if self.is_eof() {
let span = self.peek().span;
self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof(diagnostic_text), span);
Err(ParseProcessError::ErrorInMatch)
} else { } else {
let token = self.next(); let token = self.next();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, diagnostic_text), ParseError::ExpectedBefore(token.value, diagnostic_text),
token.span, token.span,
); );
Err(ParseProcessError::ErrorInMatch) Err(ParseProcessError::ErrorInMatch)
@@ -101,7 +94,7 @@ impl Parser {
if self.is_eof() { if self.is_eof() {
let span = self.last().span; let span = self.last().span;
self.diagnostics self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof(diagnostic_text), span); .add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, diagnostic_text), span);
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
} }
Ok(()) Ok(())
+4 -14
View File
@@ -1,24 +1,21 @@
use crate::{ use crate::{
ast::err::ParseError,
ast::types::{ ast::types::{
BlockStmt, BreakStmt, ContinueStmt, ForInit, ForStmt, IfElseBranch, IfStmt, ReturnStmt, BlockStmt, BreakStmt, ContinueStmt, ForInit, ForStmt, IfElseBranch, IfStmt, ReturnStmt,
Statement, WhileStmt, Statement, WhileStmt,
}, },
lexer::{ lexer::types::TokenValue,
err::ParseError,
types::TokenValue,
},
}; };
use super::{ParseProcessError, ParseType, Parser}; use super::{ParseProcessError, ParseType, Parser};
impl Parser { impl Parser {
pub(super) fn parse_block_stmt(&mut self, parse_type: ParseType) -> Result<BlockStmt, ParseProcessError> { pub(super) fn parse_block_stmt(&mut self, parse_type: ParseType) -> Result<BlockStmt, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::LBrace { if self.peek().value != TokenValue::LBrace {
if parse_type == ParseType::MustParse { if parse_type == ParseType::MustParse {
let token = self.next().clone(); let token = self.next().clone();
self.diagnostics.add_from_frontend_error( self.diagnostics.add_from_frontend_error(
ParseError::UnexpectedToken(token.value, "`{`"), ParseError::ExpectedBefore(token.value, "`{`"),
token.span, token.span,
); );
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
@@ -32,7 +29,7 @@ impl Parser {
if self.is_eof() { if self.is_eof() {
let span = self.last().span; let span = self.last().span;
self.diagnostics self.diagnostics
.add_from_frontend_error(ParseError::ExpectButEof("`}`"), span); .add_from_frontend_error(ParseError::ExpectedBefore(TokenValue::Eof, "`}`"), span);
return Err(ParseProcessError::ErrorInMatch); return Err(ParseProcessError::ErrorInMatch);
} }
if matches!(self.peek().value, TokenValue::Semicolon) { if matches!(self.peek().value, TokenValue::Semicolon) {
@@ -62,7 +59,6 @@ impl Parser {
} }
fn parse_stmt(&mut self) -> Result<Statement, ParseProcessError> { fn parse_stmt(&mut self) -> Result<Statement, ParseProcessError> {
assert!(!self.is_eof());
match self.parse_var_decl_stmt(ParseType::TryParse) { match self.parse_var_decl_stmt(ParseType::TryParse) {
Ok(var_decl) => return Ok(Statement::VarDecl(var_decl)), Ok(var_decl) => return Ok(Statement::VarDecl(var_decl)),
Err(ParseProcessError::ErrorInMatch) => return Err(ParseProcessError::ErrorInMatch), Err(ParseProcessError::ErrorInMatch) => return Err(ParseProcessError::ErrorInMatch),
@@ -116,7 +112,6 @@ impl Parser {
} }
fn parse_return_stmt(&mut self) -> Result<ReturnStmt, ParseProcessError> { fn parse_return_stmt(&mut self) -> Result<ReturnStmt, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::Return { if self.peek().value != TokenValue::Return {
return Err(ParseProcessError::TryNext); return Err(ParseProcessError::TryNext);
} }
@@ -133,7 +128,6 @@ impl Parser {
}) })
} }
fn parse_if_stmt(&mut self) -> Result<IfStmt, ParseProcessError> { fn parse_if_stmt(&mut self) -> Result<IfStmt, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::If { if self.peek().value != TokenValue::If {
return Err(ParseProcessError::TryNext); return Err(ParseProcessError::TryNext);
} }
@@ -202,7 +196,6 @@ impl Parser {
} }
fn parse_while_stmt(&mut self) -> Result<WhileStmt, ParseProcessError> { fn parse_while_stmt(&mut self) -> Result<WhileStmt, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::While { if self.peek().value != TokenValue::While {
return Err(ParseProcessError::TryNext); return Err(ParseProcessError::TryNext);
} }
@@ -225,7 +218,6 @@ impl Parser {
} }
fn parse_for_stmt(&mut self) -> Result<ForStmt, ParseProcessError> { fn parse_for_stmt(&mut self) -> Result<ForStmt, ParseProcessError> {
assert!(!self.is_eof());
if self.peek().value != TokenValue::For { if self.peek().value != TokenValue::For {
return Err(ParseProcessError::TryNext); return Err(ParseProcessError::TryNext);
} }
@@ -267,7 +259,6 @@ impl Parser {
} }
fn parse_break_stmt(&mut self) -> Result<BreakStmt, ParseProcessError> { fn parse_break_stmt(&mut self) -> Result<BreakStmt, ParseProcessError> {
assert!(!self.is_eof());
let start_span = self.peek().span; let start_span = self.peek().span;
if self.peek().value == TokenValue::Break { if self.peek().value == TokenValue::Break {
self.advance(1); self.advance(1);
@@ -281,7 +272,6 @@ impl Parser {
} }
fn parse_continue_stmt(&mut self) -> Result<ContinueStmt, ParseProcessError> { fn parse_continue_stmt(&mut self) -> Result<ContinueStmt, ParseProcessError> {
assert!(!self.is_eof());
let start_span = self.peek().span; let start_span = self.peek().span;
if self.peek().value == TokenValue::Continue { if self.peek().value == TokenValue::Continue {
self.advance(1); self.advance(1);
+1 -19
View File
@@ -1,16 +1,7 @@
use thiserror::Error; use thiserror::Error;
use crate::lexer::types::TokenValue; use crate::ast::err::ParseError;
// #[derive(Debug, Clone, PartialEq, Eq, Error)]
// pub enum ParseError {
// BlockStmt(#[from] BlockStmtError)
// }
// #[derive(Debug, Clone, PartialEq, Eq, Error)]
// pub enum BlockStmtError {
// MissingLBrace,
// MissingRBrace,
// }
#[derive(Debug, Clone, PartialEq, Eq, Error)] #[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum LexingError { pub enum LexingError {
#[error("invalid int literal")] #[error("invalid int literal")]
@@ -23,15 +14,6 @@ pub enum LexingError {
UnrecognizedToken(String), UnrecognizedToken(String),
} }
#[derive(Debug, Clone, PartialEq, Eq, Error)] #[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum ParseError {
#[error("unexpected token {}, expect {}", .0, .1)]
UnexpectedToken(TokenValue, &'static str),
#[error("cannot combine with previous {}", .0)]
CantCombineWith(TokenValue),
#[error("expect {0} after")]
ExpectButEof(&'static str),
}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum FrontendError { pub enum FrontendError {
#[error(transparent)] #[error(transparent)]
Lexing(#[from] LexingError), Lexing(#[from] LexingError),
+1 -1
View File
@@ -81,7 +81,7 @@ impl std::fmt::Display for TokenValue {
TokenValue::Return => write!(f, "return"), TokenValue::Return => write!(f, "return"),
TokenValue::Break => write!(f, "break"), TokenValue::Break => write!(f, "break"),
TokenValue::Continue => write!(f, "continue"), TokenValue::Continue => write!(f, "continue"),
TokenValue::Eof => write!(f, "<EOF>"), TokenValue::Eof => write!(f, "end of input"),
TokenValue::Unrecognized => write!(f, "unrecognized"), TokenValue::Unrecognized => write!(f, "unrecognized"),
} }
} }