@@ -18,6 +18,7 @@ module.exports = grammar({
1818
1919 conflicts : $ => [
2020 [ $ . pair ] ,
21+ [ $ . array_value , $ . value ] ,
2122 ] ,
2223
2324 extras : $ => [
@@ -68,8 +69,7 @@ module.exports = grammar({
6869 ':' ,
6970 optional ( / [ \t ] + / ) ,
7071 field ( 'value' , choice (
71- prec ( 2 , seq ( $ . inline_values , $ . _newline ) ) ,
72- prec ( 1 , seq ( $ . value , $ . _newline ) ) ,
72+ seq ( $ . value , $ . _newline ) ,
7373 seq ( $ . _newline , $ . object )
7474 ) )
7575 )
@@ -117,14 +117,23 @@ module.exports = grammar({
117117 delimiter : $ => token . immediate ( choice ( '\t' , '|' ) ) ,
118118
119119 inline_values : $ => seq (
120- $ . value ,
120+ alias ( $ . array_value , $ . value ) ,
121121 repeat ( seq (
122122 choice ( ',' , '|' , '\t' ) ,
123123 optional ( / [ \t ] * / ) ,
124- $ . value
124+ alias ( $ . array_value , $ . value )
125125 ) )
126126 ) ,
127127
128+ // Values used in array contexts (inline arrays and list items)
129+ array_value : $ => choice (
130+ $ . null ,
131+ $ . boolean ,
132+ $ . number ,
133+ $ . string ,
134+ alias ( $ . array_unquoted_string , $ . unquoted_string )
135+ ) ,
136+
128137 field_list : $ => seq (
129138 $ . field_name ,
130139 repeat ( seq (
@@ -180,7 +189,7 @@ module.exports = grammar({
180189 $ . boolean ,
181190 $ . number ,
182191 $ . string ,
183- $ . unquoted_string
192+ alias ( $ . array_unquoted_string , $ . unquoted_string )
184193 ) ,
185194
186195 object_row : $ => choice (
@@ -240,13 +249,23 @@ module.exports = grammar({
240249 $ . unquoted_string
241250 ) ,
242251
243- // Unquoted strings: cannot start with -, and cannot contain : " [ ] { } , | \t \n \r or have leading/trailing space
252+ // Unquoted strings: cannot start with -, and cannot contain : " [ ] { } \n \r or have leading/trailing space
253+ // Note: Delimiters (comma, pipe, tab) are allowed in unquoted strings for object values (no array header)
254+ // They are only special within array inline values/tabular rows (where splitting occurs)
244255 // This pattern explicitly excludes strings that would be valid numbers (those use the number rule)
245- // Strategy: match strings that contain at least one character that makes them non-numeric
246256 unquoted_string : $ => token ( choice (
247- // Starts with non-digit (but not -), anything after
248- seq ( / [ ^ \s : " \[ \] { } , | \t \ n\r \- 0 - 9 ] / , optional ( / [ ^ \n \r : " \[ \] { } , | \t ] + / ) , optional ( / [ ^ \s : " \[ \] { } , | \t \n \r ] / ) ) ,
257+ // Starts with non-digit (but not -), anything after (excluding only structural chars, not delimiters)
258+ seq ( / [ ^ \s : " \[ \] { } \ n\r \- 0 - 9 ] / , optional ( / [ ^ \n \r : " \[ \] { } ] + / ) , optional ( / [ ^ \s : " \[ \] { } \n \r ] / ) ) ,
249259 // Starts with digit, has non-number chars in middle/end
260+ seq ( / [ 0 - 9 ] / , / [ ^ \n \r : " \[ \] { } ] * [ ^ \s : " \[ \] { } \n \r 0 - 9 e E + . \- ] / , optional ( / [ ^ \n \r : " \[ \] { } ] * / ) , optional ( / [ ^ \s : " \[ \] { } \n \r ] / ) )
261+ ) ) ,
262+
263+ // Array unquoted strings: used in inline arrays and tabular rows where delimiters are special
264+ // Must exclude comma, pipe, and tab since those are used to split values
265+ array_unquoted_string : $ => token ( choice (
266+ // Starts with non-digit (but not -), anything after (excluding delimiters)
267+ seq ( / [ ^ \s : " \[ \] { } , | \t \n \r \- 0 - 9 ] / , optional ( / [ ^ \n \r : " \[ \] { } , | \t ] + / ) , optional ( / [ ^ \s : " \[ \] { } , | \t \n \r ] / ) ) ,
268+ // Starts with digit, has non-number chars in middle/end (excluding delimiters)
250269 seq ( / [ 0 - 9 ] / , / [ ^ \n \r : " \[ \] { } , | \t ] * [ ^ \s : " \[ \] { } , | \t \n \r 0 - 9 e E + . \- ] / , optional ( / [ ^ \n \r : " \[ \] { } , | \t ] * / ) , optional ( / [ ^ \s : " \[ \] { } , | \t \n \r ] / ) )
251270 ) ) ,
252271
0 commit comments