treetop 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/Rakefile +1 -1
  2. data/doc/contributing_and_planned_features.markdown +3 -11
  3. data/doc/index.markdown +65 -4
  4. data/doc/semantic_interpretation.markdown +3 -1
  5. data/doc/site.rb +79 -10
  6. data/doc/site/contribute.html +118 -0
  7. data/doc/{images/middle_backgound.png → site/images/bottom_background.png} +0 -0
  8. data/doc/{images → site/images}/middle_background.png +0 -0
  9. data/doc/{images → site/images}/paren_language_output.png +0 -0
  10. data/doc/site/images/pivotal.gif +0 -0
  11. data/doc/site/images/top_background.png +0 -0
  12. data/doc/site/index.html +102 -0
  13. data/doc/site/pitfalls_and_advanced_techniques.html +68 -0
  14. data/doc/site/screen.css +129 -0
  15. data/doc/site/semantic_interpretation.html +214 -0
  16. data/doc/site/syntactic_recognition.html +142 -0
  17. data/doc/site/using_in_ruby.html +34 -0
  18. data/doc/sitegen.rb +60 -0
  19. data/doc/syntactic_recognition.markdown +11 -14
  20. data/doc/using_in_ruby.markdown +7 -3
  21. data/lib/treetop/compiler/metagrammar.rb +2 -2
  22. data/lib/treetop/compiler/metagrammar.treetop +3 -3
  23. data/lib/treetop/compiler/node_classes.rb +1 -0
  24. data/lib/treetop/compiler/node_classes/character_class.rb +5 -1
  25. data/lib/treetop/compiler/node_classes/predicate.rb +1 -1
  26. data/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
  27. data/lib/treetop/runtime.rb +2 -1
  28. data/lib/treetop/runtime/interval_skip_list.rb +4 -0
  29. data/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
  30. data/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
  31. data/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
  32. data/lib/treetop/runtime/syntax_node.rb +40 -40
  33. metadata +23 -10
  34. data/doc/images/bottom_background.png +0 -0
  35. data/doc/images/top_background.png +0 -0
  36. data/doc/screen.css +0 -52
  37. data/doc/site.html +0 -34
@@ -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
@@ -1,12 +1,17 @@
1
1
  module Treetop
2
2
  module Runtime
3
3
  class SyntaxNode
4
- attr_reader :input, :interval
4
+ attr_reader :input, :interval, :elements
5
+ attr_accessor :parent
5
6
 
6
7
  def initialize(input, interval, elements = nil)
7
8
  @input = input
8
9
  @interval = interval
9
- @elements = elements
10
+ if @elements = elements
11
+ elements.each do |element|
12
+ element.parent = self
13
+ end
14
+ end
10
15
  end
11
16
 
12
17
  def terminal?
@@ -17,56 +22,51 @@ module Treetop
17
22
  !terminal?
18
23
  end
19
24
 
20
- def elements
21
- @elements
22
- end
23
-
24
25
  def text_value
25
26
  input[interval]
26
27
  end
27
28
 
28
29
  def empty?
29
- interval.first == interval.last && interval.exclude_end?
30
+ interval.first == interval.last && interval.exclude_end?
30
31
  end
31
32
 
32
33
  def extension_modules
33
- local_extensions =
34
- class <<self
35
- included_modules-Object.included_modules
36
- end
37
- if local_extensions.size > 0
38
- local_extensions
39
- else
40
- [] # There weren't any; must be a literal node
41
- end
34
+ local_extensions =
35
+ class <<self
36
+ included_modules-Object.included_modules
37
+ end
38
+ if local_extensions.size > 0
39
+ local_extensions
40
+ else
41
+ [] # There weren't any; must be a literal node
42
+ end
42
43
  end
43
44
 
44
45
  def inspect(indent="")
45
- em = extension_modules
46
- interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
47
- im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
48
- tv = text_value
49
- tv = "...#{tv[-20..-1]}" if tv.size > 20
50
-
51
- indent +
52
- self.class.to_s.sub(/.*:/,'') +
53
- em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
54
- " offset=#{interval.first}" +
55
- ", #{tv.inspect}" +
56
- im +
57
- (elements && elements.size > 0 ?
58
- ":" +
59
- (@elements||[]).map{|e|
60
- begin
61
- "\n"+e.inspect(indent+" ")
62
- rescue # Defend against inspect not taking a parameter
63
- "\n"+indent+" "+e.inspect
64
- end
65
- }.join("") :
66
- ""
67
- )
46
+ em = extension_modules
47
+ interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
48
+ im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
49
+ tv = text_value
50
+ tv = "...#{tv[-20..-1]}" if tv.size > 20
68
51
 
52
+ indent +
53
+ self.class.to_s.sub(/.*:/,'') +
54
+ em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
55
+ " offset=#{interval.first}" +
56
+ ", #{tv.inspect}" +
57
+ im +
58
+ (elements && elements.size > 0 ?
59
+ ":" +
60
+ (@elements||[]).map{|e|
61
+ begin
62
+ "\n"+e.inspect(indent+" ")
63
+ rescue # Defend against inspect not taking a parameter
64
+ "\n"+indent+" "+e.inspect
65
+ end
66
+ }.join("") :
67
+ ""
68
+ )
69
69
  end
70
70
  end
71
71
  end
72
- end
72
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: treetop
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.0
7
- date: 2008-01-11 00:00:00 -08:00
6
+ version: 1.2.1
7
+ date: 2008-02-01 00:00:00 -08:00
8
8
  summary: A Ruby-based text parsing and interpretation DSL
9
9
  require_paths:
10
10
  - lib
@@ -63,31 +63,44 @@ files:
63
63
  - lib/treetop/compiler/node_classes/repetition.rb
64
64
  - lib/treetop/compiler/node_classes/sequence.rb
65
65
  - lib/treetop/compiler/node_classes/terminal.rb
66
+ - lib/treetop/compiler/node_classes/transient_prefix.rb
66
67
  - lib/treetop/compiler/node_classes/treetop_file.rb
67
68
  - lib/treetop/ruby_extensions/string.rb
68
69
  - lib/treetop/runtime/compiled_parser.rb
70
+ - lib/treetop/runtime/interval_skip_list
71
+ - lib/treetop/runtime/interval_skip_list.rb
69
72
  - lib/treetop/runtime/node_cache.rb
70
73
  - lib/treetop/runtime/parse_cache.rb
71
74
  - lib/treetop/runtime/syntax_node.rb
72
75
  - lib/treetop/runtime/terminal_parse_failure.rb
73
76
  - lib/treetop/runtime/terminal_syntax_node.rb
77
+ - lib/treetop/runtime/interval_skip_list/head_node.rb
78
+ - lib/treetop/runtime/interval_skip_list/interval_skip_list.rb
79
+ - lib/treetop/runtime/interval_skip_list/node.rb
74
80
  - bin/tt
75
81
  - doc/contributing_and_planned_features.markdown
76
82
  - doc/grammar_composition.markdown
77
- - doc/images
78
83
  - doc/index.markdown
79
84
  - doc/pitfalls_and_advanced_techniques.markdown
80
- - doc/screen.css
81
85
  - doc/semantic_interpretation.markdown
82
- - doc/site.html
86
+ - doc/site
83
87
  - doc/site.rb
88
+ - doc/sitegen.rb
84
89
  - doc/syntactic_recognition.markdown
85
90
  - doc/using_in_ruby.markdown
86
- - doc/images/bottom_background.png
87
- - doc/images/middle_backgound.png
88
- - doc/images/middle_background.png
89
- - doc/images/paren_language_output.png
90
- - doc/images/top_background.png
91
+ - doc/site/contribute.html
92
+ - doc/site/images
93
+ - doc/site/index.html
94
+ - doc/site/pitfalls_and_advanced_techniques.html
95
+ - doc/site/screen.css
96
+ - doc/site/semantic_interpretation.html
97
+ - doc/site/syntactic_recognition.html
98
+ - doc/site/using_in_ruby.html
99
+ - doc/site/images/bottom_background.png
100
+ - doc/site/images/middle_background.png
101
+ - doc/site/images/paren_language_output.png
102
+ - doc/site/images/pivotal.gif
103
+ - doc/site/images/top_background.png
91
104
  - examples/lambda_calculus
92
105
  - examples/lambda_calculus/arithmetic.rb
93
106
  - examples/lambda_calculus/arithmetic.treetop
Binary file
Binary file
data/doc/screen.css DELETED
@@ -1,52 +0,0 @@
1
- body {
2
- margin: 0;
3
- padding: 0;
4
- background: #666666;
5
- font-family: "Lucida Grande", Geneva, Arial, Verdana, sans-serif;
6
- color: #333333;
7
- }
8
-
9
- div {
10
- margin: 0;
11
- background-position: center;
12
- background-repeat: none;
13
- }
14
-
15
- h1 {
16
- font-size: 120%;
17
- margin-top: 1.5em;
18
- margin-bottom: .5em;
19
- }
20
-
21
- div#top {
22
- background-image: url("images/top_background.png");
23
- height: 200px;
24
- width: 100%;
25
- }
26
-
27
- div#middle {
28
- padding-top: 10px;
29
- background-image: url("images/middle_background.png");
30
- background-repeat: repeat-y;
31
- }
32
-
33
- div#bottom {
34
- background-image: url("images/bottom_background.png");
35
- height: 42px;
36
- margin-bottom: 30px;
37
- }
38
-
39
- div#content {
40
- width: 481px;
41
- margin: 0 auto 0 auto;
42
- padding: 0 60px 25px 60px;
43
- }
44
-
45
- p {
46
- line-height: 150%;
47
- }
48
-
49
- p.intro_text {
50
- color: #C45900;
51
- font-size: 115%;
52
- }
data/doc/site.html DELETED
@@ -1,34 +0,0 @@
1
- <html><head><link type="text/css" href="./screen.css" rel="stylesheet"></link></head><body><div id="top"></div><div id="middle"><div id="content"><p class="intro_text">
2
-
3
- Treetop is a language for describing languages. Combining the elegance of Ruby with cutting-edge <em>parsing expression grammars</em>, it helps you analyze syntax with revolutionarily ease.
4
-
5
- </p>
6
-
7
- <h1>Intuitive Grammar Specifications</h1>
8
-
9
- <p>Treetop's packrat parsers use <em>memoization</em> to make the backtracking possible in linear time. This cuts the gordian knot of grammar design. There's no need to look ahead and no need to lex. Worry about the structure of the language, not the idiosyncrasies of the parser.</p>
10
-
11
- <h1>Syntax-Oriented Programming</h1>
12
-
13
- <p>Rather than implementing semantic actions that construct parse trees, define methods on the trees that Treetop automatically constructs–and write this code directly inside the grammar.</p>
14
-
15
- <h1>Reusable, Composable Language Descriptions</h1>
16
-
17
- <p>Break grammars into modules and compose them via Ruby's mixin semantics. Or combine grammars written by others in novel ways. Or extend existing grammars with your own syntactic constructs by overriding rules with access to a <code>super</code> keyword. Compositionally means your investment of time into grammar writing is secure–you can always extend and reuse your code.</p>
18
-
19
- <h1>Acknowledgements</h1>
20
-
21
- <p>First, thank you to my employer Rob Mee of Pivotal Labs for funding a substantial portion of Treetop's development. He gets it.</p>
22
-
23
- <p>I'd also like to thank:</p>
24
-
25
- <ul>
26
- <li>Damon McCormick for several hours of pair programming.</li>
27
- <li>Nick Kallen for lots of well-considered feedback and a few afternoons of programming.</li>
28
- <li>Brian Takita for a night of pair programming.</li>
29
- <li>Eliot Miranda for urging me rewrite as a compiler right away rather than putting it off.</li>
30
- <li>Ryan Davis and Eric Hodel for hurting my code.</li>
31
- <li>Dav Yaginuma for kicking me into action on my idea.</li>
32
- <li>Bryan Ford for his seminal work on Packrat Parsers.</li>
33
- <li>The editors of Lambda the Ultimate, where I discovered parsing expression grammars.</li>
34
- </ul></div></div><div id="bottom"></div></body></html>