Просмотр исходного кода

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 7 лет назад
Родитель
Сommit
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
+})

Загрузка…
Отмена
Сохранить