From 25bfe139e847c87934b1955c053dcbd2aea6b84b Mon Sep 17 00:00:00 2001 From: James Eversole Date: Tue, 15 Apr 2025 10:52:53 -0500 Subject: [PATCH] String escaping using backslash --- src/Lexer.hs | 23 +++++++++++++++++------ src/Research.hs | 1 - test/Spec.hs | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/Lexer.hs b/src/Lexer.hs index 14e1ee4..173f10e 100644 --- a/src/Lexer.hs +++ b/src/Lexer.hs @@ -41,7 +41,6 @@ tricuLexer = do , try stringLiteral , assign , colon - , backslash , openParen , closeParen , openBracket @@ -94,9 +93,6 @@ assign = char '=' $> LAssign colon :: Lexer LToken colon = char ':' $> LColon -backslash :: Lexer LToken -backslash = char '\\' $> LBackslash - openParen :: Lexer LToken openParen = char '(' $> LOpenParen @@ -126,7 +122,22 @@ integerLiteral = do stringLiteral :: Lexer LToken stringLiteral = do char '"' - content <- many (noneOf ['"']) - char '"' --" + content <- manyTill Lexer.charLiteral (char '"') return (LStringLiteral content) +charLiteral :: Lexer Char +charLiteral = escapedChar <|> normalChar + where + normalChar = noneOf ['"', '\\'] + escapedChar = do + void $ char '\\' + c <- oneOf ['n', 't', 'r', 'f', 'b', '\\', '"', '\''] + return $ case c of + 'n' -> '\n' + 't' -> '\t' + 'r' -> '\r' + 'f' -> '\f' + 'b' -> '\b' + '\\' -> '\\' + '"' -> '"' + '\'' -> '\'' diff --git a/src/Research.hs b/src/Research.hs index 0e79eb8..d076692 100644 --- a/src/Research.hs +++ b/src/Research.hs @@ -38,7 +38,6 @@ data LToken | LAssign | LColon | LDot - | LBackslash | LOpenParen | LCloseParen | LOpenBracket diff --git a/test/Spec.hs b/test/Spec.hs index ea4d54d..4254501 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -51,7 +51,22 @@ lexer = testGroup "Lexer Tests" , testCase "Lex escaped characters in strings" $ do let input = "\"hello\\nworld\"" - expect = Right [LStringLiteral "hello\\nworld"] + expect = Right [LStringLiteral "hello\nworld"] + runParser tricuLexer "" input @?= expect + + , testCase "Lex multiple escaped characters in strings" $ do + let input = "\"tab:\\t newline:\\n quote:\\\" backslash:\\\\\"" + expect = Right [LStringLiteral "tab:\t newline:\n quote:\" backslash:\\"] + runParser tricuLexer "" input @?= expect + + , testCase "Lex escaped characters in string literals" $ do + let input = "x = \"line1\\nline2\\tindented\"" + expect = Right [LIdentifier "x", LAssign, LStringLiteral "line1\nline2\tindented"] + runParser tricuLexer "" input @?= expect + + , testCase "Lex empty string with escape sequence" $ do + let input = "\"\\\"\"" + expect = Right [LStringLiteral "\""] runParser tricuLexer "" input @?= expect , testCase "Lex mixed literals" $ do