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,33 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class GrammarTest < CompilerTestCase
4
+ module Bar
5
+ end
6
+
7
+ testing_grammar %{
8
+ grammar Foo
9
+ include Bar
10
+
11
+ rule foo
12
+ bar / baz
13
+ end
14
+
15
+ rule bar
16
+ 'bar' 'bar'
17
+ end
18
+
19
+ rule baz
20
+ 'baz' 'baz'
21
+ end
22
+ end
23
+ }
24
+
25
+ it "parses matching input" do
26
+ parse('barbar').should be_success
27
+ parse('bazbaz').should be_success
28
+ end
29
+
30
+ it "mixes in included modules" do
31
+ Foo.ancestors.should include(Bar)
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ describe "A nonterminal symbol", :extend => CompilerTestCase do
4
+ testing_expression 'foo'
5
+
6
+ parser_class_under_test.class_eval do
7
+ def _nt_foo
8
+ '_nt_foo called'
9
+ end
10
+ end
11
+
12
+ it "compiles to a message send" do
13
+ parse('').should == '_nt_foo called'
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ describe "A !-predicated terminal symbol", :extend => CompilerTestCase do
4
+ testing_expression '!"foo"'
5
+
6
+ it "fails to parse input matching the terminal symbol" do
7
+ parse('foo').should be_failure
8
+ end
9
+ end
10
+
11
+ describe "A sequence of a terminal and an and another !-predicated terminal", :extend => CompilerTestCase do
12
+ testing_expression '"foo" !"bar"'
13
+
14
+ it "fails to match input matching both terminals" do
15
+ parse('foobar').should be_failure
16
+ end
17
+
18
+ it "successfully parses input matching the first terminal and not the second, with the failure of the second as a nested failure" do
19
+ parse('foo') do |result|
20
+ result.should be_success
21
+ result.nested_failures.size.should == 1
22
+ nested_failure = result.nested_failures[0]
23
+ nested_failure.index.should == 3
24
+ nested_failure.expected_string.should == 'bar'
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "A !-predicated sequence", :extend => CompilerTestCase do
30
+ testing_expression '!("a" "b" "c")'
31
+
32
+ it "fails to parse matching input" do
33
+ parse('abc').should be_failure
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class OneOrMoreOfTerminalTest < CompilerTestCase
4
+ testing_expression '"foo"+ <Foo> { def a_method; end }'
5
+
6
+ class Foo < Treetop::Runtime::SyntaxNode
7
+ end
8
+
9
+ it "fails to parse epsilon with a nested failure" do
10
+ parse('') do |result|
11
+ result.should be_failure
12
+ result.nested_failures.size.should == 1
13
+ nested_failure = result.nested_failures.first
14
+ nested_failure.index.should == 0
15
+ nested_failure.expected_string.should == 'foo'
16
+ end
17
+ end
18
+
19
+ it "successfully parses two of that terminal in a row, returning an instance of the declared node class with a nested failure representing the third attempt" do
20
+ parse("foofoo") do |result|
21
+ result.should be_success
22
+ result.should be_an_instance_of(Foo)
23
+ result.should respond_to(:a_method)
24
+ result.nested_failures.size.should == 1
25
+ nested_failure = result.nested_failures.first
26
+ nested_failure.index.should == 6
27
+ nested_failure.expected_string.should == 'foo'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ describe "An optional terminal symbol", :extend => CompilerTestCase do
4
+ testing_expression '"foo"?'
5
+
6
+ it "parses input matching the terminal" do
7
+ parse('foo').should be_success
8
+ end
9
+
10
+ it "parses epsilon, with a nested failure" do
11
+ parse('') do |result|
12
+ result.should be_success
13
+ result.interval.should == (0...0)
14
+ result.nested_failures.size.should == 1
15
+ nested_failure = result.nested_failures.first
16
+ nested_failure.index.should == 0
17
+ nested_failure.expected_string.should == 'foo'
18
+ end
19
+ end
20
+
21
+ it "parses input not matching the terminal, returning an epsilon result with a nested failure" do
22
+ parse('bar') do |result|
23
+ result.should be_success
24
+ result.interval.should == (0...0)
25
+ result.nested_failures.size.should == 1
26
+ nested_failure = result.nested_failures.first
27
+ nested_failure.index.should == 0
28
+ nested_failure.expected_string.should == 'foo'
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ParsingRuleTest < CompilerTestCase
4
+
5
+ testing_grammar %{
6
+ grammar Foo
7
+ rule bar
8
+ "baz"
9
+ end
10
+ end
11
+ }
12
+
13
+ test "node cache storage and retrieval" do
14
+ parser = FooParser.new
15
+ parser.send(:prepare_to_parse, 'baz')
16
+ node_cache = parser.send(:node_cache)
17
+
18
+ node_cache[:bar][0].should be_nil
19
+
20
+ parser._nt_bar
21
+
22
+ cached_node = node_cache[:bar][0]
23
+ cached_node.should be_an_instance_of(Runtime::SyntaxNode)
24
+ cached_node.text_value.should == 'baz'
25
+
26
+ parser.instance_eval { @index = 0 }
27
+ parser._nt_bar.should equal(cached_node)
28
+ parser.index.should == cached_node.interval.end
29
+ end
30
+ end
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class SequenceOfTerminalsTest < CompilerTestCase
4
+
5
+ class Foo < Treetop::Runtime::SyntaxNode
6
+ end
7
+
8
+ testing_expression 'foo:"foo" bar:"bar" baz:"baz" <Foo> { def a_method; end }'
9
+
10
+ test "successful result is an instance of the declared node class with element accessor methods and the method from the inline module" do
11
+ parse('foobarbaz') do |result|
12
+ result.should be_success
13
+ result.should be_an_instance_of(Foo)
14
+ result.should respond_to(:a_method)
15
+ result.foo.text_value.should == 'foo'
16
+ result.bar.text_value.should == 'bar'
17
+ result.baz.text_value.should == 'baz'
18
+ end
19
+ end
20
+
21
+ test "matching at a non-zero index" do
22
+ parse('---foobarbaz', :at_index => 3) do |result|
23
+ result.should be_success
24
+ result.should be_nonterminal
25
+ (result.elements.map {|elt| elt.text_value}).join.should == 'foobarbaz'
26
+ end
27
+ end
28
+
29
+ test "non-matching input fails with a nested failure at the first terminal that did not match" do
30
+ parse('---foobazbaz', :at_index => 3) do |result|
31
+ result.should be_failure
32
+ result.index.should == 3
33
+ result.nested_failures.size.should == 1
34
+ nested_failure = result.nested_failures.first
35
+ nested_failure.index.should == 6
36
+ nested_failure.expected_string.should == 'bar'
37
+ end
38
+ end
39
+ end
40
+
41
+ class SequenceOfNonterminalsTest < CompilerTestCase
42
+
43
+ testing_grammar %{
44
+ grammar TestGrammar
45
+ rule sequence
46
+ foo bar baz {
47
+ def baz
48
+ 'override' + super.text_value
49
+ end
50
+ }
51
+ end
52
+
53
+ rule foo 'foo' end
54
+ rule bar 'bar' end
55
+ rule baz 'baz' end
56
+ end
57
+ }
58
+
59
+ test "accessors for nonterminals are automatically defined and can be overridden in the inline block" do
60
+ parse('foobarbaz') do |result|
61
+ result.foo.text_value.should == 'foo'
62
+ result.bar.text_value.should == 'bar'
63
+ result.baz.should == 'overridebaz'
64
+ end
65
+
66
+
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TerminalSymbolTest < CompilerTestCase
4
+ class Foo < Treetop::Runtime::SyntaxNode
5
+ end
6
+
7
+ testing_expression "'foo' <Foo> { def a_method; end }"
8
+
9
+ it "correctly parses matching input prefixes at various indices, returning an instance of the declared class that can respond to methods defined in the inline module" do
10
+ parse "foo", :at_index => 0 do |result|
11
+ result.should be_an_instance_of(Foo)
12
+ result.should respond_to(:a_method)
13
+ result.interval.should == (0...3)
14
+ result.text_value.should == 'foo'
15
+ end
16
+
17
+ parse "xfoo", :at_index => 1 do |result|
18
+ result.should be_an_instance_of(Foo)
19
+ result.should respond_to(:a_method)
20
+ result.interval.should == (1...4)
21
+ result.text_value.should == 'foo'
22
+ end
23
+
24
+ parse "---foo", :at_index => 3 do |result|
25
+ result.should be_an_instance_of(Foo)
26
+ result.should respond_to(:a_method)
27
+ result.interval.should == (3...6)
28
+ result.text_value.should == 'foo'
29
+ end
30
+ end
31
+
32
+ it "fails to parse nonmatching input at the index even if a match occurs later" do
33
+ parse(" foo", :at_index => 0).should be_failure
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module Test
2
+ grammar Grammar
3
+ rule foo
4
+ 'foo'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ZeroOrMoreOfATerminalWithNodeClassDeclarationTest < CompilerTestCase
4
+
5
+ class Foo < Treetop::Runtime::SyntaxNode
6
+ end
7
+
8
+ testing_expression '"foo"* <Foo> { def a_method; end }'
9
+
10
+ it "successfully parses epsilon, returning an instance declared node class with a nested failure" do
11
+ parse('') do |result|
12
+ result.should be_success
13
+ result.should be_an_instance_of(Foo)
14
+ result.should respond_to(:a_method)
15
+ result.nested_failures.size.should == 1
16
+ nested_failure = result.nested_failures.first
17
+ nested_failure.index.should == 0
18
+ nested_failure.expected_string.should == 'foo'
19
+ end
20
+ end
21
+
22
+ it "successfully parses two of that terminal in a row, returning an instance of the declared node class with a nested failure representing the third attempt " do
23
+ parse("foofoo") do |result|
24
+ result.should be_success
25
+ result.should be_an_instance_of(Foo)
26
+ result.nested_failures.size.should == 1
27
+ nested_failure = result.nested_failures.first
28
+ nested_failure.index.should == 6
29
+ nested_failure.expected_string.should == 'foo'
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "Zero or more of a sequence", :extend => CompilerTestCase do
35
+ testing_expression '("foo" "bar")*'
36
+
37
+ it "resets the index appropriately following partially matcing input" do
38
+ parse('foobarfoo') do |result|
39
+ result.should be_success
40
+ result.interval.should == (0...6)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "Zero or more of a choice", :extend => CompilerTestCase do
46
+ testing_expression '("a" / "b")*'
47
+
48
+ it "successfully parses matching input" do
49
+ parse('abba').should be_success
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ module Test
2
+ grammar A
3
+ rule a
4
+ 'a'
5
+ end
6
+
7
+ rule inherit
8
+ 'super'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Test
2
+ grammar B
3
+ rule b
4
+ 'b'
5
+ end
6
+
7
+ rule inherit
8
+ super 'keyword'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Test
2
+ grammar C
3
+ include A
4
+ include B
5
+
6
+ rule c
7
+ a b 'c'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Test
2
+ grammar D
3
+ include A
4
+ include B
5
+
6
+ rule inherit
7
+ super 'works'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ dir = File.dirname(__FILE__)
2
+ require File.join(dir, '..', 'test_helper')
3
+
4
+ class GrammarCompositionTest < Screw::Unit::TestCase
5
+ def setup
6
+ dir = File.dirname(__FILE__)
7
+ load_grammar File.join(dir, 'a')
8
+ load_grammar File.join(dir, 'b')
9
+ load_grammar File.join(dir, 'c')
10
+ load_grammar File.join(dir, 'd')
11
+
12
+ @c = ::Test::CParser.new
13
+ @d = ::Test::DParser.new
14
+ end
15
+
16
+ test "rules in C have access to rules defined in A and B" do
17
+ @c.parse('abc').should be_success
18
+ end
19
+
20
+ test "rules in C can override rules in A and B with super semantics" do
21
+ @d.parse('superkeywordworks').should be_success
22
+ end
23
+ end
@@ -0,0 +1,53 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/../test_helper"
3
+
4
+ describe "A new terminal syntax node" do
5
+
6
+ def setup
7
+ @node = Runtime::SyntaxNode.new("input", 0...3)
8
+ end
9
+
10
+ it "reports itself as terminal" do
11
+ @node.should be_terminal
12
+ @node.should_not be_nonterminal
13
+ end
14
+
15
+ it "has a text value based on the input and the interval" do
16
+ @node.text_value.should == "inp"
17
+ end
18
+
19
+ it "has no nested failures" do
20
+ @node.nested_failures.should be_empty
21
+ end
22
+
23
+ it "has itself as its only element" do
24
+ @node.elements.should == [@node]
25
+ end
26
+ end
27
+
28
+ describe "A new nonterminal syntax node" do
29
+ def setup
30
+ @input = 'test input'
31
+ @nested_results = [Runtime::TerminalParseFailure.new(@input, 1, 'foo')]
32
+ @elements = Runtime::SyntaxNode.new('input', 0...3)
33
+ @node = Runtime::SyntaxNode.new('input', 0...3, @elements, @nested_results)
34
+ end
35
+
36
+ it "reports itself as nonterminal" do
37
+ @node.should be_nonterminal
38
+ @node.should_not be_terminal
39
+ end
40
+
41
+ it "has a text value based on the input and the interval" do
42
+ @node.text_value.should == "inp"
43
+ end
44
+
45
+ it "has the elements with which it was instantiated" do
46
+ @node.elements.should == @elements
47
+ end
48
+
49
+ it "has nested failures frow within the nested results with which it was instantiated" do
50
+ @node.nested_failures.should == @nested_results
51
+ end
52
+
53
+ end