Skip to content

Commit b62f9e1

Browse files
committed
Allow quotes to be last characters of multi-line string
Problem ------- Strings like `"""""""` are valid in scala, but not in the grammar Solution ------- In `scanner.c` emit multi-line string only when at least 3 closing quotes found and the next lookahead is not a quote
1 parent 99b7b99 commit b62f9e1

File tree

2 files changed

+135
-69
lines changed

2 files changed

+135
-69
lines changed

corpus/literals.txt

Lines changed: 133 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
==========================
1+
================================================================================
22
Simple strings
3-
==========================
3+
================================================================================
44

55
val oneLineString = "I'm just on one line"
66

@@ -10,15 +10,24 @@ val multiLineString = """
1010
${thisEither}
1111
"""
1212

13-
---
13+
val multiLineString2 = """""""
14+
15+
--------------------------------------------------------------------------------
1416

1517
(compilation_unit
16-
(val_definition (identifier) (string))
17-
(val_definition (identifier) (string)))
18+
(val_definition
19+
(identifier)
20+
(string))
21+
(val_definition
22+
(identifier)
23+
(string))
24+
(val_definition
25+
(identifier)
26+
(string)))
1827

19-
==========================
28+
================================================================================
2029
Interpolated strings
21-
==========================
30+
================================================================================
2231

2332
val string1 = s"a $b ${c}"
2433

@@ -29,35 +38,46 @@ val string3 = raw"Not a new line \n${ha}"
2938
val string4 = s"""
3039
works even in multiline strings, ${name}
3140
"""
32-
---
41+
--------------------------------------------------------------------------------
3342

3443
(compilation_unit
3544
(val_definition
3645
(identifier)
3746
(interpolated_string_expression
38-
(identifier) (interpolated_string
39-
(interpolation (identifier))
40-
(interpolation (block (identifier))))))
47+
(identifier)
48+
(interpolated_string
49+
(interpolation
50+
(identifier))
51+
(interpolation
52+
(block
53+
(identifier))))))
4154
(val_definition
4255
(identifier)
4356
(interpolated_string_expression
44-
(identifier) (interpolated_string
45-
(interpolation (identifier)))))
57+
(identifier)
58+
(interpolated_string
59+
(interpolation
60+
(identifier)))))
4661
(val_definition
4762
(identifier)
4863
(interpolated_string_expression
49-
(identifier) (interpolated_string
50-
(interpolation (block (identifier))))))
64+
(identifier)
65+
(interpolated_string
66+
(interpolation
67+
(block
68+
(identifier))))))
5169
(val_definition
5270
(identifier)
5371
(interpolated_string_expression
54-
(identifier) (interpolated_string
55-
(interpolation (block (identifier)))))))
56-
72+
(identifier)
73+
(interpolated_string
74+
(interpolation
75+
(block
76+
(identifier)))))))
5777

58-
==========================
78+
================================================================================
5979
Integer literals
60-
==========================
80+
================================================================================
6181

6282
val i1 = 0
6383
val i2 = 1234
@@ -70,65 +90,94 @@ val l4 = 0XA03L
7090
val l5 = 150_000_000
7191
val l6 = 0xFF_FF_FF
7292

73-
---
93+
--------------------------------------------------------------------------------
7494

7595
(compilation_unit
76-
(val_definition (identifier) (integer_literal))
77-
(val_definition (identifier) (integer_literal))
78-
(val_definition (identifier) (integer_literal))
79-
(val_definition (identifier) (integer_literal))
80-
(val_definition (identifier) (integer_literal))
81-
(val_definition (identifier) (integer_literal))
82-
(val_definition (identifier) (integer_literal))
83-
(val_definition (identifier) (integer_literal))
84-
(val_definition (identifier) (integer_literal))
85-
(val_definition (identifier) (integer_literal))
86-
)
96+
(val_definition
97+
(identifier)
98+
(integer_literal))
99+
(val_definition
100+
(identifier)
101+
(integer_literal))
102+
(val_definition
103+
(identifier)
104+
(integer_literal))
105+
(val_definition
106+
(identifier)
107+
(integer_literal))
108+
(val_definition
109+
(identifier)
110+
(integer_literal))
111+
(val_definition
112+
(identifier)
113+
(integer_literal))
114+
(val_definition
115+
(identifier)
116+
(integer_literal))
117+
(val_definition
118+
(identifier)
119+
(integer_literal))
120+
(val_definition
121+
(identifier)
122+
(integer_literal))
123+
(val_definition
124+
(identifier)
125+
(integer_literal)))
87126

88-
==========================
127+
================================================================================
89128
Floating point literals
90-
==========================
129+
================================================================================
91130

92131
val f1 = 3.14
93132
val f2 = -3f
94133
val f2 = 3E-1
95134
val d1 = .314D
96135

97-
---
136+
--------------------------------------------------------------------------------
98137

99138
(compilation_unit
100-
(val_definition (identifier) (floating_point_literal))
101-
(val_definition (identifier) (floating_point_literal))
102-
(val_definition (identifier) (floating_point_literal))
103-
(val_definition (identifier) (floating_point_literal))
104-
)
139+
(val_definition
140+
(identifier)
141+
(floating_point_literal))
142+
(val_definition
143+
(identifier)
144+
(floating_point_literal))
145+
(val_definition
146+
(identifier)
147+
(floating_point_literal))
148+
(val_definition
149+
(identifier)
150+
(floating_point_literal)))
105151

106-
==========================
152+
================================================================================
107153
Boolean literals
108-
==========================
154+
================================================================================
109155

110156
val myBool = true
111157

112158
def foo(a: Boolean = false) = a && true
113159

114-
---
160+
--------------------------------------------------------------------------------
115161

116162
(compilation_unit
117-
(val_definition (identifier) (boolean_literal))
163+
(val_definition
164+
(identifier)
165+
(boolean_literal))
118166
(function_definition
119167
(identifier)
120-
(parameters (parameter
121-
(identifier)
122-
(type_identifier)
123-
(boolean_literal)))
168+
(parameters
169+
(parameter
170+
(identifier)
171+
(type_identifier)
172+
(boolean_literal)))
124173
(infix_expression
125174
(identifier)
126175
(operator_identifier)
127176
(boolean_literal))))
128177

129-
==========================
178+
================================================================================
130179
Character literals
131-
==========================
180+
================================================================================
132181

133182
val myChar = 'c'
134183

@@ -138,44 +187,61 @@ val anotherChar = '\n'
138187

139188
def foo(a: Char = 'c') = a + 'd'
140189

141-
---
190+
--------------------------------------------------------------------------------
142191

143192
(compilation_unit
144-
(val_definition (identifier) (character_literal))
145-
(val_definition (identifier) (character_literal))
146-
(val_definition (identifier) (character_literal))
193+
(val_definition
194+
(identifier)
195+
(character_literal))
196+
(val_definition
197+
(identifier)
198+
(character_literal))
199+
(val_definition
200+
(identifier)
201+
(character_literal))
147202
(function_definition
148203
(identifier)
149-
(parameters (parameter
150-
(identifier)
151-
(type_identifier)
152-
(character_literal)))
204+
(parameters
205+
(parameter
206+
(identifier)
207+
(type_identifier)
208+
(character_literal)))
153209
(infix_expression
154210
(identifier)
155211
(operator_identifier)
156212
(character_literal))))
157213

158-
==========================
214+
================================================================================
159215
Null
160-
==========================
216+
================================================================================
161217

162218
lazy val nullObject: String = null
163219

164-
---
165-
(compilation_unit (val_definition (modifiers) (identifier) (type_identifier) (null_literal)))
220+
--------------------------------------------------------------------------------
166221

167-
==========================
222+
(compilation_unit
223+
(val_definition
224+
(modifiers)
225+
(identifier)
226+
(type_identifier)
227+
(null_literal)))
228+
229+
================================================================================
168230
Tuple literals
169-
==========================
231+
================================================================================
170232

171233
val x = (
172234
1,
173235
2,
174236
3,
175237
)
176238

177-
---
239+
--------------------------------------------------------------------------------
178240

179241
(compilation_unit
180-
(val_definition (identifier)
181-
(tuple_expression (integer_literal) (integer_literal) (integer_literal))))
242+
(val_definition
243+
(identifier)
244+
(tuple_expression
245+
(integer_literal)
246+
(integer_literal)
247+
(integer_literal))))

src/scanner.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ static bool scan_string_content(TSLexer *lexer, bool is_multiline, bool has_inte
5555
lexer->result_symbol = has_interpolation ? INTERPOLATED_STRING_END : SIMPLE_STRING;
5656
return true;
5757
}
58-
if (closing_quote_count == 3) {
58+
if (closing_quote_count >= 3 && lexer->lookahead != '"') {
5959
lexer->result_symbol = has_interpolation ? INTERPOLATED_MULTILINE_STRING_END : SIMPLE_MULTILINE_STRING;
6060
return true;
61-
}
61+
}
6262
} else if (lexer->lookahead == '$') {
6363
if (is_multiline && has_interpolation) {
6464
lexer->result_symbol = INTERPOLATED_MULTILINE_STRING_MIDDLE;

0 commit comments

Comments
 (0)