treetop 1.4.12 → 1.4.14
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/tt +1 -1
- data/doc/site/robots.txt +0 -0
- data/lib/treetop/compiler/grammar_compiler.rb +7 -2
- data/lib/treetop/compiler/metagrammar.rb +310 -91
- data/lib/treetop/compiler/metagrammar.treetop +56 -8
- data/lib/treetop/ruby_extensions/string.rb +7 -5
- data/lib/treetop/version.rb +1 -1
- data/spec/compiler/multibyte_chars_spec.rb +0 -1
- data/spec/compiler/sequence_spec.rb +14 -0
- data/spec/compiler/test_grammar.treetop +0 -0
- data/spec/compiler/test_grammar.tt +0 -0
- data/spec/compiler/tt_compiler_spec.rb +9 -2
- data/spec/composition/b.treetop +0 -0
- data/spec/composition/c.treetop +0 -0
- data/spec/composition/d.treetop +0 -0
- data/treetop.gemspec +2 -2
- metadata +3 -3
data/bin/tt
CHANGED
@@ -77,7 +77,7 @@ end
|
|
77
77
|
def protect_output?(filename, forced=false)
|
78
78
|
if !forced and
|
79
79
|
File.exist?(filename) and
|
80
|
-
|
80
|
+
File.open(filename) { |f| ![(f.gets rescue ''), (f.gets rescue '')].include? Treetop::Compiler::AUTOGENERATED }
|
81
81
|
puts "ERROR: '#{filename}' output already exists; skipping compilation...\n"
|
82
82
|
return true
|
83
83
|
end
|
data/doc/site/robots.txt
CHANGED
File without changes
|
@@ -4,8 +4,13 @@ module Treetop
|
|
4
4
|
class GrammarCompiler
|
5
5
|
def compile(source_path, target_path = source_path.gsub(/\.(treetop|tt)\Z/, '.rb'))
|
6
6
|
File.open(target_path, 'w') do |target_file|
|
7
|
-
|
8
|
-
|
7
|
+
ruby = ruby_source(source_path)
|
8
|
+
if ruby =~ /\A#.*\n/
|
9
|
+
ruby.sub!(/\n/, "\n"+AUTOGENERATED+"\n\n")
|
10
|
+
else
|
11
|
+
ruby = AUTOGENERATED+"\n\n"+ruby
|
12
|
+
end
|
13
|
+
target_file.write(ruby)
|
9
14
|
end
|
10
15
|
end
|
11
16
|
|
@@ -1140,36 +1140,22 @@ module Treetop
|
|
1140
1140
|
end
|
1141
1141
|
|
1142
1142
|
module Sequence0
|
1143
|
-
def
|
1143
|
+
def sequence_body
|
1144
1144
|
elements[0]
|
1145
1145
|
end
|
1146
1146
|
|
1147
|
-
def
|
1147
|
+
def node_class_declarations
|
1148
1148
|
elements[1]
|
1149
1149
|
end
|
1150
1150
|
end
|
1151
1151
|
|
1152
1152
|
module Sequence1
|
1153
|
-
def head
|
1154
|
-
elements[0]
|
1155
|
-
end
|
1156
|
-
|
1157
|
-
def tail
|
1158
|
-
elements[1]
|
1159
|
-
end
|
1160
|
-
|
1161
|
-
def node_class_declarations
|
1162
|
-
elements[2]
|
1163
|
-
end
|
1164
|
-
end
|
1165
|
-
|
1166
|
-
module Sequence2
|
1167
1153
|
def sequence_elements
|
1168
|
-
[head] + tail
|
1154
|
+
[sequence_body.head] + tail
|
1169
1155
|
end
|
1170
1156
|
|
1171
1157
|
def tail
|
1172
|
-
|
1158
|
+
sequence_body.tail
|
1173
1159
|
end
|
1174
1160
|
|
1175
1161
|
def inline_modules
|
@@ -1195,7 +1181,95 @@ module Treetop
|
|
1195
1181
|
end
|
1196
1182
|
|
1197
1183
|
i0, s0 = index, []
|
1198
|
-
r1 =
|
1184
|
+
r1 = _nt_sequence_body
|
1185
|
+
s0 << r1
|
1186
|
+
if r1
|
1187
|
+
r2 = _nt_node_class_declarations
|
1188
|
+
s0 << r2
|
1189
|
+
end
|
1190
|
+
if s0.last
|
1191
|
+
r0 = instantiate_node(Sequence,input, i0...index, s0)
|
1192
|
+
r0.extend(Sequence0)
|
1193
|
+
r0.extend(Sequence1)
|
1194
|
+
else
|
1195
|
+
@index = i0
|
1196
|
+
r0 = nil
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
node_cache[:sequence][start_index] = r0
|
1200
|
+
|
1201
|
+
r0
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
def _nt_sequence_body
|
1205
|
+
start_index = index
|
1206
|
+
if node_cache[:sequence_body].has_key?(index)
|
1207
|
+
cached = node_cache[:sequence_body][index]
|
1208
|
+
if cached
|
1209
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1210
|
+
@index = cached.interval.end
|
1211
|
+
end
|
1212
|
+
return cached
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
i0 = index
|
1216
|
+
r1 = _nt_variable_length_sequence_body
|
1217
|
+
if r1
|
1218
|
+
r0 = r1
|
1219
|
+
else
|
1220
|
+
r2 = _nt_labeled_expression_sequence_body
|
1221
|
+
if r2
|
1222
|
+
r0 = r2
|
1223
|
+
else
|
1224
|
+
@index = i0
|
1225
|
+
r0 = nil
|
1226
|
+
end
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
node_cache[:sequence_body][start_index] = r0
|
1230
|
+
|
1231
|
+
r0
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
module VariableLengthSequenceBody0
|
1235
|
+
def space
|
1236
|
+
elements[0]
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
def optionally_labeled_sequence_primary
|
1240
|
+
elements[1]
|
1241
|
+
end
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
module VariableLengthSequenceBody1
|
1245
|
+
def head
|
1246
|
+
elements[0]
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
def tail
|
1250
|
+
elements[1]
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
module VariableLengthSequenceBody2
|
1255
|
+
def tail
|
1256
|
+
super.elements.map {|elt| elt.optionally_labeled_sequence_primary }
|
1257
|
+
end
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
def _nt_variable_length_sequence_body
|
1261
|
+
start_index = index
|
1262
|
+
if node_cache[:variable_length_sequence_body].has_key?(index)
|
1263
|
+
cached = node_cache[:variable_length_sequence_body][index]
|
1264
|
+
if cached
|
1265
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1266
|
+
@index = cached.interval.end
|
1267
|
+
end
|
1268
|
+
return cached
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
i0, s0 = index, []
|
1272
|
+
r1 = _nt_optionally_labeled_sequence_primary
|
1199
1273
|
s0 << r1
|
1200
1274
|
if r1
|
1201
1275
|
s2, i2 = [], index
|
@@ -1204,12 +1278,12 @@ module Treetop
|
|
1204
1278
|
r4 = _nt_space
|
1205
1279
|
s3 << r4
|
1206
1280
|
if r4
|
1207
|
-
r5 =
|
1281
|
+
r5 = _nt_optionally_labeled_sequence_primary
|
1208
1282
|
s3 << r5
|
1209
1283
|
end
|
1210
1284
|
if s3.last
|
1211
1285
|
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
|
1212
|
-
r3.extend(
|
1286
|
+
r3.extend(VariableLengthSequenceBody0)
|
1213
1287
|
else
|
1214
1288
|
@index = i3
|
1215
1289
|
r3 = nil
|
@@ -1227,21 +1301,46 @@ module Treetop
|
|
1227
1301
|
r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
|
1228
1302
|
end
|
1229
1303
|
s0 << r2
|
1230
|
-
if r2
|
1231
|
-
r6 = _nt_node_class_declarations
|
1232
|
-
s0 << r6
|
1233
|
-
end
|
1234
1304
|
end
|
1235
1305
|
if s0.last
|
1236
|
-
r0 = instantiate_node(
|
1237
|
-
r0.extend(
|
1238
|
-
r0.extend(
|
1306
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1307
|
+
r0.extend(VariableLengthSequenceBody1)
|
1308
|
+
r0.extend(VariableLengthSequenceBody2)
|
1239
1309
|
else
|
1240
1310
|
@index = i0
|
1241
1311
|
r0 = nil
|
1242
1312
|
end
|
1243
1313
|
|
1244
|
-
node_cache[:
|
1314
|
+
node_cache[:variable_length_sequence_body][start_index] = r0
|
1315
|
+
|
1316
|
+
r0
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
module LabeledExpressionSequenceBody0
|
1320
|
+
def head
|
1321
|
+
self
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
def tail
|
1325
|
+
[]
|
1326
|
+
end
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
def _nt_labeled_expression_sequence_body
|
1330
|
+
start_index = index
|
1331
|
+
if node_cache[:labeled_expression_sequence_body].has_key?(index)
|
1332
|
+
cached = node_cache[:labeled_expression_sequence_body][index]
|
1333
|
+
if cached
|
1334
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1335
|
+
@index = cached.interval.end
|
1336
|
+
end
|
1337
|
+
return cached
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
r0 = _nt_labeled_sequence_primary
|
1341
|
+
r0.extend(LabeledExpressionSequenceBody0)
|
1342
|
+
|
1343
|
+
node_cache[:labeled_expression_sequence_body][start_index] = r0
|
1245
1344
|
|
1246
1345
|
r0
|
1247
1346
|
end
|
@@ -1499,8 +1598,38 @@ module Treetop
|
|
1499
1598
|
r0
|
1500
1599
|
end
|
1501
1600
|
|
1601
|
+
def _nt_optionally_labeled_sequence_primary
|
1602
|
+
start_index = index
|
1603
|
+
if node_cache[:optionally_labeled_sequence_primary].has_key?(index)
|
1604
|
+
cached = node_cache[:optionally_labeled_sequence_primary][index]
|
1605
|
+
if cached
|
1606
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1607
|
+
@index = cached.interval.end
|
1608
|
+
end
|
1609
|
+
return cached
|
1610
|
+
end
|
1611
|
+
|
1612
|
+
i0 = index
|
1613
|
+
r1 = _nt_labeled_sequence_primary
|
1614
|
+
if r1
|
1615
|
+
r0 = r1
|
1616
|
+
else
|
1617
|
+
r2 = _nt_unlabeled_sequence_primary
|
1618
|
+
if r2
|
1619
|
+
r0 = r2
|
1620
|
+
else
|
1621
|
+
@index = i0
|
1622
|
+
r0 = nil
|
1623
|
+
end
|
1624
|
+
end
|
1625
|
+
|
1626
|
+
node_cache[:optionally_labeled_sequence_primary][start_index] = r0
|
1627
|
+
|
1628
|
+
r0
|
1629
|
+
end
|
1630
|
+
|
1502
1631
|
module LabeledSequencePrimary0
|
1503
|
-
def
|
1632
|
+
def named_label
|
1504
1633
|
elements[0]
|
1505
1634
|
end
|
1506
1635
|
|
@@ -1519,13 +1648,7 @@ module Treetop
|
|
1519
1648
|
end
|
1520
1649
|
|
1521
1650
|
def label_name
|
1522
|
-
|
1523
|
-
label.name
|
1524
|
-
elsif sequence_primary.instance_of?(Nonterminal)
|
1525
|
-
sequence_primary.text_value
|
1526
|
-
else
|
1527
|
-
nil
|
1528
|
-
end
|
1651
|
+
named_label.name
|
1529
1652
|
end
|
1530
1653
|
end
|
1531
1654
|
|
@@ -1541,7 +1664,7 @@ module Treetop
|
|
1541
1664
|
end
|
1542
1665
|
|
1543
1666
|
i0, s0 = index, []
|
1544
|
-
r1 =
|
1667
|
+
r1 = _nt_named_label
|
1545
1668
|
s0 << r1
|
1546
1669
|
if r1
|
1547
1670
|
r2 = _nt_sequence_primary
|
@@ -1561,26 +1684,64 @@ module Treetop
|
|
1561
1684
|
r0
|
1562
1685
|
end
|
1563
1686
|
|
1564
|
-
module
|
1565
|
-
def
|
1687
|
+
module UnlabeledSequencePrimary0
|
1688
|
+
def null_label
|
1566
1689
|
elements[0]
|
1567
1690
|
end
|
1568
1691
|
|
1692
|
+
def sequence_primary
|
1693
|
+
elements[1]
|
1694
|
+
end
|
1569
1695
|
end
|
1570
1696
|
|
1571
|
-
module
|
1572
|
-
|
1697
|
+
module UnlabeledSequencePrimary1
|
1698
|
+
def compile(lexical_address, builder)
|
1699
|
+
sequence_primary.compile(lexical_address, builder)
|
1700
|
+
end
|
1573
1701
|
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1702
|
+
def inline_modules
|
1703
|
+
sequence_primary.inline_modules
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
def label_name
|
1707
|
+
if sequence_primary.instance_of?(Nonterminal)
|
1708
|
+
sequence_primary.text_value
|
1709
|
+
else
|
1710
|
+
nil
|
1711
|
+
end
|
1577
1712
|
end
|
1578
1713
|
end
|
1579
1714
|
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1715
|
+
def _nt_unlabeled_sequence_primary
|
1716
|
+
start_index = index
|
1717
|
+
if node_cache[:unlabeled_sequence_primary].has_key?(index)
|
1718
|
+
cached = node_cache[:unlabeled_sequence_primary][index]
|
1719
|
+
if cached
|
1720
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1721
|
+
@index = cached.interval.end
|
1722
|
+
end
|
1723
|
+
return cached
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
i0, s0 = index, []
|
1727
|
+
r1 = _nt_null_label
|
1728
|
+
s0 << r1
|
1729
|
+
if r1
|
1730
|
+
r2 = _nt_sequence_primary
|
1731
|
+
s0 << r2
|
1732
|
+
end
|
1733
|
+
if s0.last
|
1734
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1735
|
+
r0.extend(UnlabeledSequencePrimary0)
|
1736
|
+
r0.extend(UnlabeledSequencePrimary1)
|
1737
|
+
else
|
1738
|
+
@index = i0
|
1739
|
+
r0 = nil
|
1583
1740
|
end
|
1741
|
+
|
1742
|
+
node_cache[:unlabeled_sequence_primary][start_index] = r0
|
1743
|
+
|
1744
|
+
r0
|
1584
1745
|
end
|
1585
1746
|
|
1586
1747
|
def _nt_label
|
@@ -1595,69 +1756,127 @@ module Treetop
|
|
1595
1756
|
end
|
1596
1757
|
|
1597
1758
|
i0 = index
|
1759
|
+
r1 = _nt_named_label
|
1760
|
+
if r1
|
1761
|
+
r0 = r1
|
1762
|
+
else
|
1763
|
+
r2 = _nt_null_label
|
1764
|
+
if r2
|
1765
|
+
r0 = r2
|
1766
|
+
else
|
1767
|
+
@index = i0
|
1768
|
+
r0 = nil
|
1769
|
+
end
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
node_cache[:label][start_index] = r0
|
1773
|
+
|
1774
|
+
r0
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
module NamedLabel0
|
1778
|
+
def alpha_char
|
1779
|
+
elements[0]
|
1780
|
+
end
|
1781
|
+
|
1782
|
+
end
|
1783
|
+
|
1784
|
+
module NamedLabel1
|
1785
|
+
end
|
1786
|
+
|
1787
|
+
module NamedLabel2
|
1788
|
+
def name
|
1789
|
+
elements[0].text_value
|
1790
|
+
end
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
def _nt_named_label
|
1794
|
+
start_index = index
|
1795
|
+
if node_cache[:named_label].has_key?(index)
|
1796
|
+
cached = node_cache[:named_label][index]
|
1797
|
+
if cached
|
1798
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1799
|
+
@index = cached.interval.end
|
1800
|
+
end
|
1801
|
+
return cached
|
1802
|
+
end
|
1803
|
+
|
1804
|
+
i0, s0 = index, []
|
1598
1805
|
i1, s1 = index, []
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
s4, i4 = [], index
|
1806
|
+
r2 = _nt_alpha_char
|
1807
|
+
s1 << r2
|
1808
|
+
if r2
|
1809
|
+
s3, i3 = [], index
|
1604
1810
|
loop do
|
1605
|
-
|
1606
|
-
if
|
1607
|
-
|
1811
|
+
r4 = _nt_alphanumeric_char
|
1812
|
+
if r4
|
1813
|
+
s3 << r4
|
1608
1814
|
else
|
1609
1815
|
break
|
1610
1816
|
end
|
1611
1817
|
end
|
1612
|
-
|
1613
|
-
|
1818
|
+
r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
|
1819
|
+
s1 << r3
|
1614
1820
|
end
|
1615
|
-
if
|
1616
|
-
|
1617
|
-
|
1821
|
+
if s1.last
|
1822
|
+
r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
|
1823
|
+
r1.extend(NamedLabel0)
|
1618
1824
|
else
|
1619
|
-
@index =
|
1620
|
-
|
1825
|
+
@index = i1
|
1826
|
+
r1 = nil
|
1621
1827
|
end
|
1622
|
-
|
1623
|
-
if
|
1828
|
+
s0 << r1
|
1829
|
+
if r1
|
1624
1830
|
if has_terminal?(':', false, index)
|
1625
|
-
|
1831
|
+
r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
1626
1832
|
@index += 1
|
1627
1833
|
else
|
1628
1834
|
terminal_parse_failure(':')
|
1629
|
-
|
1835
|
+
r5 = nil
|
1630
1836
|
end
|
1631
|
-
|
1837
|
+
s0 << r5
|
1632
1838
|
end
|
1633
|
-
if
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1839
|
+
if s0.last
|
1840
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
1841
|
+
r0.extend(NamedLabel1)
|
1842
|
+
r0.extend(NamedLabel2)
|
1637
1843
|
else
|
1638
|
-
@index =
|
1639
|
-
|
1844
|
+
@index = i0
|
1845
|
+
r0 = nil
|
1640
1846
|
end
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1847
|
+
|
1848
|
+
node_cache[:named_label][start_index] = r0
|
1849
|
+
|
1850
|
+
r0
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
module NullLabel0
|
1854
|
+
def name
|
1855
|
+
nil
|
1856
|
+
end
|
1857
|
+
end
|
1858
|
+
|
1859
|
+
def _nt_null_label
|
1860
|
+
start_index = index
|
1861
|
+
if node_cache[:null_label].has_key?(index)
|
1862
|
+
cached = node_cache[:null_label][index]
|
1863
|
+
if cached
|
1864
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1865
|
+
@index = cached.interval.end
|
1657
1866
|
end
|
1867
|
+
return cached
|
1658
1868
|
end
|
1659
1869
|
|
1660
|
-
|
1870
|
+
if has_terminal?('', false, index)
|
1871
|
+
r0 = instantiate_node(SyntaxNode,input, index...(index + 0))
|
1872
|
+
r0.extend(NullLabel0)
|
1873
|
+
@index += 0
|
1874
|
+
else
|
1875
|
+
terminal_parse_failure('')
|
1876
|
+
r0 = nil
|
1877
|
+
end
|
1878
|
+
|
1879
|
+
node_cache[:null_label][start_index] = r0
|
1661
1880
|
|
1662
1881
|
r0
|
1663
1882
|
end
|
@@ -91,13 +91,13 @@ module Treetop
|
|
91
91
|
end
|
92
92
|
|
93
93
|
rule sequence
|
94
|
-
|
94
|
+
sequence_body node_class_declarations <Sequence> {
|
95
95
|
def sequence_elements
|
96
|
-
[head] + tail
|
96
|
+
[sequence_body.head] + tail
|
97
97
|
end
|
98
98
|
|
99
99
|
def tail
|
100
|
-
|
100
|
+
sequence_body.tail
|
101
101
|
end
|
102
102
|
|
103
103
|
def inline_modules
|
@@ -112,6 +112,30 @@ module Treetop
|
|
112
112
|
}
|
113
113
|
end
|
114
114
|
|
115
|
+
rule sequence_body
|
116
|
+
variable_length_sequence_body / labeled_expression_sequence_body
|
117
|
+
end
|
118
|
+
|
119
|
+
rule variable_length_sequence_body
|
120
|
+
head:optionally_labeled_sequence_primary tail:(space optionally_labeled_sequence_primary)+ {
|
121
|
+
def tail
|
122
|
+
super.elements.map {|elt| elt.optionally_labeled_sequence_primary }
|
123
|
+
end
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
rule labeled_expression_sequence_body
|
128
|
+
labeled_sequence_primary {
|
129
|
+
def head
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
def tail
|
134
|
+
[]
|
135
|
+
end
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
115
139
|
rule alternative
|
116
140
|
sequence / primary
|
117
141
|
end
|
@@ -188,8 +212,12 @@ module Treetop
|
|
188
212
|
}
|
189
213
|
end
|
190
214
|
|
215
|
+
rule optionally_labeled_sequence_primary
|
216
|
+
labeled_sequence_primary / unlabeled_sequence_primary
|
217
|
+
end
|
218
|
+
|
191
219
|
rule labeled_sequence_primary
|
192
|
-
|
220
|
+
named_label sequence_primary {
|
193
221
|
def compile(lexical_address, builder)
|
194
222
|
sequence_primary.compile(lexical_address, builder)
|
195
223
|
end
|
@@ -199,9 +227,23 @@ module Treetop
|
|
199
227
|
end
|
200
228
|
|
201
229
|
def label_name
|
202
|
-
|
203
|
-
|
204
|
-
|
230
|
+
named_label.name
|
231
|
+
end
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
rule unlabeled_sequence_primary
|
236
|
+
null_label sequence_primary {
|
237
|
+
def compile(lexical_address, builder)
|
238
|
+
sequence_primary.compile(lexical_address, builder)
|
239
|
+
end
|
240
|
+
|
241
|
+
def inline_modules
|
242
|
+
sequence_primary.inline_modules
|
243
|
+
end
|
244
|
+
|
245
|
+
def label_name
|
246
|
+
if sequence_primary.instance_of?(Nonterminal)
|
205
247
|
sequence_primary.text_value
|
206
248
|
else
|
207
249
|
nil
|
@@ -211,12 +253,18 @@ module Treetop
|
|
211
253
|
end
|
212
254
|
|
213
255
|
rule label
|
256
|
+
named_label / null_label
|
257
|
+
end
|
258
|
+
|
259
|
+
rule named_label
|
214
260
|
(alpha_char alphanumeric_char*) ':' {
|
215
261
|
def name
|
216
262
|
elements[0].text_value
|
217
263
|
end
|
218
264
|
}
|
219
|
-
|
265
|
+
end
|
266
|
+
|
267
|
+
rule null_label
|
220
268
|
'' {
|
221
269
|
def name
|
222
270
|
nil
|
@@ -28,11 +28,13 @@ class String
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
unless method_defined?(:indent)
|
32
|
+
def indent(n)
|
33
|
+
if n >= 0
|
34
|
+
gsub(/^/, ' ' * n)
|
35
|
+
else
|
36
|
+
gsub(/^ {0,#{-n}}/, "")
|
37
|
+
end
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
data/lib/treetop/version.rb
CHANGED
@@ -60,6 +60,20 @@ module SequenceSpec
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
describe "a labeled single element sequence followed by a node module declaration and a block" do
|
64
|
+
testing_expression 'foo:"foo"+ <SequenceSpec::ModFoo> { def a_method; end }'
|
65
|
+
it "upon successfully matching input, instantiates a syntax node and extends it with the declared module, element accessor methods, and the method from the inline module" do
|
66
|
+
parse('foofoofoo') do |result|
|
67
|
+
result.should_not be_nil
|
68
|
+
result.should respond_to(:mod_method)
|
69
|
+
result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
|
70
|
+
result.should be_a_kind_of(ModFoo)
|
71
|
+
result.should respond_to(:a_method)
|
72
|
+
result.foo.text_value.should == 'foofoofoo'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
63
77
|
describe "a sequence of non-terminals" do
|
64
78
|
testing_grammar %{
|
65
79
|
grammar TestGrammar
|
File without changes
|
File without changes
|
@@ -20,6 +20,7 @@ describe "The 'tt' comand line compiler" do
|
|
20
20
|
@test_grammar = "#{@test_path}.tt"
|
21
21
|
@test_ruby = "#{@test_path}.rb"
|
22
22
|
File.open(@test_grammar, 'w+') do |f|
|
23
|
+
f.print("# Encoding: UTF-8\n")
|
23
24
|
f.print("grammar Dumb\n")
|
24
25
|
f.print("end\n")
|
25
26
|
end unless File.exists?(@test_grammar)
|
@@ -96,8 +97,14 @@ describe "The 'tt' comand line compiler" do
|
|
96
97
|
File.exists?(pf).should be_true
|
97
98
|
File.zero?(pf).should_not be_true
|
98
99
|
|
99
|
-
#
|
100
|
-
File.open(pf, "r
|
100
|
+
# Check that the magic comment is preserved:
|
101
|
+
written = File.open(pf, "r") { |f| s = f.read }
|
102
|
+
written.should =~ /\A# Encoding: UTF-8/
|
103
|
+
|
104
|
+
# Modify the file's auto-generated comment and make sure it doesn't get overwritten:
|
105
|
+
written.sub!(/generated/, 'broken');
|
106
|
+
File.open(pf, "w") { |f| f.write(written) }
|
107
|
+
# File.open(pf, "r+") { |f| s = f.read; s.sub!(/generated/, 'broken'); f.rewind; f.write(s) }
|
101
108
|
orig_file_hash = Digest::SHA1.hexdigest(File.read(pf))
|
102
109
|
|
103
110
|
Kernel.open("|ruby -S tt -o #{pf} #{@test_path}") do |io|
|
data/spec/composition/b.treetop
CHANGED
File without changes
|
data/spec/composition/c.treetop
CHANGED
File without changes
|
data/spec/composition/d.treetop
CHANGED
File without changes
|
data/treetop.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "treetop"
|
8
|
-
s.version = "1.4.
|
8
|
+
s.version = "1.4.14"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nathan Sobo", "Clifford Heath"]
|
12
12
|
s.autorequire = "treetop"
|
13
|
-
s.date = "
|
13
|
+
s.date = "2013-06-04"
|
14
14
|
s.email = "cliffordheath@gmail.com"
|
15
15
|
s.executables = ["tt"]
|
16
16
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: treetop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.14
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire: treetop
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-06-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: polyglot
|
@@ -289,7 +289,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
289
289
|
version: '0'
|
290
290
|
segments:
|
291
291
|
- 0
|
292
|
-
hash:
|
292
|
+
hash: 622706517614693275
|
293
293
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
294
294
|
none: false
|
295
295
|
requirements:
|