Skip to content

Commit 27bee8a

Browse files
committed
Allow trailing commas in objects and arrays
1 parent 8967d98 commit 27bee8a

File tree

4 files changed

+90446
-100501
lines changed

4 files changed

+90446
-100501
lines changed

grammar.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module.exports = grammar({
4848

4949
// { key ,
5050
// ^--- shorthand object property or comma expression in block?
51-
[$._expression, $.object]
51+
[$._expression, $._property_definition_list]
5252
],
5353

5454
rules: {
@@ -382,20 +382,27 @@ module.exports = grammar({
382382

383383
object: $ => prec(PREC.OBJECT, seq(
384384
'{',
385-
commaSep(choice(
386-
$.pair,
387-
$.method_definition,
388-
$.identifier,
389-
$.reserved_identifier,
390-
$.spread_element
391-
)),
385+
optional($._property_definition_list),
392386
'}'
393387
)),
394388

389+
_property_definition_list: $ => commaSep1Trailing($._property_definition_list, choice(
390+
$.pair,
391+
$.method_definition,
392+
$.identifier,
393+
$.reserved_identifier,
394+
$.spread_element
395+
)),
396+
395397
array: $ => seq(
396-
'[', commaSep(choice($._expression, $.spread_element)), ']'
398+
'[', optional($._element_list), ']'
397399
),
398400

401+
_element_list: $ => commaSep1Trailing($._element_list, choice(
402+
$._expression,
403+
$.spread_element
404+
)),
405+
399406
// Anonymous class declarations only occur in exports
400407
anonymous_class: $ => choice(
401408
seq('class', $._class_tail)
@@ -658,6 +665,10 @@ module.exports = grammar({
658665
}
659666
});
660667

668+
function commaSep1Trailing(recurSymbol, rule) {
669+
return seq(rule, optional(seq(',', optional(recurSymbol))))
670+
}
671+
661672
function commaSep1 (rule) {
662673
return seq(rule, repeat(seq(',', rule)));
663674
}

grammar_test/expressions.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,17 @@ Objects with shorthand properties
123123
============================================
124124

125125
x = {a, b, get};
126+
y = {a,};
126127

127128
---
128129

129130
(program
130131
(expression_statement (assignment
131132
(identifier)
132-
(object (identifier) (identifier) (reserved_identifier)))))
133+
(object (identifier) (identifier) (reserved_identifier))))
134+
(expression_statement (assignment
135+
(identifier)
136+
(object (identifier)))))
133137

134138
============================================
135139
Objects with method definitions
@@ -262,13 +266,15 @@ Arrays
262266

263267
[];
264268
[ "item1" ];
269+
[ "item1", ];
265270
[ "item1", item2 ];
266271

267272
---
268273

269274
(program
270275
(expression_statement (array))
271276
(expression_statement (array (string)))
277+
(expression_statement (array (string)))
272278
(expression_statement (array (string) (identifier))))
273279

274280
============================================

src/grammar.json

Lines changed: 101 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,71 +1616,8 @@
16161616
"type": "CHOICE",
16171617
"members": [
16181618
{
1619-
"type": "SEQ",
1620-
"members": [
1621-
{
1622-
"type": "CHOICE",
1623-
"members": [
1624-
{
1625-
"type": "SYMBOL",
1626-
"name": "pair"
1627-
},
1628-
{
1629-
"type": "SYMBOL",
1630-
"name": "method_definition"
1631-
},
1632-
{
1633-
"type": "SYMBOL",
1634-
"name": "identifier"
1635-
},
1636-
{
1637-
"type": "SYMBOL",
1638-
"name": "reserved_identifier"
1639-
},
1640-
{
1641-
"type": "SYMBOL",
1642-
"name": "spread_element"
1643-
}
1644-
]
1645-
},
1646-
{
1647-
"type": "REPEAT",
1648-
"content": {
1649-
"type": "SEQ",
1650-
"members": [
1651-
{
1652-
"type": "STRING",
1653-
"value": ","
1654-
},
1655-
{
1656-
"type": "CHOICE",
1657-
"members": [
1658-
{
1659-
"type": "SYMBOL",
1660-
"name": "pair"
1661-
},
1662-
{
1663-
"type": "SYMBOL",
1664-
"name": "method_definition"
1665-
},
1666-
{
1667-
"type": "SYMBOL",
1668-
"name": "identifier"
1669-
},
1670-
{
1671-
"type": "SYMBOL",
1672-
"name": "reserved_identifier"
1673-
},
1674-
{
1675-
"type": "SYMBOL",
1676-
"name": "spread_element"
1677-
}
1678-
]
1679-
}
1680-
]
1681-
}
1682-
}
1683-
]
1619+
"type": "SYMBOL",
1620+
"name": "_property_definition_list"
16841621
},
16851622
{
16861623
"type": "BLANK"
@@ -1694,70 +1631,137 @@
16941631
]
16951632
}
16961633
},
1697-
"array": {
1634+
"_property_definition_list": {
16981635
"type": "SEQ",
16991636
"members": [
17001637
{
1701-
"type": "STRING",
1702-
"value": "["
1638+
"type": "CHOICE",
1639+
"members": [
1640+
{
1641+
"type": "SYMBOL",
1642+
"name": "pair"
1643+
},
1644+
{
1645+
"type": "SYMBOL",
1646+
"name": "method_definition"
1647+
},
1648+
{
1649+
"type": "SYMBOL",
1650+
"name": "identifier"
1651+
},
1652+
{
1653+
"type": "SYMBOL",
1654+
"name": "reserved_identifier"
1655+
},
1656+
{
1657+
"type": "SYMBOL",
1658+
"name": "spread_element"
1659+
}
1660+
]
17031661
},
17041662
{
17051663
"type": "CHOICE",
17061664
"members": [
17071665
{
17081666
"type": "SEQ",
17091667
"members": [
1668+
{
1669+
"type": "STRING",
1670+
"value": ","
1671+
},
17101672
{
17111673
"type": "CHOICE",
17121674
"members": [
17131675
{
17141676
"type": "SYMBOL",
1715-
"name": "_expression"
1677+
"name": "_property_definition_list"
17161678
},
17171679
{
1718-
"type": "SYMBOL",
1719-
"name": "spread_element"
1680+
"type": "BLANK"
17201681
}
17211682
]
1722-
},
1723-
{
1724-
"type": "REPEAT",
1725-
"content": {
1726-
"type": "SEQ",
1727-
"members": [
1728-
{
1729-
"type": "STRING",
1730-
"value": ","
1731-
},
1732-
{
1733-
"type": "CHOICE",
1734-
"members": [
1735-
{
1736-
"type": "SYMBOL",
1737-
"name": "_expression"
1738-
},
1739-
{
1740-
"type": "SYMBOL",
1741-
"name": "spread_element"
1742-
}
1743-
]
1744-
}
1745-
]
1746-
}
17471683
}
17481684
]
17491685
},
17501686
{
17511687
"type": "BLANK"
17521688
}
17531689
]
1690+
}
1691+
]
1692+
},
1693+
"array": {
1694+
"type": "SEQ",
1695+
"members": [
1696+
{
1697+
"type": "STRING",
1698+
"value": "["
1699+
},
1700+
{
1701+
"type": "CHOICE",
1702+
"members": [
1703+
{
1704+
"type": "SYMBOL",
1705+
"name": "_element_list"
1706+
},
1707+
{
1708+
"type": "BLANK"
1709+
}
1710+
]
17541711
},
17551712
{
17561713
"type": "STRING",
17571714
"value": "]"
17581715
}
17591716
]
17601717
},
1718+
"_element_list": {
1719+
"type": "SEQ",
1720+
"members": [
1721+
{
1722+
"type": "CHOICE",
1723+
"members": [
1724+
{
1725+
"type": "SYMBOL",
1726+
"name": "_expression"
1727+
},
1728+
{
1729+
"type": "SYMBOL",
1730+
"name": "spread_element"
1731+
}
1732+
]
1733+
},
1734+
{
1735+
"type": "CHOICE",
1736+
"members": [
1737+
{
1738+
"type": "SEQ",
1739+
"members": [
1740+
{
1741+
"type": "STRING",
1742+
"value": ","
1743+
},
1744+
{
1745+
"type": "CHOICE",
1746+
"members": [
1747+
{
1748+
"type": "SYMBOL",
1749+
"name": "_element_list"
1750+
},
1751+
{
1752+
"type": "BLANK"
1753+
}
1754+
]
1755+
}
1756+
]
1757+
},
1758+
{
1759+
"type": "BLANK"
1760+
}
1761+
]
1762+
}
1763+
]
1764+
},
17611765
"anonymous_class": {
17621766
"type": "CHOICE",
17631767
"members": [
@@ -3501,7 +3505,7 @@
35013505
],
35023506
[
35033507
"_expression",
3504-
"object"
3508+
"_property_definition_list"
35053509
]
35063510
]
35073511
}

0 commit comments

Comments
 (0)