瀏覽代碼

Allow whitespace while between quotes

What was happening was that spaces were allowed in
all literals to account for quoted strings, but
this meant that two identifiers in a row would get
parsed as a single literal. This commit sets a
flag to allow whitespace in literals when a quote
is encountered and then unsets that flag at the
next quote.
master
Dylan Baker 6 年之前
父節點
當前提交
ef0845237f
共有 2 個文件被更改,包括 41 次插入1 次删除
  1. 9
    1
      src/lexer.js
  2. 32
    0
      test/lexer.js

+ 9
- 1
src/lexer.js 查看文件

6
     let pos = 0
6
     let pos = 0
7
     let line = 1
7
     let line = 1
8
     let tokenStream = new TokenStream()
8
     let tokenStream = new TokenStream()
9
+    let allowWhiteSpaceInLiterals = false
9
 
10
 
10
     while (pos < source.length) {
11
     while (pos < source.length) {
11
       if (source[pos].match(/\(/)) {
12
       if (source[pos].match(/\(/)) {
21
         })
22
         })
22
         pos++
23
         pos++
23
       } else if (source[pos].match(/['"]/)) {
24
       } else if (source[pos].match(/['"]/)) {
25
+        allowWhiteSpaceInLiterals = !allowWhiteSpaceInLiterals
24
         tokenStream.tokens.push({
26
         tokenStream.tokens.push({
25
           type: tokenTypes.QUOTE,
27
           type: tokenTypes.QUOTE,
26
           line: line,
28
           line: line,
40
       } else if (source[pos].match(/\s/)) {
42
       } else if (source[pos].match(/\s/)) {
41
         pos++
43
         pos++
42
       } else {
44
       } else {
43
-        let value = /[^()"':]+/.exec(source.slice(pos))[0]
45
+        let endPattern = /[^()"':\s]+/
46
+
47
+        if (allowWhiteSpaceInLiterals) {
48
+          endPattern = /[^()"':]+/
49
+        }
50
+
51
+        let value = endPattern.exec(source.slice(pos))[0]
44
         tokenStream.tokens.push({
52
         tokenStream.tokens.push({
45
           type: tokenTypes.LITERAL,
53
           type: tokenTypes.LITERAL,
46
           line: line,
54
           line: line,

+ 32
- 0
test/lexer.js 查看文件

40
   t.equal(tokens[2].line, 2)
40
   t.equal(tokens[2].line, 2)
41
   t.equal(tokens[7].line, 3)
41
   t.equal(tokens[7].line, 3)
42
 })
42
 })
43
+
44
+test('multiple identifiers in a row are kept separate', t => {
45
+  t.plan(2)
46
+  const lexer = new Lexer()
47
+  let tokens = lexer.scan(`(test test test)`).tokens
48
+  t.deepEqual(
49
+    tokens.map(token => token.type),
50
+    [
51
+      tt.OPAREN,
52
+      tt.LITERAL,
53
+      tt.LITERAL,
54
+      tt.LITERAL,
55
+      tt.CPAREN,
56
+      tt.EOF,
57
+    ]
58
+  )
59
+  tokens = lexer.scan(`(test "test" test test)`).tokens
60
+  t.deepEqual(
61
+    tokens.map(token => token.type),
62
+    [
63
+      tt.OPAREN,
64
+      tt.LITERAL,
65
+      tt.QUOTE,
66
+      tt.LITERAL,
67
+      tt.QUOTE,
68
+      tt.LITERAL,
69
+      tt.LITERAL,
70
+      tt.CPAREN,
71
+      tt.EOF,
72
+    ]
73
+  )
74
+})

Loading…
取消
儲存