ghazel-parslet 1.4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/HISTORY.txt +195 -0
  2. data/LICENSE +23 -0
  3. data/README +70 -0
  4. data/Rakefile +49 -0
  5. data/example/boolean_algebra.rb +70 -0
  6. data/example/calc.rb +153 -0
  7. data/example/comments.rb +35 -0
  8. data/example/deepest_errors.rb +131 -0
  9. data/example/documentation.rb +18 -0
  10. data/example/email_parser.rb +52 -0
  11. data/example/empty.rb +13 -0
  12. data/example/erb.rb +47 -0
  13. data/example/ignore.rb +33 -0
  14. data/example/ip_address.rb +125 -0
  15. data/example/json.rb +128 -0
  16. data/example/local.rb +34 -0
  17. data/example/mathn.rb +44 -0
  18. data/example/minilisp.rb +94 -0
  19. data/example/modularity.rb +47 -0
  20. data/example/nested_errors.rb +132 -0
  21. data/example/output/boolean_algebra.out +4 -0
  22. data/example/output/calc.out +1 -0
  23. data/example/output/comments.out +8 -0
  24. data/example/output/deepest_errors.out +54 -0
  25. data/example/output/documentation.err +4 -0
  26. data/example/output/documentation.out +1 -0
  27. data/example/output/email_parser.out +2 -0
  28. data/example/output/empty.err +1 -0
  29. data/example/output/erb.out +7 -0
  30. data/example/output/ignore.out +1 -0
  31. data/example/output/ignore_whitespace.out +1 -0
  32. data/example/output/ip_address.out +9 -0
  33. data/example/output/json.out +5 -0
  34. data/example/output/local.out +3 -0
  35. data/example/output/mathn.out +4 -0
  36. data/example/output/minilisp.out +5 -0
  37. data/example/output/modularity.out +0 -0
  38. data/example/output/nested_errors.out +54 -0
  39. data/example/output/parens.out +8 -0
  40. data/example/output/readme.out +1 -0
  41. data/example/output/seasons.out +28 -0
  42. data/example/output/sentence.out +1 -0
  43. data/example/output/simple_xml.out +2 -0
  44. data/example/output/string_parser.out +3 -0
  45. data/example/parens.rb +42 -0
  46. data/example/readme.rb +30 -0
  47. data/example/seasons.rb +46 -0
  48. data/example/sentence.rb +36 -0
  49. data/example/simple.lit +3 -0
  50. data/example/simple_xml.rb +54 -0
  51. data/example/string_parser.rb +77 -0
  52. data/example/test.lit +4 -0
  53. data/lib/parslet.rb +254 -0
  54. data/lib/parslet/atoms.rb +32 -0
  55. data/lib/parslet/atoms/alternative.rb +50 -0
  56. data/lib/parslet/atoms/base.rb +124 -0
  57. data/lib/parslet/atoms/can_flatten.rb +137 -0
  58. data/lib/parslet/atoms/context.rb +94 -0
  59. data/lib/parslet/atoms/dsl.rb +98 -0
  60. data/lib/parslet/atoms/entity.rb +41 -0
  61. data/lib/parslet/atoms/lookahead.rb +49 -0
  62. data/lib/parslet/atoms/named.rb +32 -0
  63. data/lib/parslet/atoms/re.rb +38 -0
  64. data/lib/parslet/atoms/repetition.rb +63 -0
  65. data/lib/parslet/atoms/rule.rb +12 -0
  66. data/lib/parslet/atoms/rule/position.rb +143 -0
  67. data/lib/parslet/atoms/sequence.rb +38 -0
  68. data/lib/parslet/atoms/str.rb +37 -0
  69. data/lib/parslet/atoms/visitor.rb +89 -0
  70. data/lib/parslet/cause.rb +94 -0
  71. data/lib/parslet/convenience.rb +35 -0
  72. data/lib/parslet/error_reporter.rb +7 -0
  73. data/lib/parslet/error_reporter/deepest.rb +95 -0
  74. data/lib/parslet/error_reporter/tree.rb +57 -0
  75. data/lib/parslet/export.rb +162 -0
  76. data/lib/parslet/expression.rb +51 -0
  77. data/lib/parslet/expression/treetop.rb +92 -0
  78. data/lib/parslet/parser.rb +67 -0
  79. data/lib/parslet/pattern.rb +114 -0
  80. data/lib/parslet/pattern/binding.rb +49 -0
  81. data/lib/parslet/rig/rspec.rb +51 -0
  82. data/lib/parslet/slice.rb +101 -0
  83. data/lib/parslet/source.rb +62 -0
  84. data/lib/parslet/source/line_cache.rb +95 -0
  85. data/lib/parslet/transform.rb +236 -0
  86. data/lib/parslet/transform/context.rb +32 -0
  87. metadata +264 -0
@@ -0,0 +1,95 @@
1
+
2
+
3
+ class Parslet::Source
4
+ # A cache for line start positions.
5
+ #
6
+ class LineCache
7
+ def initialize
8
+ # Stores line endings as a simple position number. The first line always
9
+ # starts at 0; numbers beyond the biggest entry are on any line > size,
10
+ # but probably make a scan to that position neccessary.
11
+ @line_ends = []
12
+ @line_ends.extend RangeSearch
13
+ end
14
+
15
+ # Returns a <line, column> tuple for the given input position.
16
+ #
17
+ def line_and_column(pos)
18
+ eol_idx = @line_ends.lbound(pos)
19
+
20
+ if eol_idx
21
+ # eol_idx points to the offset that ends the current line.
22
+ # Let's try to find the offset that starts it:
23
+ offset = eol_idx>0 && @line_ends[eol_idx-1] || 0
24
+ return [eol_idx+1, pos-offset+1]
25
+ else
26
+ # eol_idx is nil, that means that we're beyond the last line end that
27
+ # we know about. Pretend for now that we're just on the last line.
28
+ offset = @line_ends.last || 0
29
+ return [@line_ends.size+1, pos-offset+1]
30
+ end
31
+ end
32
+
33
+ def scan_for_line_endings(start_pos, buf)
34
+ return unless buf
35
+ return unless buf.index("\n")
36
+ cur = -1
37
+
38
+ # If we have already read part or all of buf, we already know about
39
+ # line ends in that portion. remove it and correct cur (search index)
40
+ if @last_line_end && start_pos < @last_line_end
41
+ # Let's not search the range from start_pos to last_line_end again.
42
+ cur = @last_line_end - start_pos -1
43
+ end
44
+
45
+ # Scan the string for line endings; store the positions of all endings
46
+ # in @line_ends.
47
+ while buf && cur = buf.index("\n", cur+1)
48
+ @last_line_end = (start_pos + cur+1)
49
+ @line_ends << @last_line_end
50
+ end
51
+ end
52
+ end
53
+
54
+ # Mixin for arrays that implicitly give a number of ranges, where one range
55
+ # begins where the other one ends.
56
+ #
57
+ # Example:
58
+ #
59
+ # [10, 20, 30]
60
+ # # would describe [0, 10], (10, 20], (20, 30]
61
+ #
62
+ module RangeSearch
63
+ def find_mid(left, right)
64
+ # NOTE: Jonathan Hinkle reported that when mathn is required, just
65
+ # dividing and relying on the integer truncation is not enough.
66
+ left + ((right - left) / 2).floor
67
+ end
68
+
69
+ # Scans the array for the first number that is > than bound. Returns the
70
+ # index of that number.
71
+ #
72
+ def lbound(bound)
73
+ return nil if empty?
74
+ return nil unless last > bound
75
+
76
+ left = 0
77
+ right = size - 1
78
+
79
+ loop do
80
+ mid = find_mid(left, right)
81
+
82
+ if self[mid] > bound
83
+ right = mid
84
+ else
85
+ # assert: self[mid] <= bound
86
+ left = mid+1
87
+ end
88
+
89
+ if right <= left
90
+ return right
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,236 @@
1
+
2
+ require 'parslet/pattern'
3
+
4
+ # Transforms an expression tree into something else. The transformation
5
+ # performs a depth-first, post-order traversal of the expression tree. During
6
+ # that traversal, each time a rule matches a node, the node is replaced by the
7
+ # result of the block associated to the rule. Otherwise the node is accepted
8
+ # as is into the result tree.
9
+ #
10
+ # This is almost what you would generally do with a tree visitor, except that
11
+ # you can match several levels of the tree at once.
12
+ #
13
+ # As a consequence of this, the resulting tree will contain pieces of the
14
+ # original tree and new pieces. Most likely, you will want to transform the
15
+ # original tree wholly, so this isn't a problem.
16
+ #
17
+ # You will not be able to create a loop, given that each node will be replaced
18
+ # only once and then left alone. This means that the results of a replacement
19
+ # will not be acted upon.
20
+ #
21
+ # Example:
22
+ #
23
+ # class Example < Parslet::Transform
24
+ # rule(:string => simple(:x)) { # (1)
25
+ # StringLiteral.new(x)
26
+ # }
27
+ # end
28
+ #
29
+ # A tree transform (Parslet::Transform) is defined by a set of rules. Each
30
+ # rule can be defined by calling #rule with the pattern as argument. The block
31
+ # given will be called every time the rule matches somewhere in the tree given
32
+ # to #apply. It is passed a Hash containing all the variable bindings of this
33
+ # pattern match.
34
+ #
35
+ # In the above example, (1) illustrates a simple matching rule.
36
+ #
37
+ # Let's say you want to parse matching parentheses and distill a maximum nest
38
+ # depth. You would probably write a parser like the one in example/parens.rb;
39
+ # here's the relevant part:
40
+ #
41
+ # rule(:balanced) {
42
+ # str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
43
+ # }
44
+ #
45
+ # If you now apply this to a string like '(())', you get a intermediate parse
46
+ # tree that looks like this:
47
+ #
48
+ # {
49
+ # l: '(',
50
+ # m: {
51
+ # l: '(',
52
+ # m: nil,
53
+ # r: ')'
54
+ # },
55
+ # r: ')'
56
+ # }
57
+ #
58
+ # This parse tree is good for debugging, but what we would really like to have
59
+ # is just the nesting depth. This transformation rule will produce that:
60
+ #
61
+ # rule(:l => '(', :m => simple(:x), :r => ')') {
62
+ # # innermost :m will contain nil
63
+ # x.nil? ? 1 : x+1
64
+ # }
65
+ #
66
+ # = Usage patterns
67
+ #
68
+ # There are four ways of using this class. The first one is very much
69
+ # recommended, followed by the second one for generality. The other ones are
70
+ # omitted here.
71
+ #
72
+ # Recommended usage is as follows:
73
+ #
74
+ # class MyTransformator < Parslet::Transform
75
+ # rule(...) { ... }
76
+ # rule(...) { ... }
77
+ # # ...
78
+ # end
79
+ # MyTransformator.new.apply(tree)
80
+ #
81
+ # Alternatively, you can use the Transform class as follows:
82
+ #
83
+ # transform = Parslet::Transform.new do
84
+ # rule(...) { ... }
85
+ # end
86
+ # transform.apply(tree)
87
+ #
88
+ # = Execution context
89
+ #
90
+ # The execution context of action blocks differs depending on the arity of
91
+ # said blocks. This can be confusing. It is however somewhat intentional. You
92
+ # should not create fat Transform descendants containing a lot of helper methods,
93
+ # instead keep your AST class construction in global scope or make it available
94
+ # through a factory. The following piece of code illustrates usage of global
95
+ # scope:
96
+ #
97
+ # transform = Parslet::Transform.new do
98
+ # rule(...) { AstNode.new(a_variable) }
99
+ # rule(...) { Ast.node(a_variable) } # modules are nice
100
+ # end
101
+ # transform.apply(tree)
102
+ #
103
+ # And here's how you would use a class builder (a factory):
104
+ #
105
+ # transform = Parslet::Transform.new do
106
+ # rule(...) { builder.add_node(a_variable) }
107
+ # rule(...) { |d| d[:builder].add_node(d[:a_variable]) }
108
+ # end
109
+ # transform.apply(tree, :builder => Builder.new)
110
+ #
111
+ # As you can see, Transform allows you to inject local context for your rule
112
+ # action blocks to use.
113
+ #
114
+ class Parslet::Transform
115
+ # FIXME: Maybe only part of it? Or maybe only include into constructor
116
+ # context?
117
+ include Parslet
118
+
119
+ autoload :Context, 'parslet/transform/context'
120
+
121
+ class << self
122
+ # FIXME: Only do this for subclasses?
123
+ include Parslet
124
+
125
+ # Define a rule for the transform subclass.
126
+ #
127
+ def rule(expression, &block)
128
+ @__transform_rules ||= []
129
+ @__transform_rules << [Parslet::Pattern.new(expression), block]
130
+ end
131
+
132
+ # Allows accessing the class' rules
133
+ #
134
+ def rules
135
+ @__transform_rules || []
136
+ end
137
+ end
138
+
139
+ def initialize(&block)
140
+ @rules = []
141
+
142
+ if block
143
+ instance_eval(&block)
144
+ end
145
+ end
146
+
147
+ # Defines a rule to be applied whenever apply is called on a tree. A rule
148
+ # is composed of two parts:
149
+ #
150
+ # * an *expression pattern*
151
+ # * a *transformation block*
152
+ #
153
+ def rule(expression, &block)
154
+ @rules << [
155
+ Parslet::Pattern.new(expression),
156
+ block
157
+ ]
158
+ end
159
+
160
+ # Applies the transformation to a tree that is generated by Parslet::Parser
161
+ # or a simple parslet. Transformation will proceed down the tree, replacing
162
+ # parts/all of it with new objects. The resulting object will be returned.
163
+ #
164
+ def apply(obj, context=nil)
165
+ transform_elt(
166
+ case obj
167
+ when Hash
168
+ recurse_hash(obj, context)
169
+ when Array
170
+ recurse_array(obj, context)
171
+ else
172
+ obj
173
+ end,
174
+ context
175
+ )
176
+ end
177
+
178
+ # Executes the block on the bindings obtained by Pattern#match, if such a match
179
+ # can be made. Depending on the arity of the given block, it is called in
180
+ # one of two environments: the current one or a clean toplevel environment.
181
+ #
182
+ # If you would like the current environment preserved, please use the
183
+ # arity 1 variant of the block. Alternatively, you can inject a context object
184
+ # and call methods on it (think :ctx => self).
185
+ #
186
+ # # the local variable a is simulated
187
+ # t.call_on_match(:a => :b) { a }
188
+ # # no change of environment here
189
+ # t.call_on_match(:a => :b) { |d| d[:a] }
190
+ #
191
+ def call_on_match(bindings, block)
192
+ if block
193
+ if block.arity == 1
194
+ return block.call(bindings)
195
+ else
196
+ context = Context.new(bindings)
197
+ return context.instance_eval(&block)
198
+ end
199
+ end
200
+ end
201
+
202
+ # Allow easy access to all rules, the ones defined in the instance and the
203
+ # ones predefined in a subclass definition.
204
+ #
205
+ def rules
206
+ self.class.rules + @rules
207
+ end
208
+
209
+ # @api private
210
+ #
211
+ def transform_elt(elt, context)
212
+ rules.each do |pattern, block|
213
+ if bindings=pattern.match(elt, context)
214
+ # Produces transformed value
215
+ return call_on_match(bindings, block)
216
+ end
217
+ end
218
+
219
+ # No rule matched - element is not transformed
220
+ return elt
221
+ end
222
+
223
+ # @api private
224
+ #
225
+ def recurse_hash(hsh, ctx)
226
+ hsh.inject({}) do |new_hsh, (k,v)|
227
+ new_hsh[k] = apply(v, ctx)
228
+ new_hsh
229
+ end
230
+ end
231
+ # @api private
232
+ #
233
+ def recurse_array(ary, ctx)
234
+ ary.map { |elt| apply(elt, ctx) }
235
+ end
236
+ end
@@ -0,0 +1,32 @@
1
+ require 'blankslate'
2
+
3
+ # Provides a context for tree transformations to run in. The context allows
4
+ # accessing each of the bindings in the bindings hash as local method.
5
+ #
6
+ # Example:
7
+ #
8
+ # ctx = Context.new(:a => :b)
9
+ # ctx.instance_eval do
10
+ # a # => :b
11
+ # end
12
+ #
13
+ class Parslet::Transform::Context < BlankSlate
14
+ reveal :methods
15
+ reveal :respond_to?
16
+ reveal :inspect
17
+ reveal :to_s
18
+ reveal :instance_variable_set
19
+
20
+ def meta_def(name, &body)
21
+ metaclass = class <<self; self; end
22
+
23
+ metaclass.send(:define_method, name, &body)
24
+ end
25
+
26
+ def initialize(bindings)
27
+ bindings.each do |key, value|
28
+ meta_def(key.to_sym) { value }
29
+ instance_variable_set("@#{key}", value)
30
+ end
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,264 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghazel-parslet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kaspar Schiess
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: blankslate
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: flexmock
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rdoc
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sdoc
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: growl
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description:
143
+ email: kaspar.schiess@absurd.li
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files:
147
+ - README
148
+ files:
149
+ - HISTORY.txt
150
+ - LICENSE
151
+ - Rakefile
152
+ - README
153
+ - lib/parslet/atoms/alternative.rb
154
+ - lib/parslet/atoms/base.rb
155
+ - lib/parslet/atoms/can_flatten.rb
156
+ - lib/parslet/atoms/context.rb
157
+ - lib/parslet/atoms/dsl.rb
158
+ - lib/parslet/atoms/entity.rb
159
+ - lib/parslet/atoms/lookahead.rb
160
+ - lib/parslet/atoms/named.rb
161
+ - lib/parslet/atoms/re.rb
162
+ - lib/parslet/atoms/repetition.rb
163
+ - lib/parslet/atoms/rule/position.rb
164
+ - lib/parslet/atoms/rule.rb
165
+ - lib/parslet/atoms/sequence.rb
166
+ - lib/parslet/atoms/str.rb
167
+ - lib/parslet/atoms/visitor.rb
168
+ - lib/parslet/atoms.rb
169
+ - lib/parslet/cause.rb
170
+ - lib/parslet/convenience.rb
171
+ - lib/parslet/error_reporter/deepest.rb
172
+ - lib/parslet/error_reporter/tree.rb
173
+ - lib/parslet/error_reporter.rb
174
+ - lib/parslet/export.rb
175
+ - lib/parslet/expression/treetop.rb
176
+ - lib/parslet/expression.rb
177
+ - lib/parslet/parser.rb
178
+ - lib/parslet/pattern/binding.rb
179
+ - lib/parslet/pattern.rb
180
+ - lib/parslet/rig/rspec.rb
181
+ - lib/parslet/slice.rb
182
+ - lib/parslet/source/line_cache.rb
183
+ - lib/parslet/source.rb
184
+ - lib/parslet/transform/context.rb
185
+ - lib/parslet/transform.rb
186
+ - lib/parslet.rb
187
+ - example/boolean_algebra.rb
188
+ - example/calc.rb
189
+ - example/comments.rb
190
+ - example/deepest_errors.rb
191
+ - example/documentation.rb
192
+ - example/email_parser.rb
193
+ - example/empty.rb
194
+ - example/erb.rb
195
+ - example/ignore.rb
196
+ - example/ip_address.rb
197
+ - example/json.rb
198
+ - example/local.rb
199
+ - example/mathn.rb
200
+ - example/minilisp.rb
201
+ - example/modularity.rb
202
+ - example/nested_errors.rb
203
+ - example/output/boolean_algebra.out
204
+ - example/output/calc.out
205
+ - example/output/comments.out
206
+ - example/output/deepest_errors.out
207
+ - example/output/documentation.err
208
+ - example/output/documentation.out
209
+ - example/output/email_parser.out
210
+ - example/output/empty.err
211
+ - example/output/erb.out
212
+ - example/output/ignore.out
213
+ - example/output/ignore_whitespace.out
214
+ - example/output/ip_address.out
215
+ - example/output/json.out
216
+ - example/output/local.out
217
+ - example/output/mathn.out
218
+ - example/output/minilisp.out
219
+ - example/output/modularity.out
220
+ - example/output/nested_errors.out
221
+ - example/output/parens.out
222
+ - example/output/readme.out
223
+ - example/output/seasons.out
224
+ - example/output/sentence.out
225
+ - example/output/simple_xml.out
226
+ - example/output/string_parser.out
227
+ - example/parens.rb
228
+ - example/readme.rb
229
+ - example/seasons.rb
230
+ - example/sentence.rb
231
+ - example/simple.lit
232
+ - example/simple_xml.rb
233
+ - example/string_parser.rb
234
+ - example/test.lit
235
+ homepage: http://kschiess.github.com/parslet
236
+ licenses: []
237
+ post_install_message:
238
+ rdoc_options:
239
+ - --main
240
+ - README
241
+ require_paths:
242
+ - lib
243
+ required_ruby_version: !ruby/object:Gem::Requirement
244
+ none: false
245
+ requirements:
246
+ - - ! '>='
247
+ - !ruby/object:Gem::Version
248
+ version: '0'
249
+ segments:
250
+ - 0
251
+ hash: 337185453230177854
252
+ required_rubygems_version: !ruby/object:Gem::Requirement
253
+ none: false
254
+ requirements:
255
+ - - ! '>='
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ requirements: []
259
+ rubyforge_project:
260
+ rubygems_version: 1.8.24
261
+ signing_key:
262
+ specification_version: 3
263
+ summary: Parser construction library with great error reporting in Ruby.
264
+ test_files: []