From 884c8e515ffce07952e196ec6fd5dab51342d120 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sun, 21 Nov 2021 01:54:34 -0800 Subject: [PATCH] Fix string literal escape parsing --- schala-lang/src/parsing/peg_parser.rs | 19 +++++++++---------- schala-lang/src/parsing/test.rs | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/schala-lang/src/parsing/peg_parser.rs b/schala-lang/src/parsing/peg_parser.rs index af8ea73..f845ba7 100644 --- a/schala-lang/src/parsing/peg_parser.rs +++ b/schala-lang/src/parsing/peg_parser.rs @@ -423,7 +423,7 @@ peg::parser! { rule pattern_literal() -> Pattern = "true" { Pattern::Literal(PatternLiteral::BoolPattern(true)) } / "false" { Pattern::Literal(PatternLiteral::BoolPattern(false)) } / - s:bare_string_literal() { Pattern::Literal(PatternLiteral::StringPattern(Rc::new(s.to_string()))) } / + s:bare_string_literal() { Pattern::Literal(PatternLiteral::StringPattern(Rc::new(s))) } / sign:("-"?) num:(float_literal() / nat_literal()) { let neg = sign.is_some(); Pattern::Literal(PatternLiteral::NumPattern { neg, num }) @@ -447,19 +447,18 @@ peg::parser! { } rule string_literal() -> ExpressionKind = - prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral{ s: Rc::new(s.to_string()), + prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral{ s: Rc::new(s), prefix: prefix.map(rc_string) } } - rule bare_string_literal() -> &'input str = - "\"" s:$(string_component()*) "\"" { s } + rule bare_string_literal() -> String = + "\"" chars:string_component()* "\"" { chars.into_iter().collect::() } - rule string_component() -> &'input str = - r#"\\"# { "\\" } / - r#"\""# { "\"" } / - r#"\t"# { "\t" } / - r#"\n"# { "\n" } / - ch:$([^ '"' ]) { ch } + rule string_component() -> char = + !(r#"""# / r#"\"#) ch:$([_]) { ch.chars().next().unwrap() } / + r#"\u{"# value:$(['0'..='9' | 'a'..='f' | 'A'..='F']+) "}" { char::from_u32(u32::from_str_radix(value, 16).unwrap()).unwrap() } / + r#"\n"# { '\n' } / r#"\t"# { '\t' } / r#"\""# { '"' } / r#"\\"# { '\\' } / + expected!("Valid escape sequence") rule bool_literal() -> ExpressionKind = "true" { ExpressionKind::BoolLiteral(true) } / "false" { ExpressionKind::BoolLiteral(false) } diff --git a/schala-lang/src/parsing/test.rs b/schala-lang/src/parsing/test.rs index 95fae54..17591fb 100644 --- a/schala-lang/src/parsing/test.rs +++ b/schala-lang/src/parsing/test.rs @@ -189,8 +189,7 @@ fn string_literals() { r#"b"some bytestring""#, expr(StringLiteral { s: rc("some bytestring"), prefix: Some(rc("b")) }) ); - //NOTE I'm not 100% sure this case is correct, but I'll deal with it later - //assert_expr!(r#""Do \n \" escapes work\t""#, expr(StringLiteral(rc("Do \n \" escapes work\t")))); + assert_expr!(r#""Do \n \" escapes work\t""#, expr(strlit("Do \n \" escapes work\t"))); } #[test]