treetop 1.6.6 → 1.6.11

Sign up to get free protection for your applications and to get access to all the features.
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,129 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module SequenceSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "a sequence of labeled terminal symbols followed by a node class declaration and a block" do
8
- testing_expression 'foo:"foo" bar:"bar" baz:"baz" <SequenceSpec::Foo> { def a_method; end }'
9
-
10
- it "upon successfully matching input, instantiates 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_not be_nil
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
- it "successfully matches at a non-zero index" do
22
- parse('---foobarbaz', :index => 3) do |result|
23
- result.should_not be_nil
24
- result.should be_nonterminal
25
- (result.elements.map {|elt| elt.text_value}).join.should == 'foobarbaz'
26
- end
27
- end
28
-
29
- it "fails to match non-matching input, recording the parse failure of first non-matching terminal" do
30
- parse('---foobazbaz', :index => 3) do |result|
31
- result.should be_nil
32
- parser.index.should == 3
33
- terminal_failures = parser.terminal_failures
34
- terminal_failures.size.should == 1
35
- failure = terminal_failures.first
36
- failure.index.should == 6
37
- failure.expected_string.should == '"bar"'
38
- end
39
- end
40
- end
41
-
42
- module ModFoo
43
- def mod_method; end
44
- end
45
-
46
- describe "a sequence of labeled terminal symbols followed by a node module declaration and a block" do
47
- testing_expression 'foo:"foo" bar:"bar" baz:"baz" <SequenceSpec::ModFoo> { def a_method; end }'
48
-
49
- it "upon successfully matching input, instantiates a syntax node and extends it with the declared module, element accessor methods, and the method from the inline module" do
50
- parse('foobarbaz') do |result|
51
- result.should_not be_nil
52
- result.should respond_to(:mod_method)
53
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
54
- result.should be_a_kind_of(ModFoo)
55
- result.should respond_to(:a_method)
56
- result.foo.text_value.should == 'foo'
57
- result.bar.text_value.should == 'bar'
58
- result.baz.text_value.should == 'baz'
59
- end
60
- end
61
- end
62
-
63
- describe "a labeled single element sequence followed by a node module declaration and a block" do
64
- testing_expression 'foo:"foo"+ <SequenceSpec::ModFoo> { def a_method; end }'
65
- it "upon successfully matching input, instantiates a syntax node and extends it with the declared module, element accessor methods, and the method from the inline module" do
66
- parse('foofoofoo') do |result|
67
- result.should_not be_nil
68
- result.should respond_to(:mod_method)
69
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
70
- result.should be_a_kind_of(ModFoo)
71
- result.should respond_to(:a_method)
72
- result.foo.text_value.should == 'foofoofoo'
73
- end
74
- end
75
- end
76
-
77
- describe "a sequence of non-terminals" do
78
- testing_grammar %{
79
- grammar TestGrammar
80
- rule sequence
81
- foo bar baz {
82
- def baz
83
- 'override' + super.text_value
84
- end
85
- }
86
- end
87
-
88
- rule foo 'foo' end
89
- rule bar 'bar' end
90
- rule baz 'baz' end
91
- end
92
- }
93
-
94
- it "defines accessors for non-terminals automatically that can be overridden in the inline block" do
95
- parse('foobarbaz') do |result|
96
- result.foo.text_value.should == 'foo'
97
- result.bar.text_value.should == 'bar'
98
- result.baz.should == 'overridebaz'
99
- end
100
- end
101
- end
102
-
103
- describe "Compiling a sequence containing various white-space errors" do
104
- it "should succeed on a valid sequence" do
105
- compiling_expression('foo:"foo" "bar" <SequenceSpec::Foo> { def a_method; end }').should_not raise_error
106
- end
107
-
108
- it "rejects space after a label" do
109
- compiling_expression('foo :"foo" "bar"').should raise_error(RuntimeError)
110
- end
111
-
112
- it "rejects space after label's colon" do
113
- compiling_expression('foo: "foo" "bar"').should raise_error(RuntimeError)
114
- end
115
-
116
- it "rejects missing space after a primary" do
117
- compiling_expression('foo:"foo""bar"').should raise_error(RuntimeError)
118
- end
119
-
120
- it "rejects missing space before node class declaration" do
121
- compiling_expression('foo:"foo" "bar"<SequenceSpec::Foo>').should raise_error(RuntimeError)
122
- end
123
-
124
- it "rejects missing space before inline module" do
125
- compiling_expression('foo:"foo" "bar" <SequenceSpec::Foo>{def a_method; end}').should raise_error(RuntimeError)
126
- end
127
- end
128
-
129
- end
@@ -1,177 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TerminalSymbolSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "a terminal symbol" do
8
- testing_expression "'Foo'"
9
-
10
- it "matches the input string" do
11
- parse "Foo", :index => 0 do |result|
12
- result.should_not be_nil
13
- result.interval.should == (0...3)
14
- result.text_value.should == 'Foo'
15
- end
16
- end
17
-
18
- it "fails to match the input string other than at the start" do
19
- parse " Foo", :index => 0 do |result|
20
- result.should be_nil
21
- parser.terminal_failures.size.should == 1
22
- end
23
- end
24
-
25
- it "fails to match the input string in the wrong case" do
26
- parse "foo", :index => 0 do |result|
27
- result.should be_nil
28
- parser.terminal_failures.size.should == 1
29
- end
30
- end
31
- end
32
-
33
- describe "a terminal symbol with case-insensitive matching" do
34
- testing_expression "'Foo'i"
35
-
36
- it "matches the input string in the same case" do
37
- parse "Foo", :index => 0 do |result|
38
- result.should_not be_nil
39
- result.interval.should == (0...3)
40
- result.text_value.should == 'Foo'
41
- end
42
- end
43
-
44
- it "matches the input string in varied case" do
45
- parse "foO", :index => 0 do |result|
46
- result.should_not be_nil
47
- result.interval.should == (0...3)
48
- result.text_value.should == 'foO'
49
- end
50
- end
51
- end
52
-
53
- describe "a terminal symbol followed by a node class declaration and a block" do
54
- testing_expression "'foo' <TerminalSymbolSpec::Foo> { def a_method; end }"
55
-
56
- 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
57
- parse "foo", :index => 0 do |result|
58
- result.should be_an_instance_of(Foo)
59
- result.should respond_to(:a_method)
60
- result.interval.should == (0...3)
61
- result.text_value.should == 'foo'
62
- end
63
-
64
- parse "xfoo", :index => 1 do |result|
65
- result.should be_an_instance_of(Foo)
66
- result.should respond_to(:a_method)
67
- result.interval.should == (1...4)
68
- result.text_value.should == 'foo'
69
- end
70
-
71
- parse "---foo", :index => 3 do |result|
72
- result.should be_an_instance_of(Foo)
73
- result.should respond_to(:a_method)
74
- result.interval.should == (3...6)
75
- result.text_value.should == 'foo'
76
- end
77
- end
78
-
79
- it "fails to parse nonmatching input at the index even if a match occurs later" do
80
- parse(" foo", :index => 0) do |result|
81
- result.should be_nil
82
- parser.terminal_failures.size.should == 1
83
- end
84
- end
85
- end
86
-
87
- module ModFoo
88
- end
89
-
90
- describe "a terminal symbol followed by a node class declaration and a block" do
91
- testing_expression "'foo' <TerminalSymbolSpec::ModFoo> { def a_method; end }"
92
-
93
- it "correctly parses matching input prefixes at various indices, returning an instance of SyntaxNode extended with the declared module that can respond to methods defined in the inline module" do
94
- parse "foo", :index => 0 do |result|
95
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
96
- result.should be_a_kind_of(ModFoo)
97
- result.should respond_to(:a_method)
98
- result.interval.should == (0...3)
99
- result.text_value.should == 'foo'
100
- end
101
-
102
- parse "xfoo", :index => 1 do |result|
103
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
104
- result.should be_a_kind_of(ModFoo)
105
- result.should respond_to(:a_method)
106
- result.interval.should == (1...4)
107
- result.text_value.should == 'foo'
108
- end
109
-
110
- parse "---foo", :index => 3 do |result|
111
- result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
112
- result.should be_a_kind_of(ModFoo)
113
- result.should respond_to(:a_method)
114
- result.interval.should == (3...6)
115
- result.text_value.should == 'foo'
116
- end
117
- end
118
- end
119
-
120
- describe "a terminal regexp" do
121
- testing_expression "'Fo+'r"
122
-
123
- it "matches the input string" do
124
- parse "Fooo", :index => 0 do |result|
125
- result.should_not be_nil
126
- result.interval.should == (0...4)
127
- result.text_value.should == 'Fooo'
128
- end
129
- end
130
-
131
- it "fails to match the input string other than at the start" do
132
- parse " Foo", :index => 0 do |result|
133
- result.should be_nil
134
- parser.terminal_failures.size.should == 1
135
- end
136
- end
137
-
138
- it "fails to match the input string in the wrong case" do
139
- parse "foo", :index => 0 do |result|
140
- result.should be_nil
141
- parser.terminal_failures.size.should == 1
142
- end
143
- end
144
- end
145
-
146
- describe "a case-insensitive terminal regexp" do
147
- testing_expression "'Fo+'ri"
148
-
149
- it "matches the input string in the same case" do
150
- parse "Fooo", :index => 0 do |result|
151
- result.should_not be_nil
152
- result.interval.should == (0...4)
153
- result.text_value.should == 'Fooo'
154
- end
155
- end
156
-
157
- it "matches the input string in the same case" do
158
- parse "foOo", :index => 0 do |result|
159
- result.should_not be_nil
160
- result.interval.should == (0...4)
161
- result.text_value.should == 'foOo'
162
- end
163
- end
164
- end
165
-
166
- # Transient symbols were part of some idea of Nathan's that I no longer recall
167
- # describe "a transient terminal symbol" do
168
- # testing_expression "~'foo'"
169
- #
170
- # it "returns true upon parsing matching input prefixes at various indices" do
171
- # pending "transient terminal expressions"
172
- # parse("foo", :index => 0).should be_truthy
173
- # parse("-foo", :index => 1).should be_truthy
174
- # parse("---foo", :index => 3).should be_truthy
175
- # end
176
- # end
177
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module TerminalSymbolSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "a terminal symbol followed by a node class declaration and a block" do
8
- testing_expression "'foo' <TerminalSymbolSpec::Foo> { def a_method; end }"
9
-
10
- 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
11
- parse "foo", :index => 0 do |result|
12
- result.should be_an_instance_of(Foo)
13
- result.should respond_to(:a_method)
14
- result.interval.should == (0...3)
15
- result.text_value.should == 'foo'
16
- end
17
-
18
- parse "xfoo", :index => 1 do |result|
19
- result.should be_an_instance_of(Foo)
20
- result.should respond_to(:a_method)
21
- result.interval.should == (1...4)
22
- result.text_value.should == 'foo'
23
- end
24
-
25
- parse "---foo", :index => 3 do |result|
26
- result.should be_an_instance_of(Foo)
27
- result.should respond_to(:a_method)
28
- result.interval.should == (3...6)
29
- result.text_value.should == 'foo'
30
- end
31
- end
32
-
33
- it "fails to parse nonmatching input at the index even if a match occurs later" do
34
- parse(" foo", :index => 0) do |result|
35
- result.should be_nil
36
- parser.terminal_failures.size.should == 1
37
- end
38
- end
39
- end
40
- end
@@ -1,7 +0,0 @@
1
- module Test
2
- grammar Grammar
3
- rule foo
4
- 'foo'
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Test
2
- grammar Grammar
3
- rule foo
4
- 'foo'
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Test
2
- grammar Grammar do
3
- rule foo do
4
- 'foo'
5
- end
6
- end
7
- end
@@ -1,8 +0,0 @@
1
- # coding: UTF-8
2
- module Test
3
- grammar Grammar do
4
- rule foo do
5
- 'foo'
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- # encoding: UTF-8
2
- module Test
3
- grammar Grammar do
4
- rule foo do
5
- 'foo'
6
- end
7
- end
8
- end
@@ -1,224 +0,0 @@
1
- require 'digest/sha1'
2
- require 'tmpdir'
3
-
4
- # ensure the Kernel.system and Kernel.open's always use the correct tt and
5
- # Treetop library versions, not a previously installed gem
6
- ENV['PATH'] = File.expand_path(File.dirname(__FILE__) + '../../../bin' +
7
- File::PATH_SEPARATOR + ENV['PATH'])
8
- $LOAD_PATH.unshift(File.expand_path('../../../../lib', __FILE__))
9
-
10
- describe "The 'tt' comand line compiler" do
11
- before(:each) do
12
- @tmpdir = Dir.tmpdir
13
- end
14
-
15
- context 'when processing a single grammar file' do
16
- before(:each) do
17
- # create a fresh but dumb grammar file for each example
18
- @test_base = "dumb-#{rand(1000)}"
19
- @test_path = "#{@tmpdir}/#{@test_base}"
20
- @test_grammar = "#{@test_path}.tt"
21
- @test_ruby = "#{@test_path}.rb"
22
- File.open(@test_grammar, 'w+') do |f|
23
- f.print("# Encoding: UTF-8\n")
24
- f.print("grammar Dumb\n")
25
- f.print("end\n")
26
- end unless File.exists?(@test_grammar)
27
- end
28
-
29
- after(:each) do
30
- # cleanup test grammar and parser output files
31
- File.delete(@test_grammar) if File.exists?(@test_grammar)
32
- File.delete(@test_ruby) if File.exists?(@test_ruby)
33
- end
34
-
35
- it 'can compile a grammar file' do
36
- # puts %q{emulate 'tt dumb.tt'}
37
- system("ruby -S tt #{@test_grammar}").should be_truthy
38
-
39
- File.exists?(@test_ruby).should be_truthy
40
- File.zero?(@test_ruby).should_not be_truthy
41
- end
42
-
43
- it 'can compile a relative pathed grammar file' do
44
- dir = File.basename(File.expand_path(File.dirname(@test_grammar)))
45
-
46
- # puts %q{emulate 'tt "../<current_dir>/dumb.tt"'}
47
- system("cd #{@tmpdir}/..; ruby -S tt \"./#{dir}/#{@test_base}.tt\"").should be_truthy
48
-
49
- File.exists?(@test_ruby).should be_truthy
50
- File.zero?(@test_ruby).should_not be_truthy
51
- end
52
-
53
- it 'can compile an absolute pathed grammar file' do
54
- # puts %q{emulate 'tt "/path/to/dumb.tt"'}
55
- system("ruby -S tt \"#{File.expand_path(@test_grammar)}\"").should be_truthy
56
-
57
- File.exists?(@test_ruby).should be_truthy
58
- File.zero?(@test_ruby).should_not be_truthy
59
- end
60
-
61
- it 'can compile without explicit file extensions' do
62
- # puts %q{emulate 'tt dumb'}
63
- system("ruby -S tt #{@test_path}").should be_truthy
64
-
65
- File.exists?(@test_ruby).should be_truthy
66
- File.zero?(@test_ruby).should_not be_truthy
67
- end
68
-
69
- it 'skips nonexistent grammar file without failing or creating bogus output' do
70
- # puts %q{emulate 'tt dumb.bad'}
71
- Kernel.open("|ruby -S tt #{@test_base}.bad") do |io|
72
- (io.read =~ /ERROR.*?not exist.*?continuing/).should_not be_nil
73
- end
74
-
75
- File.exists?("#{@test_base}.rb").should be_falsey
76
- end
77
-
78
- it 'can compile to a specified parser source file' do
79
- # puts %q{emulate 'tt -o my_dumb_test_parser.rb dumb'}
80
- pf = "#{@tmpdir}/my_dumb_test_parser.rb"
81
- begin
82
- system("ruby -S tt -o #{pf} #{@test_path}").should be_truthy
83
-
84
- File.exists?(pf).should be_truthy
85
- File.zero?(pf).should_not be_truthy
86
- ensure
87
- File.delete(pf) if File.exists?(pf)
88
- end
89
- end
90
-
91
- it 'by default, does not overwrite an existing file without an autogenerated header' do
92
- # puts %q{emulate 'tt -o must_save_parser.rb dumb'}
93
- pf = "#{@tmpdir}/must_save_parser.rb"
94
- begin
95
- system("ruby -S tt -o #{pf} #{@test_path}").should be_truthy
96
-
97
- File.exists?(pf).should be_truthy
98
- File.zero?(pf).should_not be_truthy
99
-
100
- # Check that the magic comment is preserved:
101
- written = File.open(pf, "r") { |f| s = f.read }
102
- written.should =~ /\A# Encoding: UTF-8/
103
-
104
- # Modify the file's auto-generated comment and make sure it doesn't get overwritten:
105
- written.sub!(/generated/, 'broken');
106
- File.open(pf, "w") { |f| f.write(written) }
107
- # File.open(pf, "r+") { |f| s = f.read; s.sub!(/generated/, 'broken'); f.rewind; f.write(s) }
108
- orig_file_hash = Digest::SHA1.hexdigest(File.read(pf))
109
-
110
- Kernel.open("|ruby -S tt -o #{pf} #{@test_path}") do |io|
111
- (io.read =~ /ERROR.*?already exists.*?skipping/).should_not be_nil
112
- end
113
-
114
- Digest::SHA1.hexdigest(File.read(pf)).should == orig_file_hash
115
- ensure
116
- File.delete(pf) if File.exists?(pf)
117
- end
118
- end
119
-
120
- it 'by default, overwrites a changed file with an intact autogenerated header' do
121
- # puts %q{emulate 'tt -o must_save_parser.rb dumb'}
122
- pf = "#{@tmpdir}/must_save_parser.rb"
123
- begin
124
- system("ruby -S tt -o #{pf} #{@test_path}").should be_truthy
125
-
126
- File.exists?(pf).should be_truthy
127
- File.zero?(pf).should_not be_truthy
128
- orig_file_hash = Digest::SHA1.hexdigest(File.read(pf))
129
-
130
- # Modify the file and make sure it gets reverted:
131
- File.open(pf, "r+") { |f| f.gets; f.write("#") }
132
-
133
- system("ruby -S tt -o #{pf} #{@test_path}").should be_truthy
134
- Digest::SHA1.hexdigest(File.read(pf)).should == orig_file_hash
135
- ensure
136
- File.delete(pf) if File.exists?(pf)
137
- end
138
- end
139
-
140
- it 'can be forced to overwrite existing file #{@test_path}' do
141
- pf = "#{@test_path}.rb"
142
- system("echo some junk >#{pf}").should be_truthy
143
-
144
- File.exists?(pf).should be_truthy
145
- File.zero?(pf).should_not be_truthy
146
- orig_file_hash = Digest::SHA1.hexdigest(File.read(pf))
147
-
148
- system("ruby -S tt -f #{@test_path}").should be_truthy
149
- Digest::SHA1.hexdigest(File.read(pf)).should_not == orig_file_hash
150
- end
151
-
152
- end
153
-
154
- context 'when processing multiple grammar files' do
155
-
156
- before(:each) do
157
- # provide fresh but dumb grammar files for each test
158
- @test_bases = []
159
- @test_grammars = []
160
-
161
- %w[dumb1 dumb2].each do |e|
162
- base = "#{@tmpdir}/#{e}-#{rand(1000)}"
163
- grammar_file = "#{base}.tt"
164
- @test_bases << base
165
- @test_grammars << grammar_file
166
-
167
- File.open(grammar_file, 'w+') do |f|
168
- f.print("grammar #{e.capitalize}\n")
169
- f.print("end\n")
170
- end unless File.exists?(grammar_file)
171
- end
172
- end
173
-
174
- after(:each) do
175
- # cleanup test grammar and output parser files
176
- @test_grammars.each { |f| File.delete(f) if File.exists?(f) }
177
- @test_bases.each { |f| File.delete("#{f}.rb") if File.exists?("#{f}.rb") }
178
- end
179
-
180
- it 'can compile them in one invocation' do
181
- # puts %q{emulate 'tt dumb1.tt dumb2.tt'}
182
- system("ruby -S tt #{@test_grammars.join(' ')}").should be_truthy
183
-
184
- @test_bases.each do |f|
185
- pf = "#{f}.rb"
186
- File.exists?(pf).should be_truthy
187
- File.zero?(pf).should_not be_truthy
188
- end
189
- end
190
-
191
- it 'can compile them without explicit file extenstions' do
192
- # puts %q{emulate 'tt dumb1 dumb2'}
193
- system("ruby -S tt #{@test_bases.join(' ')}").should be_truthy
194
-
195
- @test_bases.each do |f|
196
- pf = "#{f}.rb"
197
- File.exists?(pf).should be_truthy
198
- File.zero?(pf).should_not be_truthy
199
- end
200
- end
201
-
202
- it 'can skip nonexistent and invalid extension named grammar files' do
203
- # puts %q{emulate 'tt not_here bad_ext.ttg dumb1 dumb2'}
204
- system("ruby -S tt not_here bad_ext.ttg #{@test_bases.join(' ')} >/dev/null 2>&1").should be_truthy
205
-
206
- File.exists?('not_here.rb').should_not be_truthy
207
- File.exists?('bad_ext.rb').should_not be_truthy
208
-
209
- @test_bases.each do |f|
210
- pf = "#{f}.rb"
211
- File.exists?(pf).should be_truthy
212
- File.zero?(pf).should_not be_truthy
213
- end
214
- end
215
-
216
- it 'can not specify an output file' do
217
- # puts %q{emulate 'tt -o my_bogus_test_parser.rb dumb1 dumb2'}
218
- pf = 'my_bogus_test_parser.rb'
219
- system("ruby -S tt -o #{pf} #{@test_bases.join(' ')} >/dev/null 2>&1").should be_falsey
220
- File.exists?(pf).should be_falsey
221
- end
222
- end
223
-
224
- end