refactor(ast): Improve error type, remove unnecessary eof judge
This commit is contained in:
@@ -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,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user