feat: 更新错误处理机制,增强词法分析器和解析器的错误报告功能

This commit is contained in:
0264408
2026-06-16 14:24:49 +08:00
parent e052226cdb
commit c7e4e0dce0
4 changed files with 240 additions and 155 deletions
+22
View File
@@ -2,13 +2,35 @@ use crate::lexer::Token;
#[derive(Debug)] #[derive(Debug)]
pub enum RuntimeError { pub enum RuntimeError {
LexError { message: String, line: usize, column: usize },
ParseError { message: String, token: Token }, ParseError { message: String, token: Token },
RuntimeError { message: String, token: Option<Token> }, RuntimeError { message: String, token: Option<Token> },
} }
impl RuntimeError {
pub fn lex(message: impl Into<String>, line: usize, column: usize) -> Self {
RuntimeError::LexError {
message: message.into(),
line,
column,
}
}
pub fn parse(message: impl Into<String>, token: Token) -> Self {
RuntimeError::ParseError {
message: message.into(),
token,
}
}
}
impl std::fmt::Display for RuntimeError { impl std::fmt::Display for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
RuntimeError::LexError { message, line, column } => {
write!(f, "[Lex Error] {} at line {}, column {}", message, line, column)
}
RuntimeError::ParseError { message, token } => { RuntimeError::ParseError { message, token } => {
write!(f, "[Parse Error] {} at line {}, column {}", message, token.line, token.column) write!(f, "[Parse Error] {} at line {}, column {}", message, token.line, token.column)
} }
+27 -12
View File
@@ -1,6 +1,7 @@
// src/lexer/lexer.rs // src/lexer/lexer.rs
use super::{Token, TokenKind}; use super::{Token, TokenKind};
use crate::error::RuntimeError;
pub struct Lexer { pub struct Lexer {
src: Vec<char>, src: Vec<char>,
@@ -19,11 +20,12 @@ impl Lexer {
} }
} }
pub fn tokenize(mut self) -> Vec<Token> { pub fn tokenize(mut self) -> (Vec<Token>, Vec<RuntimeError>) {
let mut tokens = Vec::new(); let mut tokens = Vec::new();
let mut errors = Vec::new();
while !self.is_at_end() { while !self.is_at_end() {
if let Some(token) = self.next_token() { if let Some(token) = self.next_token(&mut errors) {
tokens.push(token); tokens.push(token);
} }
} }
@@ -34,10 +36,10 @@ impl Lexer {
column: self.column, column: self.column,
}); });
tokens (tokens, errors)
} }
fn next_token(&mut self) -> Option<Token> { fn next_token(&mut self, errors: &mut Vec<RuntimeError>) -> Option<Token> {
self.skip_whitespace(); self.skip_whitespace();
if self.is_at_end() { if self.is_at_end() {
@@ -140,7 +142,8 @@ impl Lexer {
if self.match_char('&') { if self.match_char('&') {
TokenKind::AndAnd TokenKind::AndAnd
} else { } else {
panic!("Unexpected '&' at {}:{}", line, column); errors.push(RuntimeError::lex("Unexpected '&'. Did you mean '&&'?", line, column));
return None;
} }
} }
@@ -148,11 +151,12 @@ impl Lexer {
if self.match_char('|') { if self.match_char('|') {
TokenKind::OrOr TokenKind::OrOr
} else { } else {
panic!("Unexpected '|' at {}:{}", line, column); errors.push(RuntimeError::lex("Unexpected '|'. Did you mean '||'?", line, column));
return None;
} }
} }
'"' => return Some(self.string_literal(line, column)), '"' => return self.string_literal(line, column, errors),
c if c.is_ascii_digit() => { c if c.is_ascii_digit() => {
return Some(self.number_literal(c, line, column)); return Some(self.number_literal(c, line, column));
@@ -163,7 +167,12 @@ impl Lexer {
} }
_ => { _ => {
panic!("Unexpected character '{}' at {}:{}", c, line, column); errors.push(RuntimeError::lex(
format!("Unexpected character '{}'", c),
line,
column,
));
return None;
} }
}; };
@@ -215,7 +224,12 @@ impl Lexer {
self.current >= self.src.len() self.current >= self.src.len()
} }
fn string_literal(&mut self, line: usize, column: usize) -> Token { fn string_literal(
&mut self,
line: usize,
column: usize,
errors: &mut Vec<RuntimeError>,
) -> Option<Token> {
let mut value = String::new(); let mut value = String::new();
while !self.is_at_end() && self.peek() != '"' { while !self.is_at_end() && self.peek() != '"' {
@@ -223,16 +237,17 @@ impl Lexer {
} }
if self.is_at_end() { if self.is_at_end() {
panic!("Unterminated string at {}:{}", line, column); errors.push(RuntimeError::lex("Unterminated string literal", line, column));
return None;
} }
self.advance(); // consume closing " self.advance(); // consume closing "
Token { Some(Token {
kind: TokenKind::String(value), kind: TokenKind::String(value),
line, line,
column, column,
} })
} }
fn number_literal(&mut self, first: char, line: usize, column: usize) -> Token { fn number_literal(&mut self, first: char, line: usize, column: usize) -> Token {
+30 -5
View File
@@ -7,21 +7,37 @@ mod error;
use lexer::Lexer; use lexer::Lexer;
use parser::Parser; use parser::Parser;
use interpreter::Interpreter; use interpreter::Interpreter;
use error::RuntimeError;
use std::env; use std::env;
use std::fs; use std::fs;
use std::io::Write; use std::io::Write;
use std::io::stdin; use std::io::stdin;
use std::io::stdout; use std::io::stdout;
fn print_errors(errors: &[RuntimeError]) {
for err in errors {
eprintln!("{}", err);
}
}
fn run_file(src: String) { fn run_file(src: String) {
let tokens = Lexer::new(&src).tokenize(); let (tokens, lex_errors) = Lexer::new(&src).tokenize();
if !lex_errors.is_empty() {
print_errors(&lex_errors);
std::process::exit(65);
}
let mut parser = Parser::new(tokens); let mut parser = Parser::new(tokens);
let stmts = parser.parse(); let (stmts, parse_errors) = parser.parse();
if !parse_errors.is_empty() {
print_errors(&parse_errors);
std::process::exit(65);
}
let mut interpreter = Interpreter::new(); let mut interpreter = Interpreter::new();
if let Err(e) = interpreter.interpret(stmts) { if let Err(e) = interpreter.interpret(stmts) {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);
std::process::exit(1); std::process::exit(70);
} }
} }
@@ -61,9 +77,18 @@ fn run_repl() {
_ => {} _ => {}
} }
let tokens = Lexer::new(line).tokenize(); let (tokens, lex_errors) = Lexer::new(line).tokenize();
if !lex_errors.is_empty() {
print_errors(&lex_errors);
continue;
}
let mut parser = Parser::new(tokens); let mut parser = Parser::new(tokens);
let stmts = parser.parse(); let (stmts, parse_errors) = parser.parse();
if !parse_errors.is_empty() {
print_errors(&parse_errors);
continue;
}
if let Err(e) = interpreter.interpret(stmts) { if let Err(e) = interpreter.interpret(stmts) {
eprintln!("Error: {}", e); eprintln!("Error: {}", e);
+161 -138
View File
@@ -12,17 +12,24 @@ impl Parser {
Self { tokens, current: 0 } Self { tokens, current: 0 }
} }
pub fn parse(&mut self) -> Vec<Stmt> { pub fn parse(&mut self) -> (Vec<Stmt>, Vec<RuntimeError>) {
let mut statements = Vec::new(); let mut statements = Vec::new();
let mut errors = Vec::new();
while !self.is_at_end() { while !self.is_at_end() {
statements.push(self.declaration()); match self.declaration() {
Ok(stmt) => statements.push(stmt),
Err(err) => {
errors.push(err);
self.synchronize();
}
}
} }
statements (statements, errors)
} }
fn declaration(&mut self) -> Stmt { fn declaration(&mut self) -> Result<Stmt, RuntimeError> {
if self.match_kind(&[TokenKind::Let]) { if self.match_kind(&[TokenKind::Let]) {
self.let_declaration() self.let_declaration()
} else if self.match_kind(&[TokenKind::Fn]) { } else if self.match_kind(&[TokenKind::Fn]) {
@@ -32,7 +39,7 @@ impl Parser {
} }
} }
fn statement(&mut self) -> Stmt { fn statement(&mut self) -> Result<Stmt, RuntimeError> {
if self.match_kind(&[TokenKind::If]) { if self.match_kind(&[TokenKind::If]) {
self.if_statement() self.if_statement()
} else if self.match_kind(&[TokenKind::While]) { } else if self.match_kind(&[TokenKind::While]) {
@@ -46,161 +53,161 @@ impl Parser {
} else if self.match_kind(&[TokenKind::Return]) { } else if self.match_kind(&[TokenKind::Return]) {
self.return_statement() self.return_statement()
} else if self.match_kind(&[TokenKind::LeftBrace]) { } else if self.match_kind(&[TokenKind::LeftBrace]) {
Stmt::Block(self.block()) Ok(Stmt::Block(self.block()?))
} else { } else {
self.expression_statement() self.expression_statement()
} }
} }
fn let_declaration(&mut self) -> Stmt { fn let_declaration(&mut self) -> Result<Stmt, RuntimeError> {
let name = self.consume_ident("Expected variable name.").unwrap(); let name = self.consume_ident("Expected variable name.")?;
self.consume(TokenKind::Equal, "Expected '=' after variable name.").unwrap(); self.consume(TokenKind::Equal, "Expected '=' after variable name.")?;
let initializer = self.expression(); let initializer = self.expression()?;
self.match_kind(&[TokenKind::Semicolon]); // 分号可选 self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::Let { name, initializer } Ok(Stmt::Let { name, initializer })
} }
fn fn_declaration(&mut self) -> Stmt { fn fn_declaration(&mut self) -> Result<Stmt, RuntimeError> {
let name = self.consume_ident("Expected function name.").unwrap(); let name = self.consume_ident("Expected function name.")?;
self.consume(TokenKind::LeftParen, "Expected '(' after function name.").unwrap(); self.consume(TokenKind::LeftParen, "Expected '(' after function name.")?;
let mut params = Vec::new(); let mut params = Vec::new();
if !self.check(&TokenKind::RightParen) { if !self.check(&TokenKind::RightParen) {
loop { loop {
params.push(self.consume_ident("Expected parameter name.").unwrap()); params.push(self.consume_ident("Expected parameter name.")?);
if !self.match_kind(&[TokenKind::Comma]) { if !self.match_kind(&[TokenKind::Comma]) {
break; break;
} }
} }
} }
self.consume(TokenKind::RightParen, "Expected ')' after parameters.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after parameters.")?;
self.consume(TokenKind::LeftBrace, "Expected '{' before function body.").unwrap(); self.consume(TokenKind::LeftBrace, "Expected '{' before function body.")?;
let body = self.block(); let body = self.block()?;
Stmt::Function { name, params, body } Ok(Stmt::Function { name, params, body })
} }
fn lambda_expr(&mut self) -> Expr { fn lambda_expr(&mut self) -> Result<Expr, RuntimeError> {
self.consume(TokenKind::LeftParen, "Expected '(' after 'fn'.").unwrap(); self.consume(TokenKind::LeftParen, "Expected '(' after 'fn'.")?;
let mut params = Vec::new(); let mut params = Vec::new();
if !self.check(&TokenKind::RightParen) { if !self.check(&TokenKind::RightParen) {
loop { loop {
params.push(self.consume_ident("Expected parameter name.").unwrap()); params.push(self.consume_ident("Expected parameter name.")?);
if !self.match_kind(&[TokenKind::Comma]) { if !self.match_kind(&[TokenKind::Comma]) {
break; break;
} }
} }
} }
self.consume(TokenKind::RightParen, "Expected ')' after parameters.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after parameters.")?;
self.consume(TokenKind::LeftBrace, "Expected '{' before function body.").unwrap(); self.consume(TokenKind::LeftBrace, "Expected '{' before function body.")?;
let body = self.block(); let body = self.block()?;
Expr::Lambda { params, body } Ok(Expr::Lambda { params, body })
} }
fn if_statement(&mut self) -> Stmt { fn if_statement(&mut self) -> Result<Stmt, RuntimeError> {
self.consume(TokenKind::LeftParen, "Expected '(' after 'if'.").unwrap(); self.consume(TokenKind::LeftParen, "Expected '(' after 'if'.")?;
let condition = self.expression(); let condition = self.expression()?;
self.consume(TokenKind::RightParen, "Expected ')' after condition.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after condition.")?;
let then_branch = Box::new(self.statement()); let then_branch = Box::new(self.statement()?);
let else_branch = if self.match_kind(&[TokenKind::Else]) { let else_branch = if self.match_kind(&[TokenKind::Else]) {
Some(Box::new(self.statement())) Some(Box::new(self.statement()?))
} else { } else {
None None
}; };
Stmt::If { condition, then_branch, else_branch } Ok(Stmt::If { condition, then_branch, else_branch })
} }
fn while_statement(&mut self) -> Stmt { fn while_statement(&mut self) -> Result<Stmt, RuntimeError> {
self.consume(TokenKind::LeftParen, "Expected '(' after 'while'.").unwrap(); self.consume(TokenKind::LeftParen, "Expected '(' after 'while'.")?;
let condition = self.expression(); let condition = self.expression()?;
self.consume(TokenKind::RightParen, "Expected ')' after condition.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after condition.")?;
let body = Box::new(self.statement()); let body = Box::new(self.statement()?);
Stmt::While { condition, body } Ok(Stmt::While { condition, body })
} }
fn for_statement(&mut self) -> Stmt { fn for_statement(&mut self) -> Result<Stmt, RuntimeError> {
self.consume(TokenKind::LeftParen, "Expected '(' after 'for'.").unwrap(); self.consume(TokenKind::LeftParen, "Expected '(' after 'for'.")?;
let initializer = if self.match_kind(&[TokenKind::Semicolon]) { let initializer = if self.match_kind(&[TokenKind::Semicolon]) {
None None
} else if self.match_kind(&[TokenKind::Let]) { } else if self.match_kind(&[TokenKind::Let]) {
Some(self.let_declaration()) Some(self.let_declaration()?)
} else { } else {
Some(self.expression_statement()) Some(self.expression_statement()?)
}; };
let condition = if !self.check(&TokenKind::Semicolon) { let condition = if !self.check(&TokenKind::Semicolon) {
Some(self.expression()) Some(self.expression()?)
} else { } else {
None None
}; };
self.consume(TokenKind::Semicolon, "Expected ';' after loop condition.").unwrap(); self.consume(TokenKind::Semicolon, "Expected ';' after loop condition.")?;
let step = if !self.check(&TokenKind::RightParen) { let step = if !self.check(&TokenKind::RightParen) {
Some(self.expression()) Some(self.expression()?)
} else { } else {
None None
}; };
self.consume(TokenKind::RightParen, "Expected ')' after for clauses.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after for clauses.")?;
let body = Box::new(self.statement()); let body = Box::new(self.statement()?);
Stmt::For { Ok(Stmt::For {
initializer: initializer.map(Box::new), initializer: initializer.map(Box::new),
condition, condition,
step, step,
body body
} })
} }
fn break_statement(&mut self) -> Stmt { fn break_statement(&mut self) -> Result<Stmt, RuntimeError> {
self.match_kind(&[TokenKind::Semicolon]); // 分号可选 self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::Break Ok(Stmt::Break)
} }
fn continue_statement(&mut self) -> Stmt { fn continue_statement(&mut self) -> Result<Stmt, RuntimeError> {
self.match_kind(&[TokenKind::Semicolon]); // 分号可选 self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::Continue Ok(Stmt::Continue)
} }
fn return_statement(&mut self) -> Stmt { fn return_statement(&mut self) -> Result<Stmt, RuntimeError> {
let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) { let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) {
Some(self.expression()) Some(self.expression()?)
} else { } else {
None None
}; };
self.match_kind(&[TokenKind::Semicolon]); // 分号可选 self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::Return(value) Ok(Stmt::Return(value))
} }
fn block(&mut self) -> Vec<Stmt> { fn block(&mut self) -> Result<Vec<Stmt>, RuntimeError> {
let mut statements = Vec::new(); let mut statements = Vec::new();
while !self.check(&TokenKind::RightBrace) && !self.is_at_end() { while !self.check(&TokenKind::RightBrace) && !self.is_at_end() {
statements.push(self.declaration()); statements.push(self.declaration()?);
} }
self.consume(TokenKind::RightBrace, "Expected '}' after block.").unwrap(); self.consume(TokenKind::RightBrace, "Expected '}' after block.")?;
statements Ok(statements)
} }
fn expression_statement(&mut self) -> Stmt { fn expression_statement(&mut self) -> Result<Stmt, RuntimeError> {
let expr = self.expression(); let expr = self.expression()?;
self.match_kind(&[TokenKind::Semicolon]); // 分号可选 self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Stmt::ExprStmt(expr) Ok(Stmt::ExprStmt(expr))
} }
fn expression(&mut self) -> Expr { fn expression(&mut self) -> Result<Expr, RuntimeError> {
self.assignment() self.assignment()
} }
fn assignment(&mut self) -> Expr { fn assignment(&mut self) -> Result<Expr, RuntimeError> {
let expr = self.logical_or(); let expr = self.logical_or()?;
let op = if self.match_kind(&[TokenKind::Equal]) { let op = if self.match_kind(&[TokenKind::Equal]) {
Some(AssignOp::Equal) Some(AssignOp::Equal)
@@ -219,23 +226,23 @@ impl Parser {
}; };
if let Some(op) = op { if let Some(op) = op {
let value = self.assignment(); let value = self.assignment()?;
return match expr { return match expr {
Expr::Variable(name) => Expr::Assign { name, op, value: Box::new(value) }, Expr::Variable(name) => Ok(Expr::Assign { name, op, value: Box::new(value) }),
Expr::Get { object, name } => Expr::Set { object, name, op, value: Box::new(value) }, Expr::Get { object, name } => Ok(Expr::Set { object, name, op, value: Box::new(value) }),
Expr::IndexGet { array, index } => Expr::IndexSet { array, index, op, value: Box::new(value) }, Expr::IndexGet { array, index } => Ok(Expr::IndexSet { array, index, op, value: Box::new(value) }),
_ => panic!("Invalid assignment target."), _ => Err(RuntimeError::parse("Invalid assignment target.", self.previous().clone())),
}; };
} }
expr Ok(expr)
} }
fn logical_or(&mut self) -> Expr { fn logical_or(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.logical_and(); let mut expr = self.logical_and()?;
while self.match_kind(&[TokenKind::OrOr]) { while self.match_kind(&[TokenKind::OrOr]) {
let right = self.logical_and(); let right = self.logical_and()?;
expr = Expr::Logical { expr = Expr::Logical {
left: Box::new(expr), left: Box::new(expr),
op: LogicalOp::Or, op: LogicalOp::Or,
@@ -243,14 +250,14 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn logical_and(&mut self) -> Expr { fn logical_and(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.equality(); let mut expr = self.equality()?;
while self.match_kind(&[TokenKind::AndAnd]) { while self.match_kind(&[TokenKind::AndAnd]) {
let right = self.equality(); let right = self.equality()?;
expr = Expr::Logical { expr = Expr::Logical {
left: Box::new(expr), left: Box::new(expr),
op: LogicalOp::And, op: LogicalOp::And,
@@ -258,11 +265,11 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn equality(&mut self) -> Expr { fn equality(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.comparison(); let mut expr = self.comparison()?;
while self.match_kind(&[TokenKind::EqualEqual, TokenKind::BangEqual]) { while self.match_kind(&[TokenKind::EqualEqual, TokenKind::BangEqual]) {
let op = match self.previous().kind { let op = match self.previous().kind {
@@ -270,7 +277,7 @@ impl Parser {
TokenKind::BangEqual => BinaryOp::NotEqual, TokenKind::BangEqual => BinaryOp::NotEqual,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.comparison(); let right = self.comparison()?;
expr = Expr::Binary { expr = Expr::Binary {
left: Box::new(expr), left: Box::new(expr),
op, op,
@@ -278,11 +285,11 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn comparison(&mut self) -> Expr { fn comparison(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.term(); let mut expr = self.term()?;
while self.match_kind(&[TokenKind::Greater, TokenKind::GreaterEqual, TokenKind::Less, TokenKind::LessEqual]) { while self.match_kind(&[TokenKind::Greater, TokenKind::GreaterEqual, TokenKind::Less, TokenKind::LessEqual]) {
let op = match self.previous().kind { let op = match self.previous().kind {
@@ -292,7 +299,7 @@ impl Parser {
TokenKind::LessEqual => BinaryOp::LessEqual, TokenKind::LessEqual => BinaryOp::LessEqual,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.term(); let right = self.term()?;
expr = Expr::Binary { expr = Expr::Binary {
left: Box::new(expr), left: Box::new(expr),
op, op,
@@ -300,11 +307,11 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn term(&mut self) -> Expr { fn term(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.factor(); let mut expr = self.factor()?;
while self.match_kind(&[TokenKind::Plus, TokenKind::Minus]) { while self.match_kind(&[TokenKind::Plus, TokenKind::Minus]) {
let op = match self.previous().kind { let op = match self.previous().kind {
@@ -312,7 +319,7 @@ impl Parser {
TokenKind::Minus => BinaryOp::Sub, TokenKind::Minus => BinaryOp::Sub,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.factor(); let right = self.factor()?;
expr = Expr::Binary { expr = Expr::Binary {
left: Box::new(expr), left: Box::new(expr),
op, op,
@@ -320,11 +327,11 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn factor(&mut self) -> Expr { fn factor(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.unary(); let mut expr = self.unary()?;
while self.match_kind(&[TokenKind::Star, TokenKind::Slash, TokenKind::Percent]) { while self.match_kind(&[TokenKind::Star, TokenKind::Slash, TokenKind::Percent]) {
let op = match self.previous().kind { let op = match self.previous().kind {
@@ -333,7 +340,7 @@ impl Parser {
TokenKind::Percent => BinaryOp::Mod, TokenKind::Percent => BinaryOp::Mod,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.unary(); let right = self.unary()?;
expr = Expr::Binary { expr = Expr::Binary {
left: Box::new(expr), left: Box::new(expr),
op, op,
@@ -341,54 +348,54 @@ impl Parser {
}; };
} }
expr Ok(expr)
} }
fn unary(&mut self) -> Expr { fn unary(&mut self) -> Result<Expr, RuntimeError> {
if self.match_kind(&[TokenKind::Bang, TokenKind::Minus]) { if self.match_kind(&[TokenKind::Bang, TokenKind::Minus]) {
let op = match self.previous().kind { let op = match self.previous().kind {
TokenKind::Bang => UnaryOp::Not, TokenKind::Bang => UnaryOp::Not,
TokenKind::Minus => UnaryOp::Negate, TokenKind::Minus => UnaryOp::Negate,
_ => unreachable!(), _ => unreachable!(),
}; };
let right = self.unary(); let right = self.unary()?;
return Expr::Unary { return Ok(Expr::Unary {
op, op,
right: Box::new(right), right: Box::new(right),
}; });
} }
self.call() self.call()
} }
fn call(&mut self) -> Expr { fn call(&mut self) -> Result<Expr, RuntimeError> {
let mut expr = self.primary(); let mut expr = self.primary()?;
loop { loop {
if self.match_kind(&[TokenKind::LeftParen]) { if self.match_kind(&[TokenKind::LeftParen]) {
let mut arguments = Vec::new(); let mut arguments = Vec::new();
if !self.check(&TokenKind::RightParen) { if !self.check(&TokenKind::RightParen) {
loop { loop {
arguments.push(self.expression()); arguments.push(self.expression()?);
if !self.match_kind(&[TokenKind::Comma]) { if !self.match_kind(&[TokenKind::Comma]) {
break; break;
} }
} }
} }
self.consume(TokenKind::RightParen, "Expected ')' after arguments.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after arguments.")?;
expr = Expr::Call { expr = Expr::Call {
callee: Box::new(expr), callee: Box::new(expr),
arguments, arguments,
}; };
} else if self.match_kind(&[TokenKind::Dot]) { } else if self.match_kind(&[TokenKind::Dot]) {
let name = self.consume_ident("Expected property name after '.'.").unwrap(); let name = self.consume_ident("Expected property name after '.'.")?;
expr = Expr::Get { expr = Expr::Get {
object: Box::new(expr), object: Box::new(expr),
name, name,
}; };
} else if self.match_kind(&[TokenKind::LeftBracket]) { } else if self.match_kind(&[TokenKind::LeftBracket]) {
let index = self.expression(); let index = self.expression()?;
self.consume(TokenKind::RightBracket, "Expected ']' after index.").unwrap(); self.consume(TokenKind::RightBracket, "Expected ']' after index.")?;
expr = Expr::IndexGet { expr = Expr::IndexGet {
array: Box::new(expr), array: Box::new(expr),
index: Box::new(index), index: Box::new(index),
@@ -398,39 +405,39 @@ impl Parser {
} }
} }
expr Ok(expr)
} }
fn primary(&mut self) -> Expr { fn primary(&mut self) -> Result<Expr, RuntimeError> {
// 布尔值 // 布尔值
if self.match_kind(&[TokenKind::True]) { if self.match_kind(&[TokenKind::True]) {
return Expr::Literal(Literal::Bool(true)); return Ok(Expr::Literal(Literal::Bool(true)));
} }
if self.match_kind(&[TokenKind::False]) { if self.match_kind(&[TokenKind::False]) {
return Expr::Literal(Literal::Bool(false)); return Ok(Expr::Literal(Literal::Bool(false)));
} }
if self.match_kind(&[TokenKind::Nil]) { if self.match_kind(&[TokenKind::Nil]) {
return Expr::Literal(Literal::Nil); return Ok(Expr::Literal(Literal::Nil));
} }
// 数字 // 数字
if let TokenKind::Number(n) = self.peek().kind { if let TokenKind::Number(n) = self.peek().kind {
self.advance(); self.advance();
return Expr::Literal(Literal::Number(n)); return Ok(Expr::Literal(Literal::Number(n)));
} }
// 字符串 // 字符串
if let TokenKind::String(s) = &self.peek().kind { if let TokenKind::String(s) = &self.peek().kind {
let s = s.clone(); let s = s.clone();
self.advance(); self.advance();
return Expr::Literal(Literal::String(s)); return Ok(Expr::Literal(Literal::String(s)));
} }
// 标识符(变量) // 标识符(变量)
if let TokenKind::Identifier(name) = &self.peek().kind { if let TokenKind::Identifier(name) = &self.peek().kind {
let name = name.clone(); let name = name.clone();
self.advance(); self.advance();
return Expr::Variable(name); return Ok(Expr::Variable(name));
} }
// 匿名函数(闭包): fn(params) { body } // 匿名函数(闭包): fn(params) { body }
@@ -440,9 +447,9 @@ impl Parser {
// 括号表达式 // 括号表达式
if self.match_kind(&[TokenKind::LeftParen]) { if self.match_kind(&[TokenKind::LeftParen]) {
let expr = self.expression(); let expr = self.expression()?;
self.consume(TokenKind::RightParen, "Expected ')' after expression.").unwrap(); self.consume(TokenKind::RightParen, "Expected ')' after expression.")?;
return expr; return Ok(expr);
} }
if self.match_kind(&[TokenKind::LeftBrace]) { if self.match_kind(&[TokenKind::LeftBrace]) {
@@ -453,7 +460,7 @@ impl Parser {
return self.array_literal(); return self.array_literal();
} }
panic!("Expected expression at line {}", self.peek().line); Err(RuntimeError::parse("Expected expression.", self.peek().clone()))
} }
fn match_kind(&mut self, kinds: &[TokenKind]) -> bool { fn match_kind(&mut self, kinds: &[TokenKind]) -> bool {
@@ -471,10 +478,7 @@ impl Parser {
self.advance(); self.advance();
Ok(()) Ok(())
} else { } else {
Err(RuntimeError::ParseError { Err(RuntimeError::parse(msg, self.peek().clone()))
message: msg.to_string(),
token: self.peek().clone(),
})
} }
} }
@@ -485,10 +489,7 @@ impl Parser {
self.advance(); self.advance();
Ok(name) Ok(name)
} }
_ => Err(RuntimeError::ParseError { _ => Err(RuntimeError::parse(msg, self.peek().clone())),
message: msg.to_string(),
token: self.peek().clone(),
}),
} }
} }
@@ -519,34 +520,56 @@ impl Parser {
&self.tokens[self.current - 1] &self.tokens[self.current - 1]
} }
fn object_literal(&mut self) -> Expr { fn object_literal(&mut self) -> Result<Expr, RuntimeError> {
let mut properties = Vec::new(); let mut properties = Vec::new();
if !self.check(&TokenKind::RightBrace) { if !self.check(&TokenKind::RightBrace) {
loop { loop {
let name = self.consume_ident("Expected property name in object literal").unwrap(); let name = self.consume_ident("Expected property name in object literal")?;
self.consume(TokenKind::Colon, "Expected ':' after property name in object literal").unwrap(); self.consume(TokenKind::Colon, "Expected ':' after property name in object literal")?;
let value = self.expression(); let value = self.expression()?;
properties.push((name, value)); properties.push((name, value));
if !self.match_kind(&[TokenKind::Comma]) { if !self.match_kind(&[TokenKind::Comma]) {
break; break;
} }
} }
} }
self.consume(TokenKind::RightBrace, "Expected '}' after object literal").unwrap(); self.consume(TokenKind::RightBrace, "Expected '}' after object literal")?;
Expr::ObjectLiteral { properties } Ok(Expr::ObjectLiteral { properties })
} }
fn array_literal(&mut self) -> Expr { fn array_literal(&mut self) -> Result<Expr, RuntimeError> {
let mut elements = Vec::new(); let mut elements = Vec::new();
if !self.check(&TokenKind::RightBracket) { if !self.check(&TokenKind::RightBracket) {
loop { loop {
elements.push(self.expression()); elements.push(self.expression()?);
if !self.match_kind(&[TokenKind::Comma]) { if !self.match_kind(&[TokenKind::Comma]) {
break; break;
} }
} }
} }
self.consume(TokenKind::RightBracket, "Expected ']' after array literal").unwrap(); self.consume(TokenKind::RightBracket, "Expected ']' after array literal")?;
Expr::ArrayLiteral { elements } Ok(Expr::ArrayLiteral { elements })
}
fn synchronize(&mut self) {
while !self.is_at_end() {
if self.current > 0 && matches!(self.previous().kind, TokenKind::Semicolon) {
return;
}
match self.peek().kind {
TokenKind::Let
| TokenKind::Fn
| TokenKind::If
| TokenKind::While
| TokenKind::For
| TokenKind::Return
| TokenKind::Break
| TokenKind::Continue => return,
_ => {
self.advance();
}
}
}
} }
} }