treetop 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. data/README +3 -0
  2. data/Rakefile +35 -0
  3. data/bin/tt +25 -0
  4. data/lib/treetop.rb +10 -6
  5. data/lib/treetop/compiler.rb +7 -0
  6. data/lib/treetop/compiler/grammar_compiler.rb +21 -0
  7. data/lib/treetop/compiler/lexical_address_space.rb +17 -0
  8. data/lib/treetop/compiler/load_grammar.rb +7 -0
  9. data/lib/treetop/compiler/metagrammar.rb +2441 -0
  10. data/lib/treetop/compiler/metagrammar.treetop +384 -0
  11. data/lib/treetop/compiler/node_classes.rb +18 -0
  12. data/lib/treetop/compiler/node_classes/anything_symbol.rb +10 -0
  13. data/lib/treetop/compiler/node_classes/atomic_expression.rb +9 -0
  14. data/lib/treetop/compiler/node_classes/character_class.rb +10 -0
  15. data/lib/treetop/compiler/node_classes/choice.rb +31 -0
  16. data/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
  17. data/lib/treetop/compiler/node_classes/grammar.rb +28 -0
  18. data/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
  19. data/lib/treetop/compiler/node_classes/nonterminal.rb +11 -0
  20. data/lib/treetop/compiler/node_classes/optional.rb +19 -0
  21. data/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
  22. data/lib/treetop/compiler/node_classes/parsing_expression.rb +132 -0
  23. data/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
  24. data/lib/treetop/compiler/node_classes/predicate.rb +45 -0
  25. data/lib/treetop/compiler/node_classes/repetition.rb +56 -0
  26. data/lib/treetop/compiler/node_classes/sequence.rb +64 -0
  27. data/lib/treetop/compiler/node_classes/terminal.rb +10 -0
  28. data/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
  29. data/lib/treetop/compiler/ruby_builder.rb +109 -0
  30. data/lib/treetop/ruby_extensions.rb +2 -0
  31. data/lib/treetop/ruby_extensions/string.rb +19 -0
  32. data/lib/treetop/runtime.rb +9 -0
  33. data/lib/treetop/runtime/compiled_parser.rb +66 -0
  34. data/lib/treetop/runtime/node_cache.rb +27 -0
  35. data/lib/treetop/runtime/parse_cache.rb +19 -0
  36. data/lib/treetop/runtime/parse_failure.rb +32 -0
  37. data/lib/treetop/runtime/parse_result.rb +30 -0
  38. data/lib/treetop/runtime/syntax_node.rb +53 -0
  39. data/lib/treetop/runtime/terminal_parse_failure.rb +33 -0
  40. data/lib/treetop/runtime/terminal_syntax_node.rb +12 -0
  41. data/test/compilation_target/target.rb +143 -0
  42. data/test/compilation_target/target.treetop +15 -0
  43. data/test/compilation_target/target_test.rb +56 -0
  44. data/test/compiler/and_predicate_test.rb +33 -0
  45. data/test/compiler/anything_symbol_test.rb +24 -0
  46. data/test/compiler/character_class_test.rb +45 -0
  47. data/test/compiler/choice_test.rb +49 -0
  48. data/test/compiler/circular_compilation_test.rb +20 -0
  49. data/test/compiler/failure_propagation_functional_test.rb +20 -0
  50. data/test/compiler/grammar_compiler_test.rb +58 -0
  51. data/test/compiler/grammar_test.rb +33 -0
  52. data/test/compiler/nonterminal_symbol_test.rb +15 -0
  53. data/test/compiler/not_predicate_test.rb +35 -0
  54. data/test/compiler/one_or_more_test.rb +30 -0
  55. data/test/compiler/optional_test.rb +32 -0
  56. data/test/compiler/parsing_rule_test.rb +30 -0
  57. data/test/compiler/sequence_test.rb +68 -0
  58. data/test/compiler/terminal_symbol_test.rb +35 -0
  59. data/test/compiler/test_grammar.treetop +7 -0
  60. data/test/compiler/zero_or_more_test.rb +51 -0
  61. data/test/composition/a.treetop +11 -0
  62. data/test/composition/b.treetop +11 -0
  63. data/test/composition/c.treetop +10 -0
  64. data/test/composition/d.treetop +10 -0
  65. data/test/composition/grammar_composition_test.rb +23 -0
  66. data/test/parser/syntax_node_test.rb +53 -0
  67. data/test/parser/terminal_parse_failure_test.rb +22 -0
  68. data/test/ruby_extensions/string_test.rb +33 -0
  69. data/test/screw/Rakefile +16 -0
  70. data/test/screw/unit.rb +37 -0
  71. data/test/screw/unit/assertion_failed_error.rb +14 -0
  72. data/test/screw/unit/assertions.rb +615 -0
  73. data/test/screw/unit/auto_runner.rb +227 -0
  74. data/test/screw/unit/collector.rb +45 -0
  75. data/test/screw/unit/collector/dir.rb +107 -0
  76. data/test/screw/unit/collector/objectspace.rb +28 -0
  77. data/test/screw/unit/error.rb +48 -0
  78. data/test/screw/unit/failure.rb +45 -0
  79. data/test/screw/unit/sugar.rb +25 -0
  80. data/test/screw/unit/test_case.rb +176 -0
  81. data/test/screw/unit/test_result.rb +73 -0
  82. data/test/screw/unit/test_suite.rb +70 -0
  83. data/test/screw/unit/ui.rb +4 -0
  84. data/test/screw/unit/ui/console/test_runner.rb +118 -0
  85. data/test/screw/unit/ui/fox/test_runner.rb +268 -0
  86. data/test/screw/unit/ui/gtk/test_runner.rb +416 -0
  87. data/test/screw/unit/ui/gtk2/testrunner.rb +465 -0
  88. data/test/screw/unit/ui/test_runner_mediator.rb +58 -0
  89. data/test/screw/unit/ui/test_runner_utilities.rb +46 -0
  90. data/test/screw/unit/ui/tk/test_runner.rb +260 -0
  91. data/test/screw/unit/util.rb +4 -0
  92. data/test/screw/unit/util/backtrace_filter.rb +40 -0
  93. data/test/screw/unit/util/observable.rb +82 -0
  94. data/test/screw/unit/util/proc_wrapper.rb +48 -0
  95. data/test/test_helper.rb +89 -0
  96. metadata +127 -69
  97. data/lib/treetop/api.rb +0 -3
  98. data/lib/treetop/api/load_grammar.rb +0 -16
  99. data/lib/treetop/api/malformed_grammar_exception.rb +0 -9
  100. data/lib/treetop/grammar.rb +0 -7
  101. data/lib/treetop/grammar/grammar.rb +0 -48
  102. data/lib/treetop/grammar/grammar_builder.rb +0 -35
  103. data/lib/treetop/grammar/parsing_expression_builder.rb +0 -5
  104. data/lib/treetop/grammar/parsing_expression_builder_helper.rb +0 -121
  105. data/lib/treetop/grammar/parsing_expressions.rb +0 -18
  106. data/lib/treetop/grammar/parsing_expressions/and_predicate.rb +0 -17
  107. data/lib/treetop/grammar/parsing_expressions/anything_symbol.rb +0 -20
  108. data/lib/treetop/grammar/parsing_expressions/character_class.rb +0 -24
  109. data/lib/treetop/grammar/parsing_expressions/node_instantiating_parsing_expression.rb +0 -14
  110. data/lib/treetop/grammar/parsing_expressions/node_propagating_parsing_expression.rb +0 -4
  111. data/lib/treetop/grammar/parsing_expressions/nonterminal_symbol.rb +0 -42
  112. data/lib/treetop/grammar/parsing_expressions/not_predicate.rb +0 -18
  113. data/lib/treetop/grammar/parsing_expressions/one_or_more.rb +0 -12
  114. data/lib/treetop/grammar/parsing_expressions/optional.rb +0 -14
  115. data/lib/treetop/grammar/parsing_expressions/ordered_choice.rb +0 -27
  116. data/lib/treetop/grammar/parsing_expressions/parsing_expression.rb +0 -36
  117. data/lib/treetop/grammar/parsing_expressions/predicate.rb +0 -25
  118. data/lib/treetop/grammar/parsing_expressions/repeating_parsing_expression.rb +0 -29
  119. data/lib/treetop/grammar/parsing_expressions/sequence.rb +0 -41
  120. data/lib/treetop/grammar/parsing_expressions/terminal_parsing_expression.rb +0 -11
  121. data/lib/treetop/grammar/parsing_expressions/terminal_symbol.rb +0 -31
  122. data/lib/treetop/grammar/parsing_expressions/zero_or_more.rb +0 -11
  123. data/lib/treetop/grammar/parsing_rule.rb +0 -10
  124. data/lib/treetop/metagrammar.rb +0 -2
  125. data/lib/treetop/metagrammar/metagrammar.rb +0 -14
  126. data/lib/treetop/metagrammar/metagrammar.treetop +0 -320
  127. data/lib/treetop/parser.rb +0 -11
  128. data/lib/treetop/parser/node_cache.rb +0 -25
  129. data/lib/treetop/parser/parse_cache.rb +0 -17
  130. data/lib/treetop/parser/parse_failure.rb +0 -22
  131. data/lib/treetop/parser/parse_result.rb +0 -26
  132. data/lib/treetop/parser/parser.rb +0 -24
  133. data/lib/treetop/parser/sequence_syntax_node.rb +0 -14
  134. data/lib/treetop/parser/syntax_node.rb +0 -31
  135. data/lib/treetop/parser/terminal_parse_failure.rb +0 -18
  136. data/lib/treetop/parser/terminal_syntax_node.rb +0 -7
  137. data/lib/treetop/protometagrammar.rb +0 -16
  138. data/lib/treetop/protometagrammar/anything_symbol_expression_builder.rb +0 -13
  139. data/lib/treetop/protometagrammar/block_expression_builder.rb +0 -17
  140. data/lib/treetop/protometagrammar/character_class_expression_builder.rb +0 -25
  141. data/lib/treetop/protometagrammar/grammar_expression_builder.rb +0 -38
  142. data/lib/treetop/protometagrammar/nonterminal_symbol_expression_builder.rb +0 -45
  143. data/lib/treetop/protometagrammar/ordered_choice_expression_builder.rb +0 -21
  144. data/lib/treetop/protometagrammar/parsing_rule_expression_builder.rb +0 -23
  145. data/lib/treetop/protometagrammar/parsing_rule_sequence_expression_builder.rb +0 -14
  146. data/lib/treetop/protometagrammar/prefix_expression_builder.rb +0 -25
  147. data/lib/treetop/protometagrammar/primary_expression_builder.rb +0 -71
  148. data/lib/treetop/protometagrammar/protometagrammar.rb +0 -25
  149. data/lib/treetop/protometagrammar/sequence_expression_builder.rb +0 -37
  150. data/lib/treetop/protometagrammar/suffix_expression_builder.rb +0 -33
  151. data/lib/treetop/protometagrammar/terminal_symbol_expression_builder.rb +0 -52
  152. data/lib/treetop/protometagrammar/trailing_block_expression_builder.rb +0 -30
  153. data/lib/treetop/ruby_extension.rb +0 -11
@@ -0,0 +1,384 @@
1
+ module Treetop
2
+ module Compiler
3
+ grammar Metagrammar
4
+ rule treetop_file
5
+ prefix:space? module_or_grammar:(module_declaration / grammar) suffix:space? {
6
+ def compile
7
+ prefix.text_value + module_or_grammar.compile + suffix.text_value
8
+ end
9
+ }
10
+ end
11
+
12
+ rule module_declaration
13
+ prefix:('module' space [A-Z] alphanumeric_char* space) module_contents:(module_declaration / grammar) suffix:(space 'end') {
14
+ def compile
15
+ prefix.text_value + module_contents.compile + suffix.text_value
16
+ end
17
+ }
18
+ end
19
+
20
+ rule grammar
21
+ 'grammar' space grammar_name space declaration_sequence space? 'end' <Grammar>
22
+ end
23
+
24
+ rule grammar_name
25
+ ([A-Z] alphanumeric_char*)
26
+ end
27
+
28
+ rule declaration_sequence
29
+ head:declaration tail:(space declaration)* <DeclarationSequence> {
30
+ def declarations
31
+ [head] + tail
32
+ end
33
+
34
+ def tail
35
+ super.elements.map { |elt| elt.declaration }
36
+ end
37
+ }
38
+ /
39
+ '' {
40
+ def compile(builder)
41
+ end
42
+ }
43
+ end
44
+
45
+ rule declaration
46
+ parsing_rule / include_declaration
47
+ end
48
+
49
+ rule include_declaration
50
+ 'include' space [A-Z] alphanumeric_char* {
51
+ def compile(builder)
52
+ builder << text_value
53
+ end
54
+ }
55
+ end
56
+
57
+ rule parsing_rule
58
+ 'rule' space nonterminal space parsing_expression space 'end' <ParsingRule>
59
+ end
60
+
61
+ rule parsing_expression
62
+ choice / sequence / primary
63
+ end
64
+
65
+ rule choice
66
+ head:alternative tail:(space? '/' space? alternative)+ <Choice> {
67
+ def alternatives
68
+ [head] + tail
69
+ end
70
+
71
+ def tail
72
+ super.elements.map {|elt| elt.alternative}
73
+ end
74
+
75
+ def inline_modules
76
+ (alternatives.map {|alt| alt.inline_modules }).flatten
77
+ end
78
+ }
79
+ end
80
+
81
+ rule sequence
82
+ head:labeled_sequence_primary tail:(space labeled_sequence_primary)+ node_class_declarations <Sequence> {
83
+ def sequence_elements
84
+ [head] + tail
85
+ end
86
+
87
+ def tail
88
+ super.elements.map {|elt| elt.labeled_sequence_primary }
89
+ end
90
+
91
+ def inline_modules
92
+ (sequence_elements.map {|elt| elt.inline_modules}).flatten +
93
+ [sequence_element_accessor_module] +
94
+ node_class_declarations.inline_modules
95
+ end
96
+
97
+ def inline_module_name
98
+ node_class_declarations.inline_module_name
99
+ end
100
+ }
101
+ end
102
+
103
+ rule alternative
104
+ sequence / primary
105
+ end
106
+
107
+ rule primary
108
+ prefix atomic {
109
+ def compile(address, builder)
110
+ prefix.compile(address, builder, self)
111
+ end
112
+
113
+ def predicated_expression
114
+ atomic
115
+ end
116
+
117
+ def inline_modules
118
+ atomic.inline_modules
119
+ end
120
+
121
+ def inline_module_name
122
+ nil
123
+ end
124
+ }
125
+ /
126
+ atomic suffix node_class_declarations {
127
+ def compile(address, builder)
128
+ suffix.compile(address, builder, self)
129
+ end
130
+
131
+ def optional_expression
132
+ atomic
133
+ end
134
+
135
+ def node_class
136
+ node_class_declarations.node_class
137
+ end
138
+
139
+ def inline_modules
140
+ atomic.inline_modules + node_class_declarations.inline_modules
141
+ end
142
+
143
+ def inline_module_name
144
+ node_class_declarations.inline_module_name
145
+ end
146
+ }
147
+ /
148
+ atomic node_class_declarations {
149
+ def compile(address, builder)
150
+ atomic.compile(address, builder, self)
151
+ end
152
+
153
+ def node_class
154
+ node_class_declarations.node_class
155
+ end
156
+
157
+ def inline_modules
158
+ atomic.inline_modules + node_class_declarations.inline_modules
159
+ end
160
+
161
+ def inline_module_name
162
+ node_class_declarations.inline_module_name
163
+ end
164
+ }
165
+ end
166
+
167
+ rule labeled_sequence_primary
168
+ label sequence_primary {
169
+ def compile(lexical_address, builder)
170
+ sequence_primary.compile(lexical_address, builder)
171
+ end
172
+
173
+ def inline_modules
174
+ sequence_primary.inline_modules
175
+ end
176
+
177
+ def label_name
178
+ if label.name
179
+ label.name
180
+ elsif sequence_primary.instance_of?(Nonterminal)
181
+ sequence_primary.text_value
182
+ else
183
+ nil
184
+ end
185
+ end
186
+ }
187
+ end
188
+
189
+ rule label
190
+ (alpha_char alphanumeric_char*) ':' {
191
+ def name
192
+ elements[0].text_value
193
+ end
194
+ }
195
+ /
196
+ '' {
197
+ def name
198
+ nil
199
+ end
200
+ }
201
+ end
202
+
203
+ rule sequence_primary
204
+ prefix atomic {
205
+ def compile(lexical_address, builder)
206
+ prefix.compile(lexical_address, builder, self)
207
+ end
208
+
209
+ def predicated_expression
210
+ elements[1]
211
+ end
212
+
213
+ def inline_modules
214
+ atomic.inline_modules
215
+ end
216
+
217
+ def inline_module_name
218
+ nil
219
+ end
220
+ }
221
+ /
222
+ atomic suffix {
223
+ def compile(lexical_address, builder)
224
+ suffix.compile(lexical_address, builder, self)
225
+ end
226
+
227
+ def node_class
228
+ 'SyntaxNode'
229
+ end
230
+
231
+ def inline_modules
232
+ atomic.inline_modules
233
+ end
234
+
235
+ def inline_module_name
236
+ nil
237
+ end
238
+ }
239
+ /
240
+ atomic
241
+ end
242
+
243
+ rule suffix
244
+ repetition_suffix / optional_suffix
245
+ end
246
+
247
+ rule optional_suffix
248
+ '?' <Optional>
249
+ end
250
+
251
+ rule node_class_declarations
252
+ node_class_expression trailing_inline_module {
253
+ def node_class
254
+ node_class_expression.node_class
255
+ end
256
+
257
+ def inline_modules
258
+ trailing_inline_module.inline_modules
259
+ end
260
+
261
+ def inline_module
262
+ trailing_inline_module.inline_module
263
+ end
264
+
265
+ def inline_module_name
266
+ inline_module.module_name if inline_module
267
+ end
268
+ }
269
+ end
270
+
271
+ rule repetition_suffix
272
+ '+' <OneOrMore> / '*' <ZeroOrMore>
273
+ end
274
+
275
+ rule prefix
276
+ '&' <AndPredicate> / '!' <NotPredicate>
277
+ end
278
+
279
+ rule atomic
280
+ terminal
281
+ /
282
+ nonterminal
283
+ /
284
+ parenthesized_expression
285
+ end
286
+
287
+ rule parenthesized_expression
288
+ '(' space? parsing_expression space? ')' <ParenthesizedExpression> {
289
+ def inline_modules
290
+ parsing_expression.inline_modules
291
+ end
292
+ }
293
+ end
294
+
295
+ rule nonterminal
296
+ !keyword_inside_grammar (alpha_char alphanumeric_char*) <Nonterminal>
297
+ end
298
+
299
+ rule terminal
300
+ single_quoted_string / double_quoted_string / character_class / anything_symbol
301
+ end
302
+
303
+ rule double_quoted_string
304
+ '"' (!'"' ("\\\\" / '\"' / .))* '"' <Terminal>
305
+ end
306
+
307
+ rule single_quoted_string
308
+ "'" (!"'" ("\\\\" / "\\'" / .))* "'" <Terminal>
309
+ end
310
+
311
+ rule character_class
312
+ '[' (!']' ('\]'/.))+ ']' <CharacterClass>
313
+ end
314
+
315
+ rule anything_symbol
316
+ '.' <AnythingSymbol>
317
+ end
318
+
319
+ rule node_class_expression
320
+ space '<' (!'>' .)+ '>' {
321
+ def node_class
322
+ elements[2].text_value
323
+ end
324
+ }
325
+ /
326
+ '' {
327
+ def node_class
328
+ 'SyntaxNode'
329
+ end
330
+ }
331
+ end
332
+
333
+ rule trailing_inline_module
334
+ space inline_module {
335
+ def inline_modules
336
+ [inline_module]
337
+ end
338
+
339
+ def inline_module_name
340
+ inline_module.module_name
341
+ end
342
+ }
343
+ /
344
+ '' {
345
+ def inline_modules
346
+ []
347
+ end
348
+
349
+ def inline_module
350
+ nil
351
+ end
352
+
353
+ def inline_module_name
354
+ nil
355
+ end
356
+ }
357
+ end
358
+
359
+ rule inline_module
360
+ '{' (inline_module / ![{}] .)* '}' <InlineModule>
361
+ end
362
+
363
+ rule keyword_inside_grammar
364
+ ('rule' / 'end') !non_space_char
365
+ end
366
+
367
+ rule non_space_char
368
+ !space .
369
+ end
370
+
371
+ rule alpha_char
372
+ [A-Za-z_]
373
+ end
374
+
375
+ rule alphanumeric_char
376
+ alpha_char / [0-9]
377
+ end
378
+
379
+ rule space
380
+ [ \t\n\r]+
381
+ end
382
+ end
383
+ end
384
+ end
@@ -0,0 +1,18 @@
1
+ dir = File.dirname(__FILE__)
2
+ require File.join(dir, *%w[node_classes parsing_expression])
3
+ require File.join(dir, *%w[node_classes atomic_expression])
4
+ require File.join(dir, *%w[node_classes inline_module])
5
+ require File.join(dir, *%w[node_classes treetop_file])
6
+ require File.join(dir, *%w[node_classes grammar])
7
+ require File.join(dir, *%w[node_classes declaration_sequence])
8
+ require File.join(dir, *%w[node_classes parsing_rule])
9
+ require File.join(dir, *%w[node_classes parenthesized_expression])
10
+ require File.join(dir, *%w[node_classes nonterminal])
11
+ require File.join(dir, *%w[node_classes terminal])
12
+ require File.join(dir, *%w[node_classes anything_symbol])
13
+ require File.join(dir, *%w[node_classes character_class])
14
+ require File.join(dir, *%w[node_classes sequence])
15
+ require File.join(dir, *%w[node_classes choice])
16
+ require File.join(dir, *%w[node_classes repetition])
17
+ require File.join(dir, *%w[node_classes optional])
18
+ require File.join(dir, *%w[node_classes predicate])
@@ -0,0 +1,10 @@
1
+ module Treetop
2
+ module Compiler
3
+ class AnythingSymbol < AtomicExpression
4
+ def compile(address, builder, parent_expression = nil)
5
+ super
6
+ assign_result "parse_anything(#{node_class}#{optional_arg(inline_module_name)})"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Treetop
2
+ module Compiler
3
+ class AtomicExpression < ParsingExpression
4
+ def inline_modules
5
+ []
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Treetop
2
+ module Compiler
3
+ class CharacterClass < AtomicExpression
4
+ def compile(address, builder, parent_expression = nil)
5
+ super
6
+ assign_result "parse_char_class(/#{text_value}/, '#{elements[1].text_value.gsub(/'$/, "\\\\'")}', #{node_class}#{optional_arg(inline_module_name)})"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ module Treetop
2
+ module Compiler
3
+ class Choice < ParsingExpression
4
+ def compile(address, builder, parent_expression = nil)
5
+ super
6
+ begin_comment(self)
7
+ use_vars :result, :start_index, :nested_results
8
+ compile_alternatives(alternatives)
9
+ end_comment(self)
10
+ end
11
+
12
+ def compile_alternatives(alternatives)
13
+ obtain_new_subexpression_address
14
+ alternatives.first.compile(subexpression_address, builder)
15
+ accumulate_nested_result
16
+ builder.if__ subexpression_success? do
17
+ assign_result subexpression_result_var
18
+ builder << "#{subexpression_result_var}.update_nested_results(#{nested_results_var})"
19
+ end
20
+ builder.else_ do
21
+ if alternatives.size == 1
22
+ reset_index
23
+ assign_failure start_index_var, nested_results_var
24
+ else
25
+ compile_alternatives(alternatives[1..-1])
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end