Skip to content

Commit 6432feb

Browse files
committed
feature: support raw string with char `
1 parent cb1f345 commit 6432feb

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

parser/lexer/lexer.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,16 @@ func (l *lexer) scanString(quote rune) (n int) {
219219
}
220220
return
221221
}
222+
223+
func (l *lexer) scanRawString(quote rune) (n int) {
224+
ch := l.next() // read character after quote
225+
for ch != quote {
226+
if ch == eof {
227+
l.error("literal not terminated")
228+
return
229+
}
230+
ch = l.next()
231+
n++
232+
}
233+
return
234+
}

parser/lexer/state.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package lexer
22

33
import (
4+
"strconv"
45
"strings"
56
)
67

@@ -21,6 +22,14 @@ func root(l *lexer) stateFn {
2122
l.error("%v", err)
2223
}
2324
l.emitValue(String, str)
25+
case r == '`': // raw string case
26+
l.scanRawString(r)
27+
n := len(l.word())
28+
str, err := unescape(strconv.Quote(l.word()[1 : n-1]))
29+
if err != nil {
30+
l.error("%v", err)
31+
}
32+
l.emitValue(String, str)
2433
case '0' <= r && r <= '9':
2534
l.backup()
2635
return number

parser/parser_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,24 @@ func TestParse(t *testing.T) {
444444
Left: &IdentifierNode{Value: "foo"},
445445
Right: &CallNode{Callee: &IdentifierNode{Value: "bar"}}},
446446
},
447+
{
448+
"`" + `foo\n\rbar\\` + "`",
449+
&StringNode{Value: `foo\n\rbar\\`},
450+
},
451+
{
452+
"`" + `foo\
453+
\n` + "`",
454+
&StringNode{Value: "foo\\\n\\n"},
455+
},
456+
{
457+
"`foo\\n\\rbar\\\\`", // because quoted by ", must add '\' to '\'
458+
&StringNode{Value: `foo\n\rbar\\`},
459+
},
460+
{
461+
"\"" + `foo\nbar\\` + "\"",
462+
&StringNode{Value: `foo
463+
bar\`},
464+
},
447465
}
448466
for _, test := range parseTests {
449467
actual, err := parser.Parse(test.input)
@@ -538,6 +556,15 @@ func TestParse_error(t *testing.T) {
538556
}
539557
}
540558

559+
func TestParseRawString_error(t *testing.T) {
560+
_, err := parser.Parse("`foo")
561+
if err == nil {
562+
t.Errorf("expect to get error")
563+
} else {
564+
t.Logf("got err: %+v", err)
565+
}
566+
}
567+
541568
func TestParse_optional_chaining(t *testing.T) {
542569
parseTests := []struct {
543570
input string

0 commit comments

Comments
 (0)