treetop 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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