diff --git a/crates/erg_parser/error.rs b/crates/erg_parser/error.rs index ea9211442..ad990ffde 100644 --- a/crates/erg_parser/error.rs +++ b/crates/erg_parser/error.rs @@ -175,6 +175,23 @@ impl LexError { )) } + pub fn parenthesize_error(errno: usize, loc: Location, got: &str) -> Self { + let msg = switch_lang!( + "japanese" => "不適切な閉じ括弧があります", + "simplified_chinese" => "存在不匹配的右括号", + "traditional_chinese" => "存在不匹配的右括號", + "english" => "unmatched closing parenthesis found", + ); + let got = StyledStr::new(got, Some(ERR), Some(ATTR)); + let hint = switch_lang!( + "japanese" => format!("この{}は対応する開き括弧がないため、削除するか開き括弧を追加してください", got), + "simplified_chinese" => format!("{}缺少对应的左括号,请删除或添加左括号", got), + "traditional_chinese" => format!("{}缺少對應的左括號,請刪除或添加左括號", got), + "english" => format!("{} has no matching opening parenthesis - either remove it or add an opening parenthesis", got), + ); + Self::syntax_error(errno, loc, msg, Some(hint)) + } + pub fn expect_next_line_error(errno: usize, loc: Location, caused: &str) -> Self { Self::new(ErrorCore::new( vec![SubMessage::ambiguous_new( diff --git a/crates/erg_parser/parse.rs b/crates/erg_parser/parse.rs index 6236de1d7..cde39f981 100644 --- a/crates/erg_parser/parse.rs +++ b/crates/erg_parser/parse.rs @@ -2050,6 +2050,13 @@ impl Parser { debug_exit_info!(self); return Err(()); } + Some(t) if t.is(RParen) => { + let err = ParseError::parenthesize_error(line!() as usize, t.loc(), ")"); + self.errs.push(err); + self.next_expr(); + debug_exit_info!(self); + return Err(()); + } _ => { if stack.len() <= 1 { break; diff --git a/crates/erg_parser/tests/parse_test.rs b/crates/erg_parser/tests/parse_test.rs index 8b780a362..6f56729f1 100644 --- a/crates/erg_parser/tests/parse_test.rs +++ b/crates/erg_parser/tests/parse_test.rs @@ -84,6 +84,11 @@ fn parse_invalid_class_definition() -> Result<(), ()> { expect_failure("tests/invalid_class_definition.er", 0, 7) } +#[test] +fn parse_missing_paren() -> Result<(), ()> { + expect_failure("tests/unmatched_paren.er", 0, 1) +} + #[test] fn parse_warns() -> Result<(), ()> { expect_success("tests/warns.er", 1) diff --git a/crates/erg_parser/tests/unmatched_paren.er b/crates/erg_parser/tests/unmatched_paren.er new file mode 100644 index 000000000..fdcb10430 --- /dev/null +++ b/crates/erg_parser/tests/unmatched_paren.er @@ -0,0 +1 @@ +func a, b) = a + b \ No newline at end of file