plurimath-parslet 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.txt +284 -0
  3. data/LICENSE +23 -0
  4. data/README.adoc +454 -0
  5. data/Rakefile +71 -0
  6. data/lib/parslet/accelerator/application.rb +62 -0
  7. data/lib/parslet/accelerator/engine.rb +112 -0
  8. data/lib/parslet/accelerator.rb +162 -0
  9. data/lib/parslet/atoms/alternative.rb +53 -0
  10. data/lib/parslet/atoms/base.rb +157 -0
  11. data/lib/parslet/atoms/can_flatten.rb +137 -0
  12. data/lib/parslet/atoms/capture.rb +38 -0
  13. data/lib/parslet/atoms/context.rb +103 -0
  14. data/lib/parslet/atoms/dsl.rb +112 -0
  15. data/lib/parslet/atoms/dynamic.rb +32 -0
  16. data/lib/parslet/atoms/entity.rb +45 -0
  17. data/lib/parslet/atoms/ignored.rb +26 -0
  18. data/lib/parslet/atoms/infix.rb +115 -0
  19. data/lib/parslet/atoms/lookahead.rb +52 -0
  20. data/lib/parslet/atoms/named.rb +32 -0
  21. data/lib/parslet/atoms/re.rb +41 -0
  22. data/lib/parslet/atoms/repetition.rb +87 -0
  23. data/lib/parslet/atoms/scope.rb +26 -0
  24. data/lib/parslet/atoms/sequence.rb +48 -0
  25. data/lib/parslet/atoms/str.rb +42 -0
  26. data/lib/parslet/atoms/visitor.rb +89 -0
  27. data/lib/parslet/atoms.rb +34 -0
  28. data/lib/parslet/cause.rb +101 -0
  29. data/lib/parslet/context.rb +21 -0
  30. data/lib/parslet/convenience.rb +33 -0
  31. data/lib/parslet/error_reporter/contextual.rb +120 -0
  32. data/lib/parslet/error_reporter/deepest.rb +100 -0
  33. data/lib/parslet/error_reporter/tree.rb +63 -0
  34. data/lib/parslet/error_reporter.rb +8 -0
  35. data/lib/parslet/export.rb +163 -0
  36. data/lib/parslet/expression/treetop.rb +92 -0
  37. data/lib/parslet/expression.rb +51 -0
  38. data/lib/parslet/graphviz.rb +97 -0
  39. data/lib/parslet/parser.rb +68 -0
  40. data/lib/parslet/pattern/binding.rb +49 -0
  41. data/lib/parslet/pattern.rb +113 -0
  42. data/lib/parslet/position.rb +21 -0
  43. data/lib/parslet/rig/rspec.rb +52 -0
  44. data/lib/parslet/scope.rb +42 -0
  45. data/lib/parslet/slice.rb +105 -0
  46. data/lib/parslet/source/line_cache.rb +99 -0
  47. data/lib/parslet/source.rb +96 -0
  48. data/lib/parslet/transform.rb +265 -0
  49. data/lib/parslet/version.rb +5 -0
  50. data/lib/parslet.rb +314 -0
  51. data/plurimath-parslet.gemspec +42 -0
  52. data/spec/acceptance/infix_parser_spec.rb +145 -0
  53. data/spec/acceptance/mixing_parsers_spec.rb +74 -0
  54. data/spec/acceptance/regression_spec.rb +329 -0
  55. data/spec/acceptance/repetition_and_maybe_spec.rb +44 -0
  56. data/spec/acceptance/unconsumed_input_spec.rb +21 -0
  57. data/spec/examples/boolean_algebra_spec.rb +257 -0
  58. data/spec/examples/calc_spec.rb +278 -0
  59. data/spec/examples/capture_spec.rb +137 -0
  60. data/spec/examples/comments_spec.rb +186 -0
  61. data/spec/examples/deepest_errors_spec.rb +420 -0
  62. data/spec/examples/documentation_spec.rb +205 -0
  63. data/spec/examples/email_parser_spec.rb +275 -0
  64. data/spec/examples/empty_spec.rb +37 -0
  65. data/spec/examples/erb_spec.rb +482 -0
  66. data/spec/examples/ip_address_spec.rb +153 -0
  67. data/spec/examples/json_spec.rb +413 -0
  68. data/spec/examples/local_spec.rb +302 -0
  69. data/spec/examples/mathn_spec.rb +151 -0
  70. data/spec/examples/minilisp_spec.rb +492 -0
  71. data/spec/examples/modularity_spec.rb +340 -0
  72. data/spec/examples/nested_errors_spec.rb +322 -0
  73. data/spec/examples/optimized_erb_spec.rb +299 -0
  74. data/spec/examples/parens_spec.rb +239 -0
  75. data/spec/examples/prec_calc_spec.rb +525 -0
  76. data/spec/examples/readme_spec.rb +228 -0
  77. data/spec/examples/scopes_spec.rb +187 -0
  78. data/spec/examples/seasons_spec.rb +196 -0
  79. data/spec/examples/sentence_spec.rb +119 -0
  80. data/spec/examples/simple_xml_spec.rb +250 -0
  81. data/spec/examples/string_parser_spec.rb +407 -0
  82. data/spec/fixtures/examples/boolean_algebra.rb +62 -0
  83. data/spec/fixtures/examples/calc.rb +86 -0
  84. data/spec/fixtures/examples/capture.rb +36 -0
  85. data/spec/fixtures/examples/comments.rb +22 -0
  86. data/spec/fixtures/examples/deepest_errors.rb +99 -0
  87. data/spec/fixtures/examples/documentation.rb +32 -0
  88. data/spec/fixtures/examples/email_parser.rb +42 -0
  89. data/spec/fixtures/examples/empty.rb +10 -0
  90. data/spec/fixtures/examples/erb.rb +39 -0
  91. data/spec/fixtures/examples/ip_address.rb +103 -0
  92. data/spec/fixtures/examples/json.rb +107 -0
  93. data/spec/fixtures/examples/local.rb +60 -0
  94. data/spec/fixtures/examples/mathn.rb +47 -0
  95. data/spec/fixtures/examples/minilisp.rb +75 -0
  96. data/spec/fixtures/examples/modularity.rb +60 -0
  97. data/spec/fixtures/examples/nested_errors.rb +95 -0
  98. data/spec/fixtures/examples/optimized_erb.rb +105 -0
  99. data/spec/fixtures/examples/parens.rb +25 -0
  100. data/spec/fixtures/examples/prec_calc.rb +71 -0
  101. data/spec/fixtures/examples/readme.rb +59 -0
  102. data/spec/fixtures/examples/scopes.rb +43 -0
  103. data/spec/fixtures/examples/seasons.rb +40 -0
  104. data/spec/fixtures/examples/sentence.rb +18 -0
  105. data/spec/fixtures/examples/simple_xml.rb +51 -0
  106. data/spec/fixtures/examples/string_parser.rb +77 -0
  107. data/spec/parslet/atom_results_spec.rb +39 -0
  108. data/spec/parslet/atoms/alternative_spec.rb +26 -0
  109. data/spec/parslet/atoms/base_spec.rb +127 -0
  110. data/spec/parslet/atoms/capture_spec.rb +21 -0
  111. data/spec/parslet/atoms/combinations_spec.rb +5 -0
  112. data/spec/parslet/atoms/dsl_spec.rb +7 -0
  113. data/spec/parslet/atoms/entity_spec.rb +77 -0
  114. data/spec/parslet/atoms/ignored_spec.rb +15 -0
  115. data/spec/parslet/atoms/infix_spec.rb +5 -0
  116. data/spec/parslet/atoms/lookahead_spec.rb +22 -0
  117. data/spec/parslet/atoms/named_spec.rb +4 -0
  118. data/spec/parslet/atoms/re_spec.rb +14 -0
  119. data/spec/parslet/atoms/repetition_spec.rb +24 -0
  120. data/spec/parslet/atoms/scope_spec.rb +26 -0
  121. data/spec/parslet/atoms/sequence_spec.rb +28 -0
  122. data/spec/parslet/atoms/str_spec.rb +15 -0
  123. data/spec/parslet/atoms/visitor_spec.rb +101 -0
  124. data/spec/parslet/atoms_spec.rb +488 -0
  125. data/spec/parslet/convenience_spec.rb +54 -0
  126. data/spec/parslet/error_reporter/contextual_spec.rb +118 -0
  127. data/spec/parslet/error_reporter/deepest_spec.rb +82 -0
  128. data/spec/parslet/error_reporter/tree_spec.rb +7 -0
  129. data/spec/parslet/export_spec.rb +40 -0
  130. data/spec/parslet/expression/treetop_spec.rb +74 -0
  131. data/spec/parslet/minilisp.citrus +29 -0
  132. data/spec/parslet/minilisp.tt +29 -0
  133. data/spec/parslet/parser_spec.rb +36 -0
  134. data/spec/parslet/parslet_spec.rb +38 -0
  135. data/spec/parslet/pattern_spec.rb +272 -0
  136. data/spec/parslet/position_spec.rb +14 -0
  137. data/spec/parslet/rig/rspec_spec.rb +54 -0
  138. data/spec/parslet/scope_spec.rb +45 -0
  139. data/spec/parslet/slice_spec.rb +186 -0
  140. data/spec/parslet/source/line_cache_spec.rb +74 -0
  141. data/spec/parslet/source_spec.rb +210 -0
  142. data/spec/parslet/transform/context_spec.rb +56 -0
  143. data/spec/parslet/transform_spec.rb +183 -0
  144. data/spec/spec_helper.rb +74 -0
  145. data/spec/support/opal.rb +8 -0
  146. data/spec/support/opal.rb.erb +14 -0
  147. data/spec/support/parslet_matchers.rb +96 -0
  148. metadata +240 -0
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Base do
4
+ let(:parslet) { Parslet::Atoms::Base.new }
5
+ let(:context) { Parslet::Atoms::Context.new }
6
+
7
+ describe '<- #try(io)' do
8
+ it 'raises NotImplementedError' do
9
+ lambda {
10
+ parslet.try(double(:io), context, false)
11
+ }.should raise_error(NotImplementedError)
12
+ end
13
+ end
14
+
15
+ describe '<- #flatten_sequence' do
16
+ [
17
+ # 9 possibilities for making a word of 2 letters from the alphabeth of
18
+ # A(rray), H(ash) and S(tring). Make sure that all results are valid.
19
+ #
20
+ %w[a b], 'ab', # S S
21
+ [['a'], ['b']], %w[a b], # A A
22
+ [{ a: 'a' }, { b: 'b' }], { a: 'a', b: 'b' }, # H H
23
+
24
+ [{ a: 'a' }, ['a']], [{ a: 'a' }, 'a'], # H A
25
+ [{ a: 'a' }, 's'], { a: 'a' }, # H S
26
+
27
+ [['a'], { a: 'a' }], ['a', { a: 'a' }], # A H (symmetric to H A)
28
+ [['a'], 'b'], ['a'], # A S
29
+
30
+ ['a', { b: 'b' }], { b: 'b' }, # S H (symmetric to H S)
31
+ ['a', ['b']], ['b'], # S A (symmetric to A S)
32
+
33
+ [nil, ['a']], ['a'], # handling of lhs nil
34
+ [nil, { a: 'a' }], { a: 'a' },
35
+ [['a'], nil], ['a'], # handling of rhs nil
36
+ [{ a: 'a' }, nil], { a: 'a' }
37
+ ].each_slice(2) do |sequence, result|
38
+ context 'for ' + sequence.inspect do
39
+ it "equals #{result.inspect}" do
40
+ parslet.flatten_sequence(sequence).should == result
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ describe '<- #flatten_repetition' do
47
+ def unnamed(obj)
48
+ parslet.flatten_repetition(obj, false)
49
+ end
50
+
51
+ it 'gives subtrees precedence' do
52
+ unnamed([[{ a: 'a' }, { m: 'm' }], { a: 'a' }]).should == [{ a: 'a' }]
53
+ end
54
+ end
55
+
56
+ describe '#parse(source)' do
57
+ context 'when given something that looks like a source' do
58
+ let(:source) do
59
+ double('source lookalike',
60
+ line_and_column: [1, 2],
61
+ bytepos: 1,
62
+ chars_left: 0)
63
+ end
64
+
65
+ it 'does not rewrap in a source' do
66
+ expect(Parslet::Source).not_to receive(:new)
67
+
68
+ begin
69
+ parslet.parse(source)
70
+ rescue NotImplementedError
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'when the parse fails, the exception' do
77
+ it 'contains a string' do
78
+ Parslet.str('foo').parse('bar')
79
+ rescue Parslet::ParseFailed => e
80
+ e.message.should be_kind_of(String)
81
+ end
82
+ end
83
+
84
+ context 'when not all input is consumed' do
85
+ let(:parslet) { Parslet.str('foo') }
86
+
87
+ it 'raises with a proper error message' do
88
+ error = catch_failed_parse do
89
+ parslet.parse('foobar')
90
+ end
91
+
92
+ error.to_s.should == "Don't know what to do with \"bar\" at line 1 char 4."
93
+ end
94
+ end
95
+
96
+ context 'when only parsing string prefix' do
97
+ let(:parslet) { Parslet.str('foo') >> Parslet.str('bar') }
98
+
99
+ it 'returns the first half on a prefix parse' do
100
+ parslet.parse('foobarbaz', prefix: true).should == 'foobar'
101
+ end
102
+ end
103
+
104
+ describe ':reporter option' do
105
+ let(:parslet) { Parslet.str('test') >> Parslet.str('ing') }
106
+ let(:reporter) { double(:reporter) }
107
+
108
+ it 'replaces the default reporter' do
109
+ cause = double(:cause)
110
+
111
+ # Two levels of the parse, calling two different error reporting
112
+ # methods.
113
+ expect(reporter).to receive(:err_at).once
114
+ expect(reporter).to receive(:err).and_return(cause).once
115
+ expect(reporter).to receive(:succ).once
116
+
117
+ # The final cause will be sent the #raise method.
118
+ expect(cause).to receive(:raise).once.and_throw(:raise)
119
+
120
+ catch(:raise) do
121
+ parslet.parse('testung', reporter: reporter)
122
+
123
+ raise 'NEVER REACHED'
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Capture do
4
+ include Parslet
5
+
6
+ let(:context) { Parslet::Atoms::Context.new(nil) }
7
+
8
+ def inject string, parser
9
+ source = Parslet::Source.new(string)
10
+ parser.apply(source, context, true)
11
+ end
12
+
13
+ it "should capture simple results" do
14
+ inject 'a', str('a').capture(:a)
15
+ context.captures[:a].should == 'a'
16
+ end
17
+ it "should capture complex results" do
18
+ inject 'a', str('a').as(:b).capture(:a)
19
+ context.captures[:a].should == {:b => 'a'}
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Parslet combinations" do
4
+ include Parslet
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::DSL do
4
+ describe "deprecated methods" do
5
+ let(:parslet) { Parslet.str('foo') }
6
+ end
7
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Entity do
4
+ context "when constructed with str('bar') inside" do
5
+ let(:named) { Parslet::Atoms::Entity.new('name', &proc { Parslet.str('bar') }) }
6
+
7
+ it "should parse 'bar' without raising exceptions" do
8
+ named.parse('bar')
9
+ end
10
+ it "should raise when applied to 'foo'" do
11
+ lambda {
12
+ named.parse('foo')
13
+ }.should raise_error(Parslet::ParseFailed)
14
+ end
15
+
16
+ describe "#inspect" do
17
+ it "should return the name of the entity" do
18
+ named.inspect.should == 'NAME'
19
+ end
20
+ end
21
+ end
22
+ context "when constructed with empty block" do
23
+ let(:entity) { Parslet::Atoms::Entity.new('name', &proc { }) }
24
+
25
+ it "should raise NotImplementedError" do
26
+ lambda {
27
+ entity.parse('some_string')
28
+ }.should raise_error(NotImplementedError)
29
+ end
30
+ end
31
+
32
+ context "recursive definition parser" do
33
+ class RecDefParser
34
+ include Parslet
35
+ rule :recdef do
36
+ str('(') >> atom >> str(')')
37
+ end
38
+ rule :atom do
39
+ str('a') | str('b') | recdef
40
+ end
41
+ end
42
+ let(:parser) { RecDefParser.new }
43
+
44
+ it "should parse balanced parens" do
45
+ parser.recdef.parse("(((a)))")
46
+ end
47
+ it "should not throw 'stack level too deep' when printing errors" do
48
+ cause = catch_failed_parse { parser.recdef.parse('(((a))') }
49
+ cause.ascii_tree
50
+ end
51
+ end
52
+
53
+ context "when constructed with a label" do
54
+ let(:named) { Parslet::Atoms::Entity.new('name', 'label', &proc { Parslet.str('bar') }) }
55
+
56
+ it "should parse 'bar' without raising exceptions" do
57
+ named.parse('bar')
58
+ end
59
+ it "should raise when applied to 'foo'" do
60
+ lambda {
61
+ named.parse('foo')
62
+ }.should raise_error(Parslet::ParseFailed)
63
+ end
64
+
65
+ describe "#inspect" do
66
+ it "should return the label of the entity" do
67
+ named.inspect.should == 'label'
68
+ end
69
+ end
70
+
71
+ describe "#parslet" do
72
+ it "should set the label on the cached parslet" do
73
+ named.parslet.label.should == 'label'
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Ignored do
4
+ include Parslet
5
+
6
+ describe "ignore" do
7
+ it "ignores parts of the input" do
8
+ str('a').ignore.parse('a').should == nil
9
+ (str('a') >> str('b').ignore >> str('c')).parse('abc').should == 'ac'
10
+ (str('a') >> str('b').as(:name).ignore >> str('c')).parse('abc').should == 'ac'
11
+ (str('a') >> str('b').maybe.ignore >> str('c')).parse('abc').should == 'ac'
12
+ (str('a') >> str('b').maybe.ignore >> str('c')).parse('ac').should == 'ac'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Infix do
4
+
5
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Lookahead do
4
+ include Parslet
5
+
6
+ describe 'negative lookahead' do
7
+ it "influences the error tree" do
8
+ parser = str('f').absent? >> str('b')
9
+ cause = catch_failed_parse { parser.parse('f') }
10
+
11
+ cause.ascii_tree.should == "Failed to match sequence (!'f' 'b') at line 1 char 1.\n`- Input should not start with 'f' at line 1 char 1.\n"
12
+ end
13
+ end
14
+ describe 'positive lookahead' do
15
+ it "influences the error tree" do
16
+ parser = str('f').present? >> str('b')
17
+ cause = catch_failed_parse { parser.parse('b') }
18
+
19
+ cause.ascii_tree.should == "Failed to match sequence (&'f' 'b') at line 1 char 1.\n`- Input should start with 'f' at line 1 char 1.\n"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Named do
4
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Re do
4
+ describe "construction" do
5
+ include Parslet
6
+
7
+ it "should allow match(str) form" do
8
+ Parslet.match('[a]').should be_a(Parslet::Atoms::Re)
9
+ end
10
+ it "should allow match[str] form" do
11
+ Parslet.match['a'].should be_a(Parslet::Atoms::Re)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Repetition do
4
+ include Parslet
5
+
6
+ describe "repeat" do
7
+ let(:parslet) { str('a') }
8
+
9
+ describe "(min, max)" do
10
+ subject { parslet.repeat(1,2) }
11
+
12
+ it { should_not parse("") }
13
+ it { should parse("a") }
14
+ it { should parse("aa") }
15
+ end
16
+ describe "0 times" do
17
+ it "raises an ArgumentError" do
18
+ expect {
19
+ parslet.repeat(0,0)
20
+ }.to raise_error(ArgumentError)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Scope do
4
+ include Parslet
5
+ include Parslet::Atoms::DSL
6
+
7
+
8
+ let(:context) { Parslet::Atoms::Context.new(nil) }
9
+ let(:captures) { context.captures }
10
+
11
+ def inject string, parser
12
+ source = Parslet::Source.new(string)
13
+ parser.apply(source, context, true)
14
+ end
15
+
16
+ let(:aabb) {
17
+ scope {
18
+ Parslet.match['ab'].capture(:f) >> dynamic { |s,c| str(c.captures[:f]) }
19
+ }
20
+ }
21
+ it "keeps values of captures outside" do
22
+ captures[:f] = 'old_value'
23
+ inject 'aa', aabb
24
+ captures[:f].should == 'old_value'
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms::Sequence do
4
+ include Parslet
5
+
6
+ let(:sequence) { described_class.new }
7
+
8
+ describe '>> shortcut' do
9
+ let(:sequence) { str('a') >> str('b') }
10
+
11
+ context "when chained with different atoms" do
12
+ before(:each) {
13
+ # Chain something else to the sequence parslet. If it modifies the
14
+ # parslet atom in place, we'll notice:
15
+
16
+ sequence >> str('d')
17
+ }
18
+ let!(:chained) { sequence >> str('c') }
19
+
20
+
21
+ it "is side-effect free" do
22
+ chained.should parse('abc')
23
+ chained.should_not parse('abdc')
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ # Encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Parslet::Atoms::Str do
6
+ def str(s)
7
+ described_class.new(s)
8
+ end
9
+
10
+ describe 'regression #1: multibyte characters' do
11
+ it "parses successfully (length check works)" do
12
+ str('あああ').should parse('あああ')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Parslet::Atoms do
4
+ include Parslet
5
+ let(:visitor) { double(:visitor) }
6
+
7
+ describe Parslet::Atoms::Str do
8
+ let(:parslet) { str('foo') }
9
+
10
+ it 'calls back visitor' do
11
+ expect(visitor).to receive(:visit_str).with('foo').once
12
+
13
+ parslet.accept(visitor)
14
+ end
15
+ end
16
+
17
+ describe Parslet::Atoms::Re do
18
+ let(:parslet) { Parslet.match['abc'] }
19
+
20
+ it 'calls back visitor' do
21
+ expect(visitor).to receive(:visit_re).with('[abc]').once
22
+
23
+ parslet.accept(visitor)
24
+ end
25
+ end
26
+
27
+ describe Parslet::Atoms::Sequence do
28
+ let(:parslet) { str('a') >> str('b') }
29
+
30
+ it 'calls back visitor' do
31
+ expect(visitor).to receive(:visit_sequence).with(Array).once
32
+
33
+ parslet.accept(visitor)
34
+ end
35
+ end
36
+
37
+ describe Parslet::Atoms::Repetition do
38
+ let(:parslet) { str('a').repeat(1, 2) }
39
+
40
+ it 'calls back visitor' do
41
+ expect(visitor).to receive(:visit_repetition).with(:repetition, 1, 2, Parslet::Atoms::Base).once
42
+
43
+ parslet.accept(visitor)
44
+ end
45
+ end
46
+
47
+ describe Parslet::Atoms::Alternative do
48
+ let(:parslet) { str('a') | str('b') }
49
+
50
+ it 'calls back visitor' do
51
+ expect(visitor).to receive(:visit_alternative).with(Array).once
52
+
53
+ parslet.accept(visitor)
54
+ end
55
+ end
56
+
57
+ describe Parslet::Atoms::Named do
58
+ let(:parslet) { str('a').as(:a) }
59
+
60
+ it 'calls back visitor' do
61
+ expect(visitor).to receive(:visit_named).with(:a, Parslet::Atoms::Base).once
62
+
63
+ parslet.accept(visitor)
64
+ end
65
+ end
66
+
67
+ describe Parslet::Atoms::Entity do
68
+ let(:parslet) { Parslet::Atoms::Entity.new('foo', &-> {}) }
69
+
70
+ it 'calls back visitor' do
71
+ expect(visitor).to receive(:visit_entity).with('foo', Proc).once
72
+
73
+ parslet.accept(visitor)
74
+ end
75
+ end
76
+
77
+ describe Parslet::Atoms::Lookahead do
78
+ let(:parslet) { str('a').absent? }
79
+
80
+ it 'calls back visitor' do
81
+ expect(visitor).to receive(:visit_lookahead).with(false, Parslet::Atoms::Base).once
82
+
83
+ parslet.accept(visitor)
84
+ end
85
+ end
86
+
87
+ describe '< Parslet::Parser' do
88
+ let(:parslet) do
89
+ Class.new(Parslet::Parser) do
90
+ rule(:test_rule) { str('test') }
91
+ root(:test_rule)
92
+ end.new
93
+ end
94
+
95
+ it 'calls back to visitor' do
96
+ expect(visitor).to receive(:visit_parser).with(Parslet::Atoms::Base).once
97
+
98
+ parslet.accept(visitor)
99
+ end
100
+ end
101
+ end