mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 20:34:44 +00:00
Update: add closure for error and, line and col
The length of the string is calculated as the rightmost newline or 0, and that is the message of the error
This commit is contained in:
parent
beb10ef166
commit
f1dd25e508
1 changed files with 71 additions and 62 deletions
|
@ -690,92 +690,101 @@ impl Lexer /*<'a>*/ {
|
||||||
|
|
||||||
fn lex_multi_line_str(&mut self) -> LexResult<Token> {
|
fn lex_multi_line_str(&mut self) -> LexResult<Token> {
|
||||||
let mut s = "\"\"\"".to_string();
|
let mut s = "\"\"\"".to_string();
|
||||||
|
let unclosed_error = |t: Token| -> LexResult<Token> {
|
||||||
|
Err(LexError::syntax_error(
|
||||||
|
0,
|
||||||
|
t.loc(),
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => "文字列が\"\"\"によって閉じられていません",
|
||||||
|
"simplified_chinese" => "字符串没有被\"\"\"关闭",
|
||||||
|
"traditional_chinese" => "字符串没有被\"\"\"关闭",
|
||||||
|
"english" => "the string is not closed by \"\"\"",
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
while let Some(c) = self.peek_cur_ch() {
|
while let Some(c) = self.peek_cur_ch() {
|
||||||
match c {
|
match c {
|
||||||
'"' => {
|
'"' => {
|
||||||
s.push(self.consume().unwrap());
|
s.push(self.consume().unwrap());
|
||||||
let next_c = self.peek_cur_ch();
|
let next_c = self.peek_cur_ch();
|
||||||
let aft_next_c = self.peek_next_ch();
|
let aft_next_c = self.peek_next_ch();
|
||||||
if next_c.is_none() || aft_next_c.is_none() {
|
if next_c.is_none() {
|
||||||
let token = self.emit_token(Illegal, &s);
|
let col_end = s.rfind('\n').unwrap_or_default();
|
||||||
return Err(LexError::syntax_error(
|
let error_s = &s[col_end..s.len()];
|
||||||
0,
|
let token = self.emit_token(Illegal, error_s);
|
||||||
token.loc(),
|
return unclosed_error(token);
|
||||||
switch_lang!(
|
}
|
||||||
"japanese" => "文字列が\"\"\"によって閉じられていません",
|
if aft_next_c.is_none() {
|
||||||
"simplified_chinese" => "字符串没有被\"\"\"关闭",
|
s.push(self.consume().unwrap());
|
||||||
"traditional_chinese" => "字符串没有被\"\"\"关闭",
|
let col_end = s.rfind('\n').unwrap_or_default();
|
||||||
"english" => "the string is not closed by \"\"\"",
|
let error_s = &s[col_end..s.len()];
|
||||||
),
|
let token = self.emit_token(Illegal, error_s);
|
||||||
None,
|
return unclosed_error(token);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let next_c = self.consume().unwrap();
|
let next_c = self.consume().unwrap();
|
||||||
let aft_next_c = self.consume().unwrap();
|
let aft_next_c = self.consume().unwrap();
|
||||||
if next_c == '"' && aft_next_c == '"' {
|
if next_c == '"' && aft_next_c == '"' {
|
||||||
|
s.push_str("\"\"");
|
||||||
let token = self.emit_token(StrLit, &s);
|
let token = self.emit_token(StrLit, &s);
|
||||||
return Ok(token);
|
return Ok(token);
|
||||||
}
|
}
|
||||||
|
s.push(self.consume().unwrap());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let c = self.consume().unwrap();
|
let c = self.consume().unwrap();
|
||||||
if c == '\\' {
|
match c {
|
||||||
let next_c = self.consume().unwrap();
|
'\\' => {
|
||||||
match next_c {
|
let next_c = self.consume().unwrap();
|
||||||
'0' => s.push('\0'),
|
match next_c {
|
||||||
'r' => s.push('\r'),
|
'0' => s.push('\0'),
|
||||||
'\'' => {
|
'r' => s.push('\r'),
|
||||||
s.push('\'');
|
'\'' => s.push('\''),
|
||||||
if self.peek_next_ch().is_some()
|
'"' => s.push('"'),
|
||||||
&& self.peek_next_ch().unwrap() == '\n'
|
't' => s.push_str(" "), // tab is invalid, so changed into 4 whitespace
|
||||||
{
|
'\\' => s.push('\\'),
|
||||||
continue; // Escaping a line break if only '\' comes at the end
|
'n' => s.push('\n'),
|
||||||
|
'\n' => {
|
||||||
|
self.lineno_token_starts += 1;
|
||||||
|
self.col_token_starts = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let token = self.emit_token(Illegal, &format!("\\{next_c}"));
|
||||||
|
return Err(LexError::syntax_error(
|
||||||
|
0,
|
||||||
|
token.loc(),
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => format!("不正なエスケープシーケンスです: \\{}", next_c),
|
||||||
|
"simplified_chinese" => format!("不合法的转义序列: \\{}", next_c),
|
||||||
|
"traditional_chinese" => format!("不合法的轉義序列: \\{}", next_c),
|
||||||
|
"english" => format!("illegal escape sequence: \\{}", next_c),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'"' => s.push('"'),
|
|
||||||
't' => s.push_str(" "), // tab is invalid, so changed into 4 whitespace
|
|
||||||
'\\' => s.push('\\'),
|
|
||||||
'n' => s.push('\n'),
|
|
||||||
'\n' => {
|
|
||||||
self.lineno_token_starts += 1;
|
|
||||||
self.col_token_starts = 0;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let token = self.emit_token(Illegal, &format!("\\{next_c}"));
|
|
||||||
return Err(LexError::syntax_error(
|
|
||||||
0,
|
|
||||||
token.loc(),
|
|
||||||
switch_lang!(
|
|
||||||
"japanese" => format!("不正なエスケープシーケンスです: \\{}", next_c),
|
|
||||||
"simplified_chinese" => format!("不合法的转义序列: \\{}", next_c),
|
|
||||||
"traditional_chinese" => format!("不合法的轉義序列: \\{}", next_c),
|
|
||||||
"english" => format!("illegal escape sequence: \\{}", next_c),
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
'\n' => {
|
||||||
s.push(c);
|
self.lineno_token_starts += 1;
|
||||||
if Self::is_bidi(c) {
|
self.col_token_starts = 0;
|
||||||
return Err(self._invalid_unicode_character(&s));
|
s.push('\n')
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
s.push(c);
|
||||||
|
if Self::is_bidi(c) {
|
||||||
|
return Err(self._invalid_unicode_character(&s));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let token = self.emit_token(Illegal, &s);
|
let col_end = s.rfind('\n').unwrap_or_default();
|
||||||
Err(LexError::syntax_error(
|
let error_s = &s[col_end..s.len()];
|
||||||
0,
|
let token = self.emit_token(Illegal, error_s);
|
||||||
token.loc(),
|
unclosed_error(token)
|
||||||
switch_lang!(
|
|
||||||
"japanese" => "文字列が\"\"\"によって閉じられていません",
|
|
||||||
"simplified_chinese" => "字符串没有被\"\"\"关闭",
|
|
||||||
"traditional_chinese" => "字符串没有被\"\"\"关闭",
|
|
||||||
"english" => "the string is not closed by \"\"\"",
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for single strings and multi strings
|
// for single strings and multi strings
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue