treetop 1.5.3 → 1.6.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +5 -13
  2. data/Gemfile +12 -0
  3. data/History.txt +18 -0
  4. data/README.md +4 -0
  5. data/Rakefile +20 -40
  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 +7 -1
  15. data/doc/syntactic_recognition.markdown +7 -2
  16. data/doc/tt.1 +1 -1
  17. data/examples/indented_blocks/indented_blocks.tt +73 -0
  18. data/examples/indented_blocks/indented_blocks_test.rb +24 -0
  19. data/lib/treetop/compiler/grammar_compiler.rb +6 -3
  20. data/lib/treetop/compiler/metagrammar.rb +301 -159
  21. data/lib/treetop/compiler/metagrammar.treetop +96 -13
  22. data/lib/treetop/compiler/node_classes/anything_symbol.rb +10 -2
  23. data/lib/treetop/compiler/node_classes/atomic_expression.rb +2 -2
  24. data/lib/treetop/compiler/node_classes/character_class.rb +10 -2
  25. data/lib/treetop/compiler/node_classes/choice.rb +11 -7
  26. data/lib/treetop/compiler/node_classes/nonterminal.rb +6 -2
  27. data/lib/treetop/compiler/node_classes/parenthesized_expression.rb +5 -1
  28. data/lib/treetop/compiler/node_classes/parsing_expression.rb +10 -1
  29. data/lib/treetop/compiler/node_classes/parsing_rule.rb +1 -1
  30. data/lib/treetop/compiler/node_classes/predicate.rb +8 -1
  31. data/lib/treetop/compiler/node_classes/predicate_block.rb +7 -0
  32. data/lib/treetop/compiler/node_classes/repetition.rb +28 -8
  33. data/lib/treetop/compiler/node_classes/sequence.rb +5 -1
  34. data/lib/treetop/compiler/node_classes/terminal.rb +36 -22
  35. data/lib/treetop/compiler/ruby_builder.rb +2 -2
  36. data/lib/treetop/ruby_extensions/string.rb +0 -6
  37. data/lib/treetop/runtime/compiled_parser.rb +33 -14
  38. data/lib/treetop/runtime/syntax_node.rb +24 -15
  39. data/lib/treetop/runtime/terminal_parse_failure.rb +4 -3
  40. data/lib/treetop/runtime/terminal_syntax_node.rb +4 -4
  41. data/lib/treetop/version.rb +2 -2
  42. data/treetop.gemspec +25 -165
  43. metadata +43 -98
  44. data/doc/site.rb +0 -112
  45. data/doc/sitegen.rb +0 -65
  46. data/examples/lambda_calculus/lambda_calculus +0 -0
  47. data/spec/compiler/and_predicate_spec.rb +0 -36
  48. data/spec/compiler/anything_symbol_spec.rb +0 -44
  49. data/spec/compiler/character_class_spec.rb +0 -301
  50. data/spec/compiler/choice_spec.rb +0 -80
  51. data/spec/compiler/circular_compilation_spec.rb +0 -30
  52. data/spec/compiler/failure_propagation_functional_spec.rb +0 -21
  53. data/spec/compiler/grammar_compiler_spec.rb +0 -113
  54. data/spec/compiler/grammar_spec.rb +0 -41
  55. data/spec/compiler/multibyte_chars_spec.rb +0 -38
  56. data/spec/compiler/namespace_spec.rb +0 -42
  57. data/spec/compiler/nonterminal_symbol_spec.rb +0 -40
  58. data/spec/compiler/not_predicate_spec.rb +0 -38
  59. data/spec/compiler/occurrence_range_spec.rb +0 -189
  60. data/spec/compiler/one_or_more_spec.rb +0 -35
  61. data/spec/compiler/optional_spec.rb +0 -37
  62. data/spec/compiler/parenthesized_expression_spec.rb +0 -19
  63. data/spec/compiler/parsing_rule_spec.rb +0 -61
  64. data/spec/compiler/repeated_subrule_spec.rb +0 -29
  65. data/spec/compiler/semantic_predicate_spec.rb +0 -175
  66. data/spec/compiler/sequence_spec.rb +0 -129
  67. data/spec/compiler/terminal_spec.rb +0 -170
  68. data/spec/compiler/terminal_symbol_spec.rb +0 -37
  69. data/spec/compiler/test_grammar.treetop +0 -7
  70. data/spec/compiler/test_grammar.tt +0 -7
  71. data/spec/compiler/test_grammar_do.treetop +0 -7
  72. data/spec/compiler/test_grammar_magic_coding.treetop +0 -8
  73. data/spec/compiler/test_grammar_magic_encoding.treetop +0 -8
  74. data/spec/compiler/tt_compiler_spec.rb +0 -224
  75. data/spec/compiler/zero_or_more_spec.rb +0 -56
  76. data/spec/composition/a.treetop +0 -11
  77. data/spec/composition/b.treetop +0 -11
  78. data/spec/composition/c.treetop +0 -10
  79. data/spec/composition/d.treetop +0 -10
  80. data/spec/composition/f.treetop +0 -17
  81. data/spec/composition/grammar_composition_spec.rb +0 -40
  82. data/spec/composition/subfolder/e_includes_c.treetop +0 -15
  83. data/spec/ruby_extensions/string_spec.rb +0 -32
  84. data/spec/runtime/compiled_parser_spec.rb +0 -123
  85. data/spec/runtime/interval_skip_list/delete_spec.rb +0 -147
  86. data/spec/runtime/interval_skip_list/expire_range_spec.rb +0 -349
  87. data/spec/runtime/interval_skip_list/insert_and_delete_node_spec.rb +0 -385
  88. data/spec/runtime/interval_skip_list/insert_spec.rb +0 -660
  89. data/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +0 -6175
  90. data/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +0 -58
  91. data/spec/runtime/interval_skip_list/palindromic_fixture.rb +0 -35
  92. data/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +0 -163
  93. data/spec/runtime/interval_skip_list/spec_helper.rb +0 -91
  94. data/spec/runtime/syntax_node_spec.rb +0 -77
  95. data/spec/spec_helper.rb +0 -115
@@ -1,301 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CharacterClassSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "a character class followed by a node class declaration and a block" do
8
-
9
- testing_expression "[A-Z] <CharacterClassSpec::Foo> { def a_method; end }"
10
-
11
- it "matches single characters within that range, returning instances of the declared node class that respond to the method defined in the inline module" do
12
- result = parse('A')
13
- result.should be_an_instance_of(Foo)
14
- result.should respond_to(:a_method)
15
- result = parse('N')
16
- result.should be_an_instance_of(Foo)
17
- result.should respond_to(:a_method)
18
- result = parse('Z')
19
- result.should be_an_instance_of(Foo)
20
- result.should respond_to(:a_method)
21
- end
22
-
23
- it "does not match single characters outside of that range" do
24
- parse('8').should be_nil
25
- parse('a').should be_nil
26
- end
27
-
28
- it "matches a single character within that range at index 1" do
29
- parse(' A', :index => 1).should_not be_nil
30
- end
31
-
32
- it "fails to match a single character out of that range at index 1" do
33
- parse(' 1', :index => 1).should be_nil
34
- end
35
- end
36
-
37
- module ModFoo
38
- end
39
-
40
- describe "a character class followed by a node module declaration and a block" do
41
-
42
- testing_expression "[A-Z] <CharacterClassSpec::ModFoo> { def a_method; end }"
43
-
44
- it "matches single characters within that range, returning instances of SyntaxNode extended by the specified module" do
45
- result = parse('A')
46
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
47
- result.should be_a_kind_of(ModFoo)
48
- result.should respond_to(:a_method)
49
- result = parse('N')
50
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
51
- result.should be_a_kind_of(ModFoo)
52
- result.should respond_to(:a_method)
53
- result = parse('Z')
54
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
55
- result.should be_a_kind_of(ModFoo)
56
- result.should respond_to(:a_method)
57
- end
58
-
59
- it "does not match single characters outside of that range" do
60
- parse('8').should be_nil
61
- parse('a').should be_nil
62
- end
63
-
64
- it "matches a single character within that range at index 1" do
65
- parse(' A', :index => 1).should_not be_nil
66
- end
67
-
68
- it "fails to match a single character out of that range at index 1" do
69
- parse(' 1', :index => 1).should be_nil
70
- end
71
- end
72
-
73
- describe "a character class with a POSIX bracket expression" do
74
- testing_expression "[[:digit:]]"
75
- it "matches a single character within the class" do
76
- parse('1').should_not be_nil
77
- end
78
- it "does not match a single character outside the class" do
79
- parse('a').should be_nil
80
- parse('-').should be_nil
81
- end
82
- testing_expression "[[:digit:][:space:]]+"
83
- it "matches a string with a mix of two character classes" do
84
- parse('1 4 9').should_not be_nil
85
- end
86
- end
87
-
88
- describe "a character class with a negated POSIX bracket expression" do
89
- testing_expression "[^[:space:]]"
90
- it "matches a character outside the negated class" do
91
- parse('a').should_not be_nil
92
- end
93
- it "doesn't match a character within the negated class" do
94
- parse(' ').should be_nil
95
- end
96
- end
97
-
98
- describe "a character class followed by a node class declaration and a block" do
99
-
100
- testing_expression "[A-Z] <CharacterClassSpec::Foo>"
101
-
102
- it "actively generates nodes for the character when it is the primary node" do
103
- result = parse('A')
104
- result.should be_a(Treetop::Runtime::SyntaxNode)
105
- result.elements.should be_nil
106
- end
107
-
108
- end
109
-
110
- describe "A character class containing quotes" do
111
- testing_expression "[\"']"
112
-
113
- it "matches a quote" do
114
- parse("'").should_not be_nil
115
- end
116
-
117
- it "matches a double-quote" do
118
- parse('"').should_not be_nil
119
- end
120
- end
121
-
122
- describe "A character class containing a special character" do
123
- testing_expression "[\t]"
124
- it "matches that character only" do
125
- parse("\t").should_not be_nil
126
- parse('t').should be_nil
127
- end
128
- end
129
-
130
- describe "A character class containing an escaped backslash" do
131
- slash = "\\" # Make it explicit that there are *two* backslashes here
132
- testing_expression "[#{slash}#{slash}]"
133
- it "matches a backslash only" do
134
- parse("\\").should_not be_nil
135
- parse('t').should be_nil
136
- end
137
- end
138
-
139
- describe "A character class containing a hex escape" do
140
- slash = "\\"
141
- testing_expression "[#{slash}x41]"
142
- it "matches that character only" do
143
- parse('A').should_not be_nil
144
- parse('\\').should be_nil
145
- parse('x').should be_nil
146
- parse('4').should be_nil
147
- parse('1').should be_nil
148
- end
149
- end
150
-
151
- describe "A character class containing an octal escape" do
152
- slash = "\\"
153
- testing_expression "[#{slash}101]"
154
- it "matches that character only" do
155
- parse('A').should_not be_nil
156
- parse('\\').should be_nil
157
- parse('1').should be_nil
158
- parse('0').should be_nil
159
- end
160
- end
161
-
162
- describe "A character class containing a \\c control-char escape" do
163
- slash = "\\"
164
- testing_expression "[#{slash}cC]"
165
- it "matches that character only" do
166
- parse("\003").should_not be_nil
167
- parse('\\').should be_nil
168
- parse('c').should be_nil
169
- parse('C').should be_nil
170
- end
171
- end
172
-
173
- describe "A character class containing a \\C- control-char escape" do
174
- slash = "\\"
175
- testing_expression "[#{slash}C-C]"
176
- it "matches that character only" do
177
- parse("\003").should_not be_nil
178
- parse('\\').should be_nil
179
- parse('C').should be_nil
180
- parse('-').should be_nil
181
- end
182
- end
183
-
184
- if RUBY_VERSION =~ /\A1\.8\./
185
- describe "A character class containing a \\M- meta-char escape" do
186
- slash = "\\"
187
- testing_expression "[#{slash}M- ]"
188
- it "matches that character only" do
189
- parse("\240").should_not be_nil
190
- parse('\\').should be_nil
191
- parse('M').should be_nil
192
- parse('-').should be_nil
193
- parse(' ').should be_nil
194
- end
195
- end
196
- end
197
-
198
- describe "A character class containing an escaped non-special character" do
199
- slash = "\\"
200
- testing_expression "[#{slash}y]"
201
- it "matches that character only" do
202
- parse("y").should_not be_nil
203
- parse('\\').should be_nil
204
- end
205
- end
206
-
207
- describe "A character class containing an \#{...} insertion" do
208
- testing_expression "[\#{raise 'error'}]"
209
- it "doesn't evaluate the insertion" do
210
- x = true
211
- lambda{
212
- x = parse("y")
213
- }.should_not raise_error
214
- x.should be_nil
215
- parse('#').should_not be_nil
216
- parse("'").should_not be_nil
217
- parse("0").should be_nil
218
- end
219
- end
220
-
221
- describe "a character class" do
222
- testing_expression "[A-Z]"
223
- it "actively generates a node for the character because it is the primary node" do
224
- result = parse('A')
225
- result.should be_a(Treetop::Runtime::SyntaxNode)
226
- result.elements.should be_nil
227
- end
228
- end
229
-
230
- describe "a character class mixed with other expressions" do
231
- testing_expression '[A-Z] "a" "bc"'
232
- it "lazily instantiates a node for the character" do
233
- result = parse('Aabc')
234
- result.instance_variable_get("@elements").should include(true)
235
- result.elements.should_not include(true)
236
- result.elements.size.should == 3
237
- end
238
- end
239
-
240
- describe "a character class with a node class declaration mixed with other expressions" do
241
- testing_expression '([A-Z] <CharacterClassSpec::Foo>) "ab"'
242
- it "actively generates a node for the character because it has a node class declared" do
243
- result = parse('Aab')
244
- result.instance_variable_get("@elements").should_not include(true)
245
- result.elements.should_not include(true)
246
- result.elements.size.should == 2
247
- end
248
- end
249
-
250
- describe "a character class with a node module declaration mixed with other expressions" do
251
- testing_expression '([A-Z] <CharacterClassSpec::ModFoo>) "ab"'
252
- it "actively generates a node for the character because it has a node module declared" do
253
- result = parse('Aab')
254
- result.instance_variable_get("@elements").should_not include(true)
255
- result.elements.should_not include(true)
256
- result.elements.size.should == 2
257
- end
258
- end
259
-
260
- describe "a character class with an inline block mixed with other expressions" do
261
- testing_expression '([A-Z] { def a_method; end }) "ab"'
262
- it "actively generates a node for the character because it has an inline block" do
263
- result = parse('Aab')
264
- result.instance_variable_get("@elements").should_not include(true)
265
- result.elements.should_not include(true)
266
- result.elements.size.should == 2
267
- end
268
- end
269
-
270
- describe "a character class with a label mixed with other expressions" do
271
- testing_expression 'upper:([A-Z]) "b" "cd"'
272
- it "returns the correct element for the labeled expression" do
273
- result = parse('Abcd')
274
- result.upper.text_value.should == "A"
275
- result.elements.size.should == 3
276
- end
277
- end
278
-
279
- describe "a character class repetition mixed with other expressions" do
280
- testing_expression '[A-Z]+ "a" "bc"'
281
- it "lazily instantiates a node for the character" do
282
- result = parse('ABCabc')
283
- result.elements[0].instance_variable_get("@elements").should include(true)
284
- result.elements[0].elements.should_not include(true)
285
- result.elements[0].elements.size.should == 3
286
- result.elements.size.should == 3
287
- result.elements.inspect.should == %Q{[SyntaxNode offset=0, "ABC":\n SyntaxNode offset=0, "A"\n SyntaxNode offset=1, "B"\n SyntaxNode offset=2, "C", SyntaxNode offset=3, "a", SyntaxNode offset=4, "bc"]}
288
- end
289
- end
290
-
291
- describe "a character class that gets cached because of a choice" do
292
- testing_expression "[A-Z] 'a' 'bc' / [A-Z]"
293
-
294
- it "generates a node for the lazily-instantiated character when it is the primary node" do
295
- result = parse('A')
296
- result.should be_a(Treetop::Runtime::SyntaxNode)
297
- result.elements.should be_nil
298
- end
299
- end
300
-
301
- end
@@ -1,80 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ChoiceSpec
4
- describe "A choice between terminal symbols" do
5
- testing_expression '"foo" { def foo_method; end } / "bar" { def bar_method; end } / "baz" { def baz_method; end }'
6
-
7
- it "successfully parses input matching any of the alternatives, returning a node that responds to methods defined in its respective inline module" do
8
- result = parse('foo')
9
- result.should_not be_nil
10
- result.should respond_to(:foo_method)
11
-
12
- result = parse('bar')
13
- result.should_not be_nil
14
- result.should respond_to(:bar_method)
15
-
16
- result = parse('baz')
17
- result.should_not be_nil
18
- result.should respond_to(:baz_method)
19
- end
20
-
21
- it "upon parsing a string matching the second alternative, records the failure of the first terminal" do
22
- result = parse('bar')
23
- terminal_failures = parser.terminal_failures
24
- terminal_failures.size.should == 1
25
- failure = terminal_failures[0]
26
- failure.expected_string.should == 'foo'
27
- failure.index.should == 0
28
- end
29
-
30
- it "upon parsing a string matching the third alternative, records the failure of the first two terminals" do
31
- result = parse('baz')
32
-
33
- terminal_failures = parser.terminal_failures
34
-
35
- terminal_failures.size.should == 2
36
-
37
- failure_1 = terminal_failures[0]
38
- failure_1.expected_string == 'foo'
39
- failure_1.index.should == 0
40
-
41
- failure_2 = terminal_failures[1]
42
- failure_2.expected_string == 'bar'
43
- failure_2.index.should == 0
44
- end
45
- end
46
-
47
- describe "A choice between sequences" do
48
- testing_expression "'foo' 'bar' 'baz'\n/\n'bing' 'bang' 'boom'"
49
-
50
- it "successfully parses input matching any of the alternatives" do
51
- parse('foobarbaz').should_not be_nil
52
- parse('bingbangboom').should_not be_nil
53
- end
54
- end
55
-
56
- describe "A choice between terminals followed by a block" do
57
- testing_expression "('a'/ 'bb' / [c]) { def a_method; end }"
58
-
59
- it "extends a match of any of its subexpressions with a module created from the block" do
60
- ['a', 'bb', 'c'].each do |letter|
61
- parse(letter).should respond_to(:a_method)
62
- end
63
- end
64
- end
65
-
66
- module TestModule
67
- def a_method
68
- end
69
- end
70
-
71
- describe "a choice followed by a declared module" do
72
- testing_expression "('a'/ 'bb' / [c]) <ChoiceSpec::TestModule>"
73
-
74
- it "extends a match of any of its subexpressions with a module created from the block" do
75
- ['a', 'bb', 'c'].each do |letter|
76
- parse(letter).should respond_to(:a_method)
77
- end
78
- end
79
- end
80
- end
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- BENCHMARK = false
4
- METAGRAMMAR_PATH = File.expand_path('../../../lib/treetop/compiler/metagrammar.treetop', __FILE__)
5
-
6
- module CircularCompilationSpec
7
- describe "a parser for the metagrammar" do
8
- attr_reader :parser
9
-
10
- before do
11
- @parser = Treetop::Compiler::MetagrammarParser.new
12
- end
13
-
14
- it "can parse the metagrammar.treetop whence it was generated" do
15
- File.open(METAGRAMMAR_PATH, 'r') do |f|
16
- metagrammar_source = f.read
17
- result = parser.parse(metagrammar_source)
18
- result.should_not be_nil
19
-
20
- # generated_parser = result.compile
21
- # Object.class_eval(generated_parser)
22
- # parser_2 = Treetop::Compiler::MetagrammarParser.new
23
- # optionally_benchmark do
24
- # result = parser_2.parse(metagrammar_source)
25
- # result.should_not be_nil
26
- # end
27
- end
28
- end
29
- end
30
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "An expression for braces surrounding zero or more letters followed by semicolons" do
4
- testing_expression "'{' ([a-z] ';')* '}'"
5
-
6
- it "parses matching input successfully" do
7
- parse('{a;b;c;}').should_not be_nil
8
- end
9
-
10
- it "fails to parse input with an expression that is missing a semicolon, reporting the terminal failure occurring at the maximum index" do
11
- parse('{a;b;c}') do |result|
12
- result.should be_nil
13
-
14
- terminal_failures = parser.terminal_failures
15
- terminal_failures.size.should == 1
16
- failure = terminal_failures[0]
17
- failure.index.should == 6
18
- failure.expected_string.should == ';'
19
- end
20
- end
21
- end
@@ -1,113 +0,0 @@
1
- require 'spec_helper'
2
- require 'tmpdir'
3
-
4
- describe Compiler::GrammarCompiler do
5
- attr_reader :compiler, :source_path_with_treetop_extension, :source_path_with_tt_extension, :target_path, :alternate_target_path
6
- before do
7
- @compiler = Compiler::GrammarCompiler.new
8
-
9
- dir = File.dirname(__FILE__)
10
- @tmpdir = Dir.tmpdir
11
-
12
- @source_path_with_treetop_extension = "#{dir}/test_grammar.treetop"
13
- @source_path_with_do = "#{dir}/test_grammar_do.treetop"
14
- @source_path_with_tt_extension = "#{dir}/test_grammar.tt"
15
- @source_path_with_magic_coding = "#{dir}/test_grammar_magic_coding.treetop"
16
- @source_path_with_magic_encoding = "#{dir}/test_grammar_magic_encoding.treetop"
17
- @target_path = "#{@tmpdir}/test_grammar.rb"
18
- @target_path_with_do = "#{@tmpdir}/test_grammar_do.rb"
19
- @target_path_with_magic_coding = "#{@tmpdir}/test_grammar_magic_coding.rb"
20
- @target_path_with_magic_encoding = "#{@tmpdir}/test_grammar_magic_encoding.rb"
21
- @alternate_target_path = "#{@tmpdir}/test_grammar_alt.rb"
22
- delete_target_files
23
- end
24
-
25
- after do
26
- delete_target_files
27
- Object.class_eval do
28
- remove_const(:Test) if const_defined?(:Test)
29
- end
30
- end
31
-
32
- specify "compilation of a single file to a default file name" do
33
- src_copy = "#{@tmpdir}/test_grammar.treetop"
34
- File.open(source_path_with_treetop_extension) { |f| File.open(src_copy,'w'){|o|o.write(f.read)} }
35
- File.exists?(target_path).should be_false
36
- compiler.compile(src_copy)
37
- File.exists?(target_path).should be_true
38
- require target_path
39
- Test::GrammarParser.new.parse('foo').should_not be_nil
40
- end
41
-
42
- specify "compilation of a single file to an explicit file name" do
43
- File.exists?(alternate_target_path).should be_false
44
- compiler.compile(source_path_with_treetop_extension, alternate_target_path)
45
- File.exists?(alternate_target_path).should be_true
46
- require alternate_target_path
47
- Test::GrammarParser.new.parse('foo').should_not be_nil
48
- end
49
-
50
- specify "compilation of a single file without writing it to an output file" do
51
- compiler.ruby_source(source_path_with_treetop_extension).should_not be_nil
52
- end
53
-
54
- specify "ruby_source_from_string compiles a grammar stored in string" do
55
- compiler.ruby_source_from_string(File.read(source_path_with_treetop_extension)).should_not be_nil
56
- end
57
-
58
- specify "Treetop.load_from_string compiles and evaluates a source grammar stored in string" do
59
- Treetop.load_from_string File.read(source_path_with_treetop_extension)
60
- Test::GrammarParser.new.parse('foo').should_not be_nil
61
- end
62
-
63
- specify "Treetop.load compiles and evaluates a source grammar with a .treetop extension" do
64
- Treetop.load source_path_with_treetop_extension
65
- Test::GrammarParser.new.parse('foo').should_not be_nil
66
- end
67
-
68
- specify "Treetop.load compiles and evaluates a source grammar with a .tt extension" do
69
- path_without_extension = source_path_with_tt_extension
70
- Treetop.load path_without_extension
71
- Test::GrammarParser.new.parse('foo').should_not be_nil
72
- end
73
-
74
-
75
- specify "Treetop.load compiles and evaluates source grammar with no extension" do
76
- path_without_extension = source_path_with_treetop_extension.gsub(/\.treetop\Z/, '')
77
- Treetop.load path_without_extension
78
- Test::GrammarParser.new.parse('foo').should_not be_nil
79
- end
80
-
81
- specify "grammars with 'do' compile" do
82
- src_copy = "#{@tmpdir}/test_grammar_do.treetop"
83
- File.open(@source_path_with_do) { |f| File.open(src_copy,'w'){|o|o.write(f.read)} }
84
- compiler.compile(src_copy)
85
- require @target_path_with_do
86
- Test::GrammarParser.new.parse('foo').should_not be_nil
87
- end
88
-
89
- specify "grammars with magic 'encoding' comments keep those comments at the top" do
90
- src_copy = "#{@tmpdir}/test_grammar_magic_encoding.treetop"
91
- File.open(@source_path_with_magic_encoding) do |f|
92
- File.open(src_copy,'w'){|o|o.write(f.read)}
93
- end
94
- compiler.compile(src_copy)
95
- File.open(@target_path_with_magic_encoding).readline.should == "# encoding: UTF-8\n"
96
- end
97
-
98
- specify "grammars with magic 'coding' comments keep those comments at the top" do
99
- src_copy = "#{@tmpdir}/test_grammar_magic_coding.treetop"
100
- File.open(@source_path_with_magic_coding) do |f|
101
- File.open(src_copy,'w'){|o|o.write(f.read)}
102
- end
103
- compiler.compile(src_copy)
104
- File.open(@target_path_with_magic_coding).readline.should == "# coding: UTF-8\n"
105
- end
106
-
107
- def delete_target_files
108
- File.delete(target_path) if File.exists?(target_path)
109
- File.delete(@target_path_with_do) if File.exists?(@target_path_with_do)
110
- File.delete(alternate_target_path) if File.exists?(alternate_target_path)
111
- end
112
- end
113
-
@@ -1,41 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module GrammarSpec
4
- module Bar
5
- end
6
-
7
- describe "a grammar" do
8
- testing_grammar %{
9
- grammar Foo
10
- # This comment should not cause a syntax error, nor should the following empty one
11
- #
12
- include GrammarSpec::Bar
13
-
14
- rule foo
15
- bar / baz
16
- end
17
-
18
- rule bar
19
- 'bar' 'bar'
20
- end
21
-
22
- rule baz
23
- 'baz' 'baz'
24
- end
25
- end
26
- }
27
-
28
- it "parses matching input" do
29
- parse('barbar').should_not be_nil
30
- parse('bazbaz').should_not be_nil
31
- end
32
-
33
- it "fails if it does not parse all input" do
34
- parse('barbarbazbaz').should be_nil
35
- end
36
-
37
- it "mixes in included modules" do
38
- self.class.const_get(:Foo).ancestors.should include(GrammarSpec::Bar)
39
- end
40
- end
41
- end
@@ -1,38 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- module MultibyteCharsSpec
6
- describe "an anything symbol", :multibyte => true do
7
- testing_expression '.'
8
- it "matches an UTF-8 character" do
9
- parse_multibyte("ø").should_not be_nil
10
- end
11
- end
12
-
13
- describe "A character class containing UTF-8 characters", :multibyte => true do
14
- testing_expression "[æøå]"
15
- it "recognizes the UTF-8 characters" do
16
- parse_multibyte("ø").should_not be_nil
17
- end
18
- end
19
-
20
- describe( "a character class repetition containing UTF-8 characters mixed with other expressions",
21
- :multibyte => true
22
- ) do
23
- testing_expression '[æøå]+ "a"'
24
- it "lazily instantiates a node for the character" do
25
- result = parse_multibyte('æøåa')
26
- pending "Multibyte support is not supported in Ruby 1.8.6" if RUBY_VERSION =~ /^1\.8.6/
27
- result.elements[0].instance_variable_get("@elements").should include(true)
28
- result.elements[0].elements.should_not include(true)
29
- result.elements[0].elements.size.should == 3
30
- result.elements.size.should == 2
31
- result.elements[0].text_value.should == "æøå"
32
- result.elements[0].elements[0].text_value.should == "æ"
33
- result.elements[0].elements[1].text_value.should == "ø"
34
- result.elements[0].elements[2].text_value.should == "å"
35
- result.elements[1].text_value == "a"
36
- end
37
- end
38
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module NamespaceSpec
4
-
5
- describe "a grammar" do
6
- class_eval("module Foo; end")
7
- testing_grammar %{
8
- module Foo::Bar
9
- module Baz
10
- grammar Bat
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
- end
24
- end
25
- }
26
-
27
- it "parses matching input" do
28
- parse('barbar').should_not be_nil
29
- parse('bazbaz').should_not be_nil
30
- end
31
-
32
- it "mixes in included modules" do
33
- foo = self.class.const_get(:Foo)
34
- bar = foo.const_get(:Bar)
35
- baz = bar.const_get(:Baz)
36
- baz.class.should == Module
37
- bat = baz.const_get(:Bat)
38
- bat.class.should == Module
39
- baz.const_get(:BatParser).class.should == Class
40
- end
41
- end
42
- end