diff --git a/forge_test.go b/forge_test.go index d45b9ba..0d55720 100644 --- a/forge_test.go +++ b/forge_test.go @@ -14,6 +14,7 @@ global = "global value"; # Primary stuff primary { string = "primary string value"; + string_with_quote = "some \"quoted\" str\\ing"; integer = 500; float = 80.80; negative = -50; @@ -54,6 +55,7 @@ func assertDirectives(values map[string]interface{}, t *testing.T) { // Primary primary := values["primary"].(map[string]interface{}) assertEqual(primary["string"], "primary string value", t) + assertEqual(primary["string_with_quote"], "some \"quoted\" str\\ing", t) assertEqual(primary["integer"], int64(500), t) assertEqual(primary["float"], float64(80.80), t) assertEqual(primary["negative"], int64(-50), t) diff --git a/scanner.go b/scanner.go index eb7c0b9..24663f8 100644 --- a/scanner.go +++ b/scanner.go @@ -14,6 +14,10 @@ func isLetter(ch rune) bool { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') } +func isEscapeCharacter(ch rune) bool { + return ch == '\\' || ch == '"' +} + func isDigit(ch rune) bool { return ('0' <= ch && ch <= '9') } @@ -123,10 +127,26 @@ func (scanner *Scanner) parseNumber(negative bool) { func (scanner *Scanner) parseString() { scanner.curTok.ID = token.STRING scanner.curTok.Literal = string(scanner.curCh) + // Whether or not we are trying to escape a character + escape := false for { scanner.readRune() - if scanner.curCh == '"' { - break + if escape == false { + // We haven't seen a backslash yet + if scanner.curCh == '\\' { + // A new backslash + escape = true + continue + } else if scanner.curCh == '"' { + // An unescaped quote, time to bail out + break + } + } else if isEscapeCharacter(scanner.curCh) { + // A valid escape character, continue as normal + escape = false + } else { + // We had a backslash, but an invalid escape character + // TODO: "Unsupported escape character found" } scanner.curTok.Literal += string(scanner.curCh) } diff --git a/test.cfg b/test.cfg index 6ef259a..4d0b634 100644 --- a/test.cfg +++ b/test.cfg @@ -3,6 +3,7 @@ global = "global value"; # Primary stuff primary { string = "primary string value"; + string_with_quote = "some \"quoted\" str\\ing"; integer = 500; float = 80.80; negative = -50;