diff options
-rw-r--r-- | crates/rebel-parse/src/grammar/tokenize.rs | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/crates/rebel-parse/src/grammar/tokenize.rs b/crates/rebel-parse/src/grammar/tokenize.rs index 811da0d..8ca9d59 100644 --- a/crates/rebel-parse/src/grammar/tokenize.rs +++ b/crates/rebel-parse/src/grammar/tokenize.rs @@ -45,16 +45,17 @@ peg::parser! { kind: StringKind::RawString, } } - / "```" newline() chars:$((!"```" [_])+) "```" { + / "```" newline() pieces:script_string_piece()* "```" { String { - pieces: vec![StringPiece::Chars(chars)], + pieces, kind: StringKind::ScriptString, } } rule string_piece() -> StringPiece<'input> - = chars:$([^'"' | '\\']+) { StringPiece::Chars(chars) } + = chars:$((!"{{" [^'"' | '\\'])+) { StringPiece::Chars(chars) } / "\\" escape:string_escape() { StringPiece::Escape(escape) } + / string_interp() rule string_escape() -> char = "n" { '\n' } @@ -70,6 +71,18 @@ peg::parser! { u32::from_str_radix(digits, 16).unwrap().try_into().or(Err("Invalid unicode escape")) } + rule script_string_piece() -> StringPiece<'input> + = chars:$((!"{{" !"```" [_])+) { StringPiece::Chars(chars) } + / string_interp() + + rule string_interp() -> StringPiece<'input> + = "{{" tokens:subtoken()* "}}" { + StringPiece::Interp(TokenStream(tokens)) + } + + rule subtoken() -> Token<'input> + = !"}}" token:token() { token } + rule hex_digit() = ['0'..='9' | 'a'..='f' | 'A'..='F'] |