Support back-tick at EOL for literal strings.

This commit is contained in:
Stephen Chung 2021-03-30 13:59:27 +08:00
parent d756b7bac6
commit e36e490a30
3 changed files with 43 additions and 10 deletions

View File

@ -715,13 +715,13 @@ fn parse_map_literal(
return Err(PERR::Reserved(s).into_err(pos));
}
(Token::LexError(err), pos) => return Err(err.into_err(pos)),
(_, pos) if map.is_empty() => {
(Token::EOF, pos) => {
return Err(
PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into())
.into_err(pos),
);
}
(Token::EOF, pos) => {
(_, pos) if map.is_empty() => {
return Err(
PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into())
.into_err(pos),

View File

@ -1294,15 +1294,36 @@ fn get_next_token_inner(
return get_identifier(stream, pos, start_pos, c);
}
// " or ` - string literal
('"', _) | ('`', _) => {
let multi_line = c == '`';
// " - string literal
('"', _) => {
return parse_string_literal(stream, state, pos, c, true, false).map_or_else(
|err| Some((Token::LexError(err.0), err.1)),
|out| Some((Token::StringConstant(out), start_pos)),
);
}
// ` - string literal
('`', _) => {
// Start from the next line if ` at the end of line
match stream.peek_next() {
// `\r - start from next line
Some('\r') => {
eat_next(stream, pos);
// `\r\n
if stream.peek_next().map(|ch| ch == '\n').unwrap_or(false) {
eat_next(stream, pos);
}
}
// `\n - start from next line
Some('\n') => {
eat_next(stream, pos);
}
_ => (),
}
return parse_string_literal(stream, state, pos, c, !multi_line, multi_line)
.map_or_else(
|err| Some((Token::LexError(err.0), err.1)),
|out| Some((Token::StringConstant(out), start_pos)),
);
return parse_string_literal(stream, state, pos, c, false, true).map_or_else(
|err| Some((Token::LexError(err.0), err.1)),
|out| Some((Token::StringConstant(out), start_pos)),
);
}
// ' - character literal

View File

@ -8,6 +8,10 @@ fn test_string() -> Result<(), Box<EvalAltResult>> {
engine.eval::<String>(r#""Test string: \u2764""#)?,
"Test string: ❤"
);
assert_eq!(
engine.eval::<String>("\"Test\rstring: \\u2764\"")?,
"Test\rstring: ❤"
);
assert_eq!(
engine.eval::<String>(" \"Test string: \\u2764\\\n hello, world!\"")?,
"Test string: ❤ hello, world!"
@ -16,6 +20,14 @@ fn test_string() -> Result<(), Box<EvalAltResult>> {
engine.eval::<String>(" `Test string: \\u2764\nhello,\\nworld!`")?,
"Test string: \\u2764\nhello,\\nworld!"
);
assert_eq!(
engine.eval::<String>(" `\nTest string: \\u2764\nhello,\\nworld!`")?,
"Test string: \\u2764\nhello,\\nworld!"
);
assert_eq!(
engine.eval::<String>(" `\r\nTest string: \\u2764\nhello,\\nworld!`")?,
"Test string: \\u2764\nhello,\\nworld!"
);
assert_eq!(
engine.eval::<String>(r#""Test string: \x58""#)?,
"Test string: X"