Browse Source

Add support for single quotes

this fixes #18
pull/21/head
Brett Langdon 11 years ago
parent
commit
43f1f42de4
5 changed files with 25 additions and 13 deletions
  1. +1
    -0
      README.md
  2. +3
    -3
      forge.go
  3. +4
    -0
      forge_test.go
  4. +15
    -10
      scanner.go
  5. +2
    -0
      test.cfg

+ 1
- 0
README.md View File

@ -26,6 +26,7 @@ global = "global value";
# Primary section
primary {
string = "primary string value";
single = 'single quotes are allowed too';
integer = 500;
float = 80.80;
boolean = true;


+ 3
- 3
forge.go View File

@ -32,7 +32,7 @@
// NULL: 'null'
// INTEGER: ('-')? NUMBERS
// FLOAT: ('-')? NUMBERS '.' NUMBERS
// STRING: '"' .* '"'
// STRING: ['"] .* ['"]
// REFERENCE: (IDENTIFIER)? ('.' IDENTIFIER)+
// VALUE: BOOL | NULL | INTEGER | FLOAT | STRING | REFERENCE
//
@ -46,8 +46,8 @@
//
// Values
// * String:
// Any value enclosed in double quotes (single quotes not allowed) (e.g. "string").
// Double quotes and backslashes can be escaped with backslashes (e.g. "\"quoted\"" and "\\<--backslash")
// Any value enclosed in double or single quotes (e.g. "string" or 'string').
// Double quotes, single quotes, and backslashes can be escaped with backslashes (e.g. "\"quoted\"", '\'quoted\'', and "\\<--backslash")
// * Integer:
// Any number without decimal places (e.g. 500)
// * Float:


+ 4
- 0
forge_test.go View File

@ -15,6 +15,8 @@ global = "global value";
primary {
string = "primary string value";
string_with_quote = "some \"quoted\" str\\ing";
single = 'hello world';
single_with_quote = '\'hello\' "world"';
integer = 500;
float = 80.80;
negative = -50;
@ -56,6 +58,8 @@ func assertDirectives(values map[string]interface{}, t *testing.T) {
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["single"], "hello world", t)
assertEqual(primary["single_with_quote"], "'hello' \"world\"", t)
assertEqual(primary["integer"], int64(500), t)
assertEqual(primary["float"], float64(80.80), t)
assertEqual(primary["negative"], int64(-50), t)


+ 15
- 10
scanner.go View File

@ -14,10 +14,6 @@ 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')
}
@ -124,11 +120,18 @@ func (scanner *Scanner) parseNumber(negative bool) {
}
}
func (scanner *Scanner) parseString() {
func (scanner *Scanner) parseString(delimiter rune) {
scanner.curTok.ID = token.STRING
scanner.curTok.Literal = string(scanner.curCh)
scanner.curTok.Literal = ""
// Whether or not we are trying to escape a character
escape := false
// If the first character is an escape
if scanner.curCh == '\\' {
escape = true
} else {
scanner.curTok.Literal = string(scanner.curCh)
}
for {
scanner.readRune()
if escape == false {
@ -137,16 +140,18 @@ func (scanner *Scanner) parseString() {
// A new backslash
escape = true
continue
} else if scanner.curCh == '"' {
} else if scanner.curCh == delimiter {
// An unescaped quote, time to bail out
break
}
} else if isEscapeCharacter(scanner.curCh) {
// Continue as normal, no escaping necessary
} else if scanner.curCh == '\\' || scanner.curCh == delimiter {
// A valid escape character, continue as normal
escape = false
} else {
// We had a backslash, but an invalid escape character
// TODO: "Unsupported escape character found"
break
}
scanner.curTok.Literal += string(scanner.curCh)
}
@ -204,8 +209,8 @@ func (scanner *Scanner) NextToken() token.Token {
switch ch {
case '=':
scanner.curTok.ID = token.EQUAL
case '"':
scanner.parseString()
case '"', '\'':
scanner.parseString(ch)
case '{':
scanner.curTok.ID = token.LBRACKET
case '}':


+ 2
- 0
test.cfg View File

@ -4,6 +4,8 @@ global = "global value";
primary {
string = "primary string value";
string_with_quote = "some \"quoted\" str\\ing";
single = 'hello world';
single_with_quote = '\'hello\' "world"';
integer = 500;
float = 80.80;
negative = -50;


Loading…
Cancel
Save