mail 1.3.3 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mail might be problematic. Click here for more details.

Files changed (129) hide show
  1. data/Rakefile +1 -1
  2. data/lib/mail.rb +2 -1
  3. data/lib/mail/version.rb +1 -1
  4. data/lib/vendor/treetop-1.4.3/History.txt +18 -0
  5. data/lib/vendor/treetop-1.4.3/LICENSE +19 -0
  6. data/lib/vendor/treetop-1.4.3/README.md +164 -0
  7. data/lib/vendor/treetop-1.4.3/Rakefile +23 -0
  8. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
  9. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
  10. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/designable.nib +1524 -0
  11. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/keyedobjects.nib +0 -0
  12. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Support/syntax_tree_viewer.rb +117 -0
  13. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +251 -0
  14. data/lib/vendor/treetop-1.4.3/Treetop.tmbundle/info.plist +10 -0
  15. data/lib/vendor/treetop-1.4.3/benchmark/seqpar.gnuplot +15 -0
  16. data/lib/vendor/treetop-1.4.3/benchmark/seqpar.treetop +16 -0
  17. data/lib/vendor/treetop-1.4.3/benchmark/seqpar_benchmark.rb +107 -0
  18. data/lib/vendor/treetop-1.4.3/bin/tt +112 -0
  19. data/lib/vendor/treetop-1.4.3/doc/contributing_and_planned_features.markdown +103 -0
  20. data/lib/vendor/treetop-1.4.3/doc/grammar_composition.markdown +65 -0
  21. data/lib/vendor/treetop-1.4.3/doc/index.markdown +90 -0
  22. data/lib/vendor/treetop-1.4.3/doc/pitfalls_and_advanced_techniques.markdown +51 -0
  23. data/lib/vendor/treetop-1.4.3/doc/semantic_interpretation.markdown +189 -0
  24. data/lib/vendor/treetop-1.4.3/doc/site.rb +112 -0
  25. data/lib/vendor/treetop-1.4.3/doc/sitegen.rb +65 -0
  26. data/lib/vendor/treetop-1.4.3/doc/syntactic_recognition.markdown +100 -0
  27. data/lib/vendor/treetop-1.4.3/doc/using_in_ruby.markdown +21 -0
  28. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/arithmetic.rb +551 -0
  29. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/arithmetic.treetop +97 -0
  30. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/arithmetic_node_classes.rb +7 -0
  31. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/arithmetic_test.rb +54 -0
  32. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus +0 -0
  33. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus.rb +718 -0
  34. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus.treetop +132 -0
  35. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus_node_classes.rb +5 -0
  36. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/lambda_calculus_test.rb +89 -0
  37. data/lib/vendor/treetop-1.4.3/examples/lambda_calculus/test_helper.rb +18 -0
  38. data/lib/vendor/treetop-1.4.3/lib/treetop.rb +17 -0
  39. data/lib/vendor/treetop-1.4.3/lib/treetop/bootstrap_gen_1_metagrammar.rb +45 -0
  40. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler.rb +6 -0
  41. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/grammar_compiler.rb +44 -0
  42. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/lexical_address_space.rb +17 -0
  43. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/metagrammar.rb +3366 -0
  44. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/metagrammar.treetop +436 -0
  45. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes.rb +20 -0
  46. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/anything_symbol.rb +18 -0
  47. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/atomic_expression.rb +14 -0
  48. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/character_class.rb +28 -0
  49. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/choice.rb +31 -0
  50. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
  51. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/grammar.rb +28 -0
  52. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
  53. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/nonterminal.rb +13 -0
  54. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/optional.rb +19 -0
  55. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
  56. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/parsing_expression.rb +146 -0
  57. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/parsing_rule.rb +58 -0
  58. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/predicate.rb +45 -0
  59. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/predicate_block.rb +16 -0
  60. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/repetition.rb +55 -0
  61. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/sequence.rb +71 -0
  62. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/terminal.rb +20 -0
  63. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
  64. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
  65. data/lib/vendor/treetop-1.4.3/lib/treetop/compiler/ruby_builder.rb +113 -0
  66. data/lib/vendor/treetop-1.4.3/lib/treetop/ruby_extensions.rb +2 -0
  67. data/lib/vendor/treetop-1.4.3/lib/treetop/ruby_extensions/string.rb +42 -0
  68. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime.rb +5 -0
  69. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/compiled_parser.rb +110 -0
  70. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list.rb +4 -0
  71. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
  72. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
  73. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
  74. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/syntax_node.rb +114 -0
  75. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/terminal_parse_failure.rb +16 -0
  76. data/lib/vendor/treetop-1.4.3/lib/treetop/runtime/terminal_syntax_node.rb +17 -0
  77. data/lib/vendor/treetop-1.4.3/lib/treetop/version.rb +9 -0
  78. data/lib/vendor/treetop-1.4.3/script/generate_metagrammar.rb +14 -0
  79. data/lib/vendor/treetop-1.4.3/script/svnadd +11 -0
  80. data/lib/vendor/treetop-1.4.3/script/svnrm +11 -0
  81. data/lib/vendor/treetop-1.4.3/spec/compiler/and_predicate_spec.rb +36 -0
  82. data/lib/vendor/treetop-1.4.3/spec/compiler/anything_symbol_spec.rb +44 -0
  83. data/lib/vendor/treetop-1.4.3/spec/compiler/character_class_spec.rb +276 -0
  84. data/lib/vendor/treetop-1.4.3/spec/compiler/choice_spec.rb +80 -0
  85. data/lib/vendor/treetop-1.4.3/spec/compiler/circular_compilation_spec.rb +28 -0
  86. data/lib/vendor/treetop-1.4.3/spec/compiler/failure_propagation_functional_spec.rb +21 -0
  87. data/lib/vendor/treetop-1.4.3/spec/compiler/grammar_compiler_spec.rb +84 -0
  88. data/lib/vendor/treetop-1.4.3/spec/compiler/grammar_spec.rb +41 -0
  89. data/lib/vendor/treetop-1.4.3/spec/compiler/multibyte_chars_spec.rb +46 -0
  90. data/lib/vendor/treetop-1.4.3/spec/compiler/nonterminal_symbol_spec.rb +40 -0
  91. data/lib/vendor/treetop-1.4.3/spec/compiler/not_predicate_spec.rb +38 -0
  92. data/lib/vendor/treetop-1.4.3/spec/compiler/one_or_more_spec.rb +35 -0
  93. data/lib/vendor/treetop-1.4.3/spec/compiler/optional_spec.rb +37 -0
  94. data/lib/vendor/treetop-1.4.3/spec/compiler/parenthesized_expression_spec.rb +19 -0
  95. data/lib/vendor/treetop-1.4.3/spec/compiler/parsing_rule_spec.rb +61 -0
  96. data/lib/vendor/treetop-1.4.3/spec/compiler/repeated_subrule_spec.rb +29 -0
  97. data/lib/vendor/treetop-1.4.3/spec/compiler/semantic_predicate_spec.rb +175 -0
  98. data/lib/vendor/treetop-1.4.3/spec/compiler/sequence_spec.rb +115 -0
  99. data/lib/vendor/treetop-1.4.3/spec/compiler/terminal_spec.rb +81 -0
  100. data/lib/vendor/treetop-1.4.3/spec/compiler/terminal_symbol_spec.rb +37 -0
  101. data/lib/vendor/treetop-1.4.3/spec/compiler/test_grammar.treetop +7 -0
  102. data/lib/vendor/treetop-1.4.3/spec/compiler/test_grammar.tt +7 -0
  103. data/lib/vendor/treetop-1.4.3/spec/compiler/test_grammar_do.treetop +7 -0
  104. data/lib/vendor/treetop-1.4.3/spec/compiler/tt_compiler_spec.rb +216 -0
  105. data/lib/vendor/treetop-1.4.3/spec/compiler/zero_or_more_spec.rb +56 -0
  106. data/lib/vendor/treetop-1.4.3/spec/composition/a.treetop +11 -0
  107. data/lib/vendor/treetop-1.4.3/spec/composition/b.treetop +11 -0
  108. data/lib/vendor/treetop-1.4.3/spec/composition/c.treetop +10 -0
  109. data/lib/vendor/treetop-1.4.3/spec/composition/d.treetop +10 -0
  110. data/lib/vendor/treetop-1.4.3/spec/composition/f.treetop +17 -0
  111. data/lib/vendor/treetop-1.4.3/spec/composition/grammar_composition_spec.rb +40 -0
  112. data/lib/vendor/treetop-1.4.3/spec/composition/subfolder/e_includes_c.treetop +15 -0
  113. data/lib/vendor/treetop-1.4.3/spec/ruby_extensions/string_spec.rb +32 -0
  114. data/lib/vendor/treetop-1.4.3/spec/runtime/compiled_parser_spec.rb +101 -0
  115. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/delete_spec.rb +147 -0
  116. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/expire_range_spec.rb +349 -0
  117. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/insert_and_delete_node.rb +385 -0
  118. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/insert_spec.rb +660 -0
  119. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +6175 -0
  120. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +58 -0
  121. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/palindromic_fixture.rb +23 -0
  122. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +164 -0
  123. data/lib/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/spec_helper.rb +84 -0
  124. data/lib/vendor/treetop-1.4.3/spec/runtime/syntax_node_spec.rb +77 -0
  125. data/lib/vendor/treetop-1.4.3/spec/spec_helper.rb +110 -0
  126. data/lib/vendor/treetop-1.4.3/spec/spec_suite.rb +4 -0
  127. data/lib/vendor/treetop-1.4.3/treetop.gemspec +18 -0
  128. data/lib/vendor/treetop.rb +5 -0
  129. metadata +126 -11
@@ -0,0 +1,4 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/interval_skip_list/interval_skip_list.rb"
3
+ require "#{dir}/interval_skip_list/head_node.rb"
4
+ require "#{dir}/interval_skip_list/node.rb"
@@ -0,0 +1,15 @@
1
+ class IntervalSkipList
2
+ class HeadNode
3
+ attr_reader :height, :forward, :forward_markers
4
+
5
+ def initialize(height)
6
+ @height = height
7
+ @forward = Array.new(height, nil)
8
+ @forward_markers = Array.new(height) {|i| []}
9
+ end
10
+
11
+ def top_level
12
+ height - 1
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,200 @@
1
+ class IntervalSkipList
2
+ attr_reader :probability
3
+
4
+ def initialize
5
+ @head = HeadNode.new(max_height)
6
+ @ranges = {}
7
+ @probability = 0.5
8
+ end
9
+
10
+ def max_height
11
+ 3
12
+ end
13
+
14
+ def empty?
15
+ head.forward[0].nil?
16
+ end
17
+
18
+ def expire(range, length_change)
19
+ expired_markers, first_node_after_range = overlapping(range)
20
+ expired_markers.each { |marker| delete(marker) }
21
+ first_node_after_range.propagate_length_change(length_change)
22
+ end
23
+
24
+ def overlapping(range)
25
+ markers, first_node = containing_with_node(range.first)
26
+
27
+ cur_node = first_node
28
+ begin
29
+ markers.concat(cur_node.forward_markers.flatten)
30
+ cur_node = cur_node.forward[0]
31
+ end while cur_node.key < range.last
32
+
33
+ return markers.uniq, cur_node
34
+ end
35
+
36
+ def containing(n)
37
+ containing_with_node(n).first
38
+ end
39
+
40
+ def insert(range, marker)
41
+ ranges[marker] = range
42
+ first_node = insert_node(range.first)
43
+ first_node.endpoint_of.push(marker)
44
+ last_node = insert_node(range.last)
45
+ last_node.endpoint_of.push(marker)
46
+
47
+ cur_node = first_node
48
+ cur_level = first_node.top_level
49
+ while next_node_at_level_inside_range?(cur_node, cur_level, range)
50
+ while can_ascend_from?(cur_node, cur_level) && next_node_at_level_inside_range?(cur_node, cur_level + 1, range)
51
+ cur_level += 1
52
+ end
53
+ cur_node = mark_forward_path_at_level(cur_node, cur_level, marker)
54
+ end
55
+
56
+ while node_inside_range?(cur_node, range)
57
+ while can_descend_from?(cur_level) && next_node_at_level_outside_range?(cur_node, cur_level, range)
58
+ cur_level -= 1
59
+ end
60
+ cur_node = mark_forward_path_at_level(cur_node, cur_level, marker)
61
+ end
62
+ end
63
+
64
+ def delete(marker)
65
+ range = ranges[marker]
66
+ path_to_first_node = make_path
67
+ first_node = find(range.first, path_to_first_node)
68
+
69
+ cur_node = first_node
70
+ cur_level = first_node.top_level
71
+ while next_node_at_level_inside_range?(cur_node, cur_level, range)
72
+ while can_ascend_from?(cur_node, cur_level) && next_node_at_level_inside_range?(cur_node, cur_level + 1, range)
73
+ cur_level += 1
74
+ end
75
+ cur_node = unmark_forward_path_at_level(cur_node, cur_level, marker)
76
+ end
77
+
78
+ while node_inside_range?(cur_node, range)
79
+ while can_descend_from?(cur_level) && next_node_at_level_outside_range?(cur_node, cur_level, range)
80
+ cur_level -= 1
81
+ end
82
+ cur_node = unmark_forward_path_at_level(cur_node, cur_level, marker)
83
+ end
84
+ last_node = cur_node
85
+
86
+ first_node.endpoint_of.delete(marker)
87
+ if first_node.endpoint_of.empty?
88
+ first_node.delete(path_to_first_node)
89
+ end
90
+
91
+ last_node.endpoint_of.delete(marker)
92
+ if last_node.endpoint_of.empty?
93
+ path_to_last_node = make_path
94
+ find(range.last, path_to_last_node)
95
+ last_node.delete(path_to_last_node)
96
+ end
97
+ end
98
+
99
+ protected
100
+ attr_reader :head, :ranges
101
+
102
+ def insert_node(key)
103
+ path = make_path
104
+ found_node = find(key, path)
105
+ if found_node && found_node.key == key
106
+ return found_node
107
+ else
108
+ return Node.new(key, next_node_height, path)
109
+ end
110
+ end
111
+
112
+ def containing_with_node(n)
113
+ containing = []
114
+ cur_node = head
115
+ (max_height - 1).downto(0) do |cur_level|
116
+ while (next_node = cur_node.forward[cur_level]) && next_node.key <= n
117
+ cur_node = next_node
118
+ if cur_node.key == n
119
+ return containing + (cur_node.markers - cur_node.endpoint_of), cur_node
120
+ end
121
+ end
122
+ containing.concat(cur_node.forward_markers[cur_level])
123
+ end
124
+
125
+ return containing, cur_node
126
+ end
127
+
128
+ def delete_node(key)
129
+ path = make_path
130
+ found_node = find(key, path)
131
+ found_node.delete(path) if found_node.key == key
132
+ end
133
+
134
+ def find(key, path)
135
+ cur_node = head
136
+ (max_height - 1).downto(0) do |cur_level|
137
+ while (next_node = cur_node.forward[cur_level]) && next_node.key < key
138
+ cur_node = next_node
139
+ end
140
+ path[cur_level] = cur_node
141
+ end
142
+ cur_node.forward[0]
143
+ end
144
+
145
+ def make_path
146
+ Array.new(max_height, nil)
147
+ end
148
+
149
+ def next_node_height
150
+ height = 1
151
+ while rand < probability && height < max_height
152
+ height += 1
153
+ end
154
+ height
155
+ end
156
+
157
+ def can_ascend_from?(node, level)
158
+ level < node.top_level
159
+ end
160
+
161
+ def can_descend_from?(level)
162
+ level > 0
163
+ end
164
+
165
+ def node_inside_range?(node, range)
166
+ node.key < range.last
167
+ end
168
+
169
+ def next_node_at_level_inside_range?(node, level, range)
170
+ node.forward[level] && node.forward[level].key <= range.last
171
+ end
172
+
173
+ def next_node_at_level_outside_range?(node, level, range)
174
+ (node.forward[level].nil? || node.forward[level].key > range.last)
175
+ end
176
+
177
+ def mark_forward_path_at_level(node, level, marker)
178
+ node.forward_markers[level].push(marker)
179
+ next_node = node.forward[level]
180
+ next_node.markers.push(marker)
181
+ node = next_node
182
+ end
183
+
184
+ def unmark_forward_path_at_level(node, level, marker)
185
+ node.forward_markers[level].delete(marker)
186
+ next_node = node.forward[level]
187
+ next_node.markers.delete(marker)
188
+ node = next_node
189
+ end
190
+
191
+ def nodes
192
+ nodes = []
193
+ cur_node = head.forward[0]
194
+ until cur_node.nil?
195
+ nodes << cur_node
196
+ cur_node = cur_node.forward[0]
197
+ end
198
+ nodes
199
+ end
200
+ end
@@ -0,0 +1,164 @@
1
+ class IntervalSkipList
2
+ class Node < HeadNode
3
+ attr_accessor :key
4
+ attr_reader :markers, :endpoint_of
5
+
6
+ def initialize(key, height, path)
7
+ super(height)
8
+ @key = key
9
+ @markers = []
10
+ @endpoint_of = []
11
+ update_forward_pointers(path)
12
+ promote_markers(path)
13
+ end
14
+
15
+ def all_forward_markers
16
+ markers.flatten
17
+ end
18
+
19
+ def delete(path)
20
+ 0.upto(top_level) do |i|
21
+ path[i].forward[i] = forward[i]
22
+ end
23
+ demote_markers(path)
24
+ end
25
+
26
+ def propagate_length_change(length_change)
27
+ cur_node = self
28
+ while cur_node do
29
+ cur_node.key += length_change
30
+ cur_node = cur_node.forward[0]
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def update_forward_pointers(path)
37
+ 0.upto(top_level) do |i|
38
+ forward[i] = path[i].forward[i]
39
+ path[i].forward[i] = self
40
+ end
41
+ end
42
+
43
+ def promote_markers(path)
44
+ promoted = []
45
+ new_promoted = []
46
+ 0.upto(top_level) do |i|
47
+ incoming_markers = path[i].forward_markers[i]
48
+ markers.concat(incoming_markers)
49
+
50
+ incoming_markers.each do |marker|
51
+ if can_be_promoted_higher?(marker, i)
52
+ new_promoted.push(marker)
53
+ forward[i].delete_marker_from_path(marker, i, forward[i+1])
54
+ else
55
+ forward_markers[i].push(marker)
56
+ end
57
+ end
58
+
59
+ promoted.each do |marker|
60
+ if can_be_promoted_higher?(marker, i)
61
+ new_promoted.push(marker)
62
+ forward[i].delete_marker_from_path(marker, i, forward[i+1])
63
+ else
64
+ forward_markers[i].push(marker)
65
+ end
66
+ end
67
+
68
+ promoted = new_promoted
69
+ new_promoted = []
70
+ end
71
+ end
72
+
73
+
74
+ def can_be_promoted_higher?(marker, level)
75
+ level < top_level && forward[level + 1] && forward[level + 1].markers.include?(marker)
76
+ end
77
+
78
+ def delete_marker_from_path(marker, level, terminus)
79
+ cur_node = self
80
+ until cur_node == terminus
81
+ cur_node.forward_markers[level].delete(marker)
82
+ cur_node.markers.delete(marker)
83
+ cur_node = cur_node.forward[level]
84
+ end
85
+ end
86
+
87
+ def demote_markers(path)
88
+ demote_inbound_markers(path)
89
+ demote_outbound_markers(path)
90
+ end
91
+
92
+ def demote_inbound_markers(path)
93
+ demoted = []
94
+ new_demoted = []
95
+
96
+ top_level.downto(0) do |i|
97
+ incoming_markers = path[i].forward_markers[i].dup
98
+ incoming_markers.each do |marker|
99
+ unless forward_node_with_marker_at_or_above_level?(marker, i)
100
+ path[i].forward_markers[i].delete(marker)
101
+ new_demoted.push(marker)
102
+ end
103
+ end
104
+
105
+ demoted.each do |marker|
106
+ path[i + 1].place_marker_on_inbound_path(marker, i, path[i])
107
+
108
+ if forward[i].markers.include?(marker)
109
+ path[i].forward_markers[i].push(marker)
110
+ else
111
+ new_demoted.push(marker)
112
+ end
113
+ end
114
+
115
+ demoted = new_demoted
116
+ new_demoted = []
117
+ end
118
+ end
119
+
120
+ def demote_outbound_markers(path)
121
+ demoted = []
122
+ new_demoted = []
123
+
124
+ top_level.downto(0) do |i|
125
+ forward_markers[i].each do |marker|
126
+ new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
127
+ end
128
+
129
+ demoted.each do |marker|
130
+ forward[i].place_marker_on_outbound_path(marker, i, forward[i + 1])
131
+ new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
132
+ end
133
+
134
+ demoted = new_demoted
135
+ new_demoted = []
136
+ end
137
+ end
138
+
139
+ def forward_node_with_marker_at_or_above_level?(marker, level)
140
+ level.upto(top_level) do |i|
141
+ return true if forward[i].markers.include?(marker)
142
+ end
143
+ false
144
+ end
145
+
146
+ def place_marker_on_outbound_path(marker, level, terminus)
147
+ cur_node = self
148
+ until cur_node == terminus
149
+ cur_node.forward_markers[level].push(marker)
150
+ cur_node.markers.push(marker)
151
+ cur_node = cur_node.forward[level]
152
+ end
153
+ end
154
+
155
+ def place_marker_on_inbound_path(marker, level, terminus)
156
+ cur_node = self
157
+ until cur_node == terminus
158
+ cur_node.forward_markers[level].push(marker)
159
+ cur_node = cur_node.forward[level]
160
+ cur_node.markers.push(marker)
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,114 @@
1
+ module Treetop
2
+ module Runtime
3
+ class SyntaxNode
4
+ attr_reader :input, :interval
5
+ attr_accessor :parent
6
+ attr_reader :dot_id
7
+
8
+ @@dot_id_counter = 0
9
+
10
+ def initialize(input, interval, elements = nil)
11
+ @input = input
12
+ @interval = interval
13
+ @elements = elements
14
+ end
15
+
16
+ def elements
17
+ return @elements if terminal?
18
+ # replace the character class placeholders in the sequence (lazy instantiation)
19
+ last_element = nil
20
+ @comprehensive_elements ||= @elements.map do |element|
21
+ if element == true
22
+ index = last_element ? last_element.interval.last : interval.first
23
+ element = SyntaxNode.new(input, index...(index + 1))
24
+ end
25
+ element.parent = self
26
+ last_element = element
27
+ end
28
+
29
+ @dot_id = @@dot_id_counter
30
+ @@dot_id_counter += 1
31
+
32
+ @comprehensive_elements
33
+ end
34
+
35
+ def terminal?
36
+ @elements.nil?
37
+ end
38
+
39
+ def nonterminal?
40
+ !terminal?
41
+ end
42
+
43
+ def text_value
44
+ input[interval]
45
+ end
46
+
47
+ def empty?
48
+ interval.first == interval.last && interval.exclude_end?
49
+ end
50
+
51
+ def <=>(other)
52
+ self.interval.first <=> other.interval.first
53
+ end
54
+
55
+ def extension_modules
56
+ local_extensions =
57
+ class <<self
58
+ included_modules-Object.included_modules
59
+ end
60
+ if local_extensions.size > 0
61
+ local_extensions
62
+ else
63
+ [] # There weren't any; must be a literal node
64
+ end
65
+ end
66
+
67
+ def inspect(indent="")
68
+ em = extension_modules
69
+ interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
70
+ im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
71
+ tv = text_value
72
+ tv = "...#{tv[-20..-1]}" if tv.size > 20
73
+
74
+ indent +
75
+ self.class.to_s.sub(/.*:/,'') +
76
+ em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
77
+ " offset=#{interval.first}" +
78
+ ", #{tv.inspect}" +
79
+ im +
80
+ (elements && elements.size > 0 ?
81
+ ":" +
82
+ (elements||[]).map{|e|
83
+ begin
84
+ "\n"+e.inspect(indent+" ")
85
+ rescue # Defend against inspect not taking a parameter
86
+ "\n"+indent+" "+e.inspect
87
+ end
88
+ }.join("") :
89
+ ""
90
+ )
91
+ end
92
+
93
+ def write_dot(io)
94
+ io.puts "node#{dot_id} [label=\"#{text_value}\"];"
95
+ if nonterminal? then
96
+ elements.each do
97
+ |x|
98
+ io.puts "node#{dot_id} -> node#{x.dot_id};"
99
+ x.write_dot(io)
100
+ end
101
+ end
102
+ end
103
+
104
+ def write_dot_file(fname)
105
+ File.open(fname + ".dot","w") do
106
+ |file|
107
+ file.puts "digraph G {"
108
+ write_dot(file)
109
+ file.puts "}"
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end