treetop 1.6.6 → 1.6.11

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +18 -0
  3. data/History.txt +18 -0
  4. data/README.md +2 -0
  5. data/Rakefile +10 -43
  6. data/Treetop.tmbundle/Preferences/Comments.tmPreferences +28 -0
  7. data/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
  8. data/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
  9. data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/designable.nib +1524 -0
  10. data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/keyedobjects.nib +0 -0
  11. data/Treetop.tmbundle/Support/syntax_tree_viewer.rb +117 -0
  12. data/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +358 -0
  13. data/Treetop.tmbundle/info.plist +10 -0
  14. data/doc/pitfalls_and_advanced_techniques.markdown +6 -0
  15. data/doc/syntactic_recognition.markdown +2 -2
  16. data/lib/treetop/compiler/grammar_compiler.rb +6 -3
  17. data/lib/treetop/compiler/metagrammar.rb +97 -77
  18. data/lib/treetop/compiler/metagrammar.treetop +1 -1
  19. data/lib/treetop/compiler/ruby_builder.rb +2 -2
  20. data/lib/treetop/ruby_extensions/string.rb +0 -6
  21. data/lib/treetop/runtime/compiled_parser.rb +15 -2
  22. data/lib/treetop/version.rb +1 -1
  23. data/treetop.gemspec +25 -157
  24. metadata +15 -61
  25. data/doc/site.rb +0 -112
  26. data/doc/sitegen.rb +0 -65
  27. data/spec/compiler/and_predicate_spec.rb +0 -36
  28. data/spec/compiler/anything_symbol_spec.rb +0 -47
  29. data/spec/compiler/character_class_spec.rb +0 -304
  30. data/spec/compiler/choice_spec.rb +0 -89
  31. data/spec/compiler/circular_compilation_spec.rb +0 -30
  32. data/spec/compiler/failure_propagation_functional_spec.rb +0 -21
  33. data/spec/compiler/grammar_compiler_spec.rb +0 -113
  34. data/spec/compiler/grammar_spec.rb +0 -44
  35. data/spec/compiler/multibyte_chars_spec.rb +0 -38
  36. data/spec/compiler/namespace_spec.rb +0 -42
  37. data/spec/compiler/nonterminal_symbol_spec.rb +0 -40
  38. data/spec/compiler/not_predicate_spec.rb +0 -52
  39. data/spec/compiler/occurrence_range_spec.rb +0 -186
  40. data/spec/compiler/one_or_more_spec.rb +0 -35
  41. data/spec/compiler/optional_spec.rb +0 -37
  42. data/spec/compiler/parenthesized_expression_spec.rb +0 -34
  43. data/spec/compiler/parsing_rule_spec.rb +0 -61
  44. data/spec/compiler/repeated_subrule_spec.rb +0 -29
  45. data/spec/compiler/semantic_predicate_spec.rb +0 -176
  46. data/spec/compiler/sequence_spec.rb +0 -129
  47. data/spec/compiler/terminal_spec.rb +0 -177
  48. data/spec/compiler/terminal_symbol_spec.rb +0 -40
  49. data/spec/compiler/test_grammar.treetop +0 -7
  50. data/spec/compiler/test_grammar.tt +0 -7
  51. data/spec/compiler/test_grammar_do.treetop +0 -7
  52. data/spec/compiler/test_grammar_magic_coding.treetop +0 -8
  53. data/spec/compiler/test_grammar_magic_encoding.treetop +0 -8
  54. data/spec/compiler/tt_compiler_spec.rb +0 -224
  55. data/spec/compiler/zero_or_more_spec.rb +0 -58
  56. data/spec/composition/a.treetop +0 -11
  57. data/spec/composition/b.treetop +0 -11
  58. data/spec/composition/c.treetop +0 -10
  59. data/spec/composition/d.treetop +0 -10
  60. data/spec/composition/f.treetop +0 -17
  61. data/spec/composition/grammar_composition_spec.rb +0 -40
  62. data/spec/composition/subfolder/e_includes_c.treetop +0 -15
  63. data/spec/ruby_extensions/string_spec.rb +0 -32
  64. data/spec/runtime/compiled_parser_spec.rb +0 -153
  65. data/spec/runtime/syntax_node_spec.rb +0 -77
  66. data/spec/spec_helper.rb +0 -123
@@ -1,186 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module OccurrenceRangeSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "zero to two of a terminal symbol followed by a node class declaration and a block" do
8
- testing_expression '"foo"..2 <OccurrenceRangeSpec::Foo> { def a_method; end }'
9
-
10
- it "successfully parses epsilon, reporting a failure" do
11
- parse('') do |result|
12
- result.should_not be_nil
13
- result.should be_an_instance_of(Foo)
14
- result.should respond_to(:a_method)
15
-
16
- terminal_failures = parser.terminal_failures
17
- terminal_failures.size.should == 0
18
- end
19
- end
20
-
21
- it "successfully parses epsilon, returning an instance declared node class and recording a terminal failure" do
22
- parse('') do |result|
23
- result.should_not be_nil
24
- result.should be_an_instance_of(Foo)
25
- result.should respond_to(:a_method)
26
-
27
- terminal_failures = parser.terminal_failures
28
- terminal_failures.size.should == 0
29
- end
30
- end
31
-
32
- it "successfully parses one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
33
- parse("foo") do |result|
34
- result.should_not be_nil
35
- result.should be_an_instance_of(Foo)
36
- result.should respond_to(:a_method)
37
-
38
- terminal_failures = parser.terminal_failures
39
- terminal_failures.size.should == 0
40
- end
41
- end
42
-
43
- it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
44
- parse("foofoo") do |result|
45
- result.should_not be_nil
46
- result.should be_an_instance_of(Foo)
47
- result.should respond_to(:a_method)
48
-
49
- terminal_failures = parser.terminal_failures
50
- terminal_failures.size.should == 0
51
- end
52
- end
53
-
54
- it "fails to parses two of that terminal but fails because of an extra one" do
55
- parse("foofoofoo") do |result|
56
- result.should be_nil
57
-
58
- parser.terminal_failures.size.should == 1
59
- end
60
- end
61
-
62
- it "parses two of three of that terminal, reporting no failure" do
63
- parse("foofoofoo", :consume_all_input => false) do |result|
64
- result.should_not be_nil
65
- result.elements.size.should == 2
66
-
67
- parser.terminal_failures.size.should == 0
68
- end
69
- end
70
-
71
- end
72
-
73
- describe "two to four of a terminal symbol followed by a node class declaration and a block" do
74
- testing_expression '"foo" 2..4 <OccurrenceRangeSpec::Foo> { def a_method; end }'
75
-
76
- it "fails to parse epsilon, reporting a failure" do
77
- parse('') do |result|
78
- result.should be_nil
79
- terminal_failures = parser.terminal_failures
80
- terminal_failures.size.should == 1
81
- failure = terminal_failures.first
82
- failure.index.should == 0
83
- failure.expected_string.should == '"foo"'
84
- end
85
- end
86
-
87
- it "fails to parse one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
88
- parse("foo") do |result|
89
- result.should be_nil
90
-
91
- terminal_failures = parser.terminal_failures
92
- terminal_failures.size.should == 1
93
- failure = terminal_failures.first
94
- failure.index.should == 3
95
- failure.expected_string.should == '"foo"'
96
- end
97
- end
98
-
99
- it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
100
- parse("foofoo") do |result|
101
- result.should_not be_nil
102
- result.should be_an_instance_of(Foo)
103
- result.should respond_to(:a_method)
104
-
105
- terminal_failures = parser.terminal_failures
106
- terminal_failures.size.should == 0
107
- end
108
- end
109
-
110
- it "successfully parses four of that terminal, returning an instance of the declared node class and reporting no failure" do
111
- parse("foofoofoofoo") do |result|
112
- result.should_not be_nil
113
- result.should be_an_instance_of(Foo)
114
- result.should respond_to(:a_method)
115
-
116
- terminal_failures = parser.terminal_failures
117
- terminal_failures.size.should == 0
118
- end
119
- end
120
-
121
- it "fails to parses four of that terminal because there's an extra unconsumed one" do
122
- parse("foofoofoofoofoo") do |result|
123
- result.should be_nil
124
-
125
- terminal_failures = parser.terminal_failures
126
- terminal_failures.size.should == 1
127
- end
128
- end
129
- end
130
-
131
- describe "two to any number of a terminal symbol followed by a node class declaration and a block" do
132
- testing_expression '"foo" 2.. <OccurrenceRangeSpec::Foo> { def a_method; end }'
133
-
134
- it "fails to parse epsilon, reporting a failure" do
135
- parse('') do |result|
136
- result.should be_nil
137
- terminal_failures = parser.terminal_failures
138
- terminal_failures.size.should == 1
139
- failure = terminal_failures.first
140
- failure.index.should == 0
141
- failure.expected_string.should == '"foo"'
142
- end
143
- end
144
-
145
- it "fails to parse one of that terminal, returning an instance of the declared node class and recording a terminal failure" do
146
- parse("foo") do |result|
147
- result.should be_nil
148
-
149
- terminal_failures = parser.terminal_failures
150
- terminal_failures.size.should == 1
151
- failure = terminal_failures.first
152
- failure.index.should == 3
153
- failure.expected_string.should == '"foo"'
154
- end
155
- end
156
-
157
- it "successfully parses two of that terminal, returning an instance of the declared node class and reporting no failure" do
158
- parse("foofoo") do |result|
159
- result.should_not be_nil
160
- result.should be_an_instance_of(Foo)
161
- result.should respond_to(:a_method)
162
-
163
- terminal_failures = parser.terminal_failures
164
- terminal_failures.size.should == 1
165
- failure = terminal_failures.first
166
- failure.index.should == 6
167
- failure.expected_string.should == '"foo"'
168
- end
169
- end
170
-
171
- it "successfully parses four of that terminal, returning an instance of the declared node class and reporting a failure on the fifth" do
172
- parse("foofoofoofoo") do |result|
173
- result.should_not be_nil
174
- result.should be_an_instance_of(Foo)
175
- result.should respond_to(:a_method)
176
-
177
- terminal_failures = parser.terminal_failures
178
- terminal_failures.size.should == 1
179
- failure = terminal_failures.first
180
- failure.index.should == 12
181
- failure.expected_string.should == '"foo"'
182
- end
183
- end
184
- end
185
-
186
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module OneOrMoreSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "one or more of a terminal symbol followed by a node class declaration and a block" do
8
- testing_expression '"foo"+ <OneOrMoreSpec::Foo> { def a_method; end }'
9
-
10
- it "fails to parse epsilon, reporting a failure" do
11
- parse('') do |result|
12
- result.should be_nil
13
- terminal_failures = parser.terminal_failures
14
- terminal_failures.size.should == 1
15
- failure = terminal_failures.first
16
- failure.index.should == 0
17
- failure.expected_string.should == '"foo"'
18
- end
19
- end
20
-
21
- it "successfully parses two of that terminal in a row, returning an instance of the declared node class and reporting the failure the third parsing attempt" do
22
- parse("foofoo") do |result|
23
- result.should_not be_nil
24
- result.should be_an_instance_of(Foo)
25
- result.should respond_to(:a_method)
26
-
27
- terminal_failures = parser.terminal_failures
28
- terminal_failures.size.should == 1
29
- failure = terminal_failures.first
30
- failure.index.should == 6
31
- failure.expected_string.should == '"foo"'
32
- end
33
- end
34
- end
35
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module OptionalSpec
4
- describe "An optional terminal symbol" do
5
- testing_expression '"foo"?'
6
-
7
- it "parses input matching the terminal" do
8
- parse('foo').should_not be_nil
9
- end
10
-
11
- it "parses epsilon, recording a failure" do
12
- parse('') do |result|
13
- result.should_not be_nil
14
- result.interval.should == (0...0)
15
-
16
- terminal_failures = parser.terminal_failures
17
- terminal_failures.size.should == 1
18
- failure = terminal_failures.first
19
- failure.index.should == 0
20
- failure.expected_string.should == '"foo"'
21
- end
22
- end
23
-
24
- it "parses input not matching the terminal, returning an epsilon result and recording a failure" do
25
- parse('bar', :consume_all_input => false) do |result|
26
- result.should_not be_nil
27
- result.interval.should == (0...0)
28
-
29
- terminal_failures = parser.terminal_failures
30
- terminal_failures.size.should == 1
31
- failure = terminal_failures.first
32
- failure.index.should == 0
33
- failure.expected_string.should == '"foo"'
34
- end
35
- end
36
- end
37
- end
@@ -1,34 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ParenthesizedExpressionSpec
4
- describe "An unadorned expression inside of parentheses" do
5
- testing_expression '("foo")'
6
-
7
- it "should behave as normal" do
8
- parse('foo').should_not be_nil
9
- end
10
- end
11
-
12
- describe "A prefixed-expression inside of parentheses" do
13
- testing_expression '(!"foo")'
14
-
15
- it "should behave as normal" do
16
- parse('foo') do |result|
17
- result.should be_nil
18
- parser.terminal_failures.size.should == 1
19
- end
20
- end
21
- end
22
-
23
- describe "An expression with code both inside and outside parentheses" do
24
- testing_expression '("foo" { def inner; end } ) { def outer; end} '
25
- it "should extend both code modules " do
26
- parse('foo') do |result|
27
- skip "Arbitrarily nested modules are not yet compiled"
28
- result.should respond_to(:inner)
29
- result.should respond_to(:outer)
30
- end
31
- end
32
- end
33
-
34
- end
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ParsingRuleSpec
4
- describe "a grammar with one parsing rule" do
5
-
6
- testing_grammar %{
7
- grammar Foo
8
- rule bar
9
- "baz"
10
- end
11
- end
12
- }
13
-
14
- it "stores and retrieves nodes in its node cache" do
15
- parser = self.class.const_get(:FooParser).new
16
- parser.send(:prepare_to_parse, 'baz')
17
- node_cache = parser.send(:node_cache)
18
-
19
- node_cache[:bar][0].should be_nil
20
-
21
- parser._nt_bar
22
-
23
- cached_node = node_cache[:bar][0]
24
- cached_node.should be_an_instance_of(Runtime::SyntaxNode)
25
- cached_node.text_value.should == 'baz'
26
-
27
- parser.instance_eval { @index = 0 }
28
- parser._nt_bar.should equal(cached_node)
29
- parser.index.should == cached_node.interval.end
30
- end
31
- end
32
-
33
-
34
- describe "a grammar with choice that uses the cache and has a subsequent expression" do
35
- testing_grammar %{
36
- grammar Logic
37
- rule expression
38
- value_plus
39
- /
40
- value
41
- end
42
-
43
- rule value_plus
44
- value "something else"
45
- end
46
-
47
- rule value
48
- [a-z]
49
- /
50
- "foobar" # the subsequent expression that needs cached.interval.end
51
- end
52
- end
53
- }
54
-
55
- it "parses a single-character value and generates a node from the cache" do
56
- result = parse('a')
57
- result.should be_a(Treetop::Runtime::SyntaxNode)
58
- result.elements.should be_nil
59
- end
60
- end
61
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RepeatedSubruleSpec
4
- describe "a repeated subrule" do
5
- testing_grammar %{
6
- grammar Foo
7
- rule foo
8
- a:'a' space b:'b' space 'cc'
9
- end
10
-
11
- rule space
12
- ' '
13
- end
14
- end
15
- }
16
-
17
- it "should produce a parser having sequence-numbered node accessor methods" do
18
- parse("a b cc") do |result|
19
- result.should_not be_nil
20
- result.should respond_to(:space1)
21
- result.should respond_to(:space2)
22
- result.should_not respond_to(:space)
23
- result.should respond_to(:a)
24
- result.should respond_to(:b)
25
- result.should_not respond_to(:c)
26
- end
27
- end
28
- end
29
- end
@@ -1,176 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module SemanticPredicateSpec
4
- describe "An &-predicate block" do
5
- testing_expression '& {|| $ok_to_succeed}'
6
-
7
- it "succeeds if it returns true, returning an epsilon syntax node" do
8
- $ok_to_succeed = true
9
- parse('foo', :consume_all_input => false) do |result|
10
- result.should_not be_nil
11
- result.interval.should == (0...0)
12
- end
13
- end
14
-
15
- it "fails if it returns false" do
16
- $ok_to_succeed = false
17
- parse('foo', :consume_all_input => false) do |result|
18
- result.should be_nil
19
- terminal_failures = parser.terminal_failures
20
- terminal_failures.size.should == 1
21
- end
22
- end
23
-
24
- end
25
-
26
- describe "A sequence of a terminal and an &-predicate block" do
27
- testing_expression '"prior " &{|s| $value = s[0].text_value; $ok_to_succeed }'
28
-
29
- it "matches the input terminal and consumes it if the block returns true, seeing the terminal in the sequence" do
30
- $ok_to_succeed = true
31
- $value = nil
32
- parse('prior foo', :consume_all_input => false) do |result|
33
- result.should_not be_nil
34
- result.elements[0].text_value.should == "prior "
35
- result.text_value.should == 'prior '
36
- $value.should == 'prior '
37
- end
38
- end
39
-
40
- it "fails if the block returns false, but sees the terminal in the sequence" do
41
- $ok_to_succeed = false
42
- $value = nil
43
- parse('prior foo', :consume_all_input => false) do |result|
44
- result.should be_nil
45
- $value.should == 'prior '
46
- terminal_failures = parser.terminal_failures
47
- terminal_failures.size.should == 1
48
- end
49
- end
50
-
51
- end
52
-
53
- describe "A sequence of an optional terminal and an &-predicate block" do
54
- testing_expression '"prior "? &{|s| $value = s[0].text_value; $ok_to_succeed}'
55
-
56
- it "matches the input terminal and consumes it if the block returns true" do
57
- $ok_to_succeed = true
58
- parse('prior foo', :consume_all_input => false) do |result|
59
- result.should_not be_nil
60
- result.elements[0].text_value.should == "prior "
61
- result.text_value.should == 'prior '
62
- $value.should == 'prior '
63
- end
64
- end
65
-
66
- it "fails with one terminal_failure if the block returns false" do
67
- $ok_to_succeed = false
68
- parse('prior foo', :consume_all_input => false) do |result|
69
- result.should be_nil
70
- $value.should == 'prior '
71
- terminal_failures = parser.terminal_failures
72
- terminal_failures.size.should == 1
73
- end
74
- end
75
-
76
- it "fail and return the expected optional preceeding terminal as expected input if the block returns false" do
77
- $ok_to_succeed = false
78
- parse('foo', :consume_all_input => false) do |result|
79
- result.should be_nil
80
- terminal_failures = parser.terminal_failures
81
- # We should get "prior " failed, and also the predicate block
82
- terminal_failures.size.should == 2
83
- terminal_failures[0].index.should == 0
84
- terminal_failures[0].expected_string.should == '"prior "'
85
- terminal_failures[1].index.should == 0
86
- terminal_failures[1].expected_string.should == '<semantic predicate>'
87
- end
88
- end
89
-
90
- end
91
-
92
- describe "A !-predicate block" do
93
- testing_expression '! {|| $ok_to_succeed}'
94
-
95
- it "succeeds if it returns false, returning an epsilon syntax node" do
96
- $ok_to_succeed = false
97
- parse('foo', :consume_all_input => false) do |result|
98
- result.should_not be_nil
99
- result.interval.should == (0...0)
100
- end
101
- end
102
-
103
- it "fails if it returns true" do
104
- $ok_to_succeed = true
105
- parse('foo', :consume_all_input => false) do |result|
106
- result.should be_nil
107
- terminal_failures = parser.terminal_failures
108
- terminal_failures.size.should == 1
109
- end
110
- end
111
-
112
- end
113
-
114
- describe "A sequence of a terminal and an !-predicate block" do
115
- testing_expression '"prior " !{|s| $value = s[0].text_value; $ok_to_succeed }'
116
-
117
- it "matches the input terminal and consumes it if the block returns false, seeing the terminal in the sequence" do
118
- $ok_to_succeed = false
119
- $value = nil
120
- parse('prior foo', :consume_all_input => false) do |result|
121
- result.should_not be_nil
122
- result.elements[0].text_value.should == "prior "
123
- result.text_value.should == 'prior '
124
- $value.should == 'prior '
125
- end
126
- end
127
-
128
- it "fails if the block returns true, but sees the terminal in the sequence" do
129
- $ok_to_succeed = true
130
- $value = nil
131
- parse('prior foo', :consume_all_input => false) do |result|
132
- result.should be_nil
133
- $value.should == 'prior '
134
- terminal_failures = parser.terminal_failures
135
- terminal_failures.size.should == 1
136
- end
137
- end
138
-
139
- end
140
-
141
- describe "A sequence of an optional terminal and an !-predicate block" do
142
- testing_expression '"prior "? !{|s| $value = s[0].text_value; $ok_to_succeed}'
143
-
144
- it "matches the input terminal and consumes it if the block returns false" do
145
- $ok_to_succeed = false
146
- parse('prior foo', :consume_all_input => false) do |result|
147
- result.should_not be_nil
148
- result.elements[0].text_value.should == "prior "
149
- result.text_value.should == 'prior '
150
- $value.should == 'prior '
151
- end
152
- end
153
-
154
- it "fails with one terminal_failure if the block returns true" do
155
- $ok_to_succeed = true
156
- parse('prior foo', :consume_all_input => false) do |result|
157
- result.should be_nil
158
- $value.should == 'prior '
159
- terminal_failures = parser.terminal_failures
160
- terminal_failures.size.should == 1
161
- end
162
- end
163
-
164
- it "fail and return the expected optional preceeding terminal as expected input if the block returns true" do
165
- $ok_to_succeed = true
166
- parse('foo', :consume_all_input => false) do |result|
167
- result.should be_nil
168
- terminal_failures = parser.terminal_failures
169
- terminal_failures.size.should == 2
170
- terminal_failures[0].index.should == 0
171
- terminal_failures[0].expected_string.should == '"prior "'
172
- end
173
- end
174
-
175
- end
176
- end