parslet 1.0.1 → 1.1.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.
@@ -0,0 +1,112 @@
1
+
2
+ require 'stringio'
3
+
4
+ # Wraps the input IO to parslet. The interface defined by this class is
5
+ # smaller than what IO offers, but enhances it with a #column and #line
6
+ # method for the current position.
7
+ #
8
+ class Parslet::Source
9
+ attr_reader :line_ends
10
+
11
+ def initialize(io)
12
+ if io.respond_to? :to_str
13
+ io = StringIO.new(io)
14
+ end
15
+
16
+ @io = io
17
+ warn "Line counting will be off if the IO is not rewound." unless @io.pos==0
18
+
19
+ # Stores line endings as a simple position number. The first line always
20
+ # starts at 0; numbers beyond the biggest entry are on any line > size,
21
+ # but probably make a scan to that position neccessary.
22
+ @line_ends = []
23
+ @line_ends.extend RangeSearch
24
+ @eof_reached_once = false
25
+ end
26
+
27
+ def read(n)
28
+ start_pos = pos
29
+ @io.read(n).tap { |buf| scan_for_line_endings(start_pos, buf) }
30
+ end
31
+
32
+ def eof?
33
+ @io.eof?
34
+ end
35
+
36
+ def pos
37
+ @io.pos
38
+ end
39
+
40
+ # NOTE: If you seek beyond the point that you last read, you will get
41
+ # undefined behaviour. This is by design.
42
+ def pos=(new_pos)
43
+ @io.pos = new_pos
44
+ end
45
+
46
+ def line_and_column(position=nil)
47
+ pos = (position || self.pos)
48
+ eol_idx = @line_ends.lbound(pos)
49
+
50
+ if eol_idx
51
+ # eol_idx points to the offset that ends the current line.
52
+ # Let's try to find the offset that starts it:
53
+ offset = eol_idx>0 && @line_ends[eol_idx-1] || 0
54
+ return [eol_idx+1, pos-offset+1]
55
+ else
56
+ # eol_idx is nil, that means that we're beyond the last line end that
57
+ # we know about. Pretend for now that we're just on the last line.
58
+ offset = @line_ends.last || 0
59
+ return [@line_ends.size+1, pos-offset+1]
60
+ end
61
+ end
62
+
63
+ # Mixin for arrays that implicitly give a number of ranges, where one range
64
+ # begins where the other one ends.
65
+ #
66
+ # Example:
67
+ #
68
+ # [10, 20, 30]
69
+ # # would describe [0, 10], (10, 20], (20, 30]
70
+ #
71
+ module RangeSearch
72
+ # Scans the array for the first number that is > than bound. Returns the
73
+ # index of that number.
74
+ #
75
+ def lbound(bound)
76
+ return nil if empty?
77
+ return nil unless last > bound
78
+
79
+ left = 0
80
+ right = size - 1
81
+
82
+ n = 10
83
+ loop do
84
+ mid = left + (right - left) / 2
85
+
86
+ if self[mid] > bound
87
+ right = mid
88
+ else
89
+ # assert: self[mid] <= bound
90
+ left = mid+1
91
+ end
92
+
93
+ if right <= left
94
+ return right
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def scan_for_line_endings(start_pos, buf)
103
+ # Scan the string for line endings; store the positions of all endings
104
+ # in @line_ends.
105
+ cur = -1
106
+ while buf && cur = buf.index("\n", cur+1)
107
+ @line_ends << (start_pos + cur+1)
108
+ end
109
+
110
+ @eof_reached_once = true
111
+ end
112
+ end
data/lib/parslet.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'stringio'
2
-
3
1
  # A simple parser generator library. Typical usage would look like this:
4
2
  #
5
3
  # require 'parslet'
@@ -229,6 +227,7 @@ module Parslet
229
227
  autoload :Expression, 'parslet/expression'
230
228
  end
231
229
 
230
+ require 'parslet/source'
232
231
  require 'parslet/error_tree'
233
232
  require 'parslet/atoms'
234
233
  require 'parslet/pattern'
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 0
8
7
  - 1
9
- version: 1.0.1
8
+ - 0
9
+ version: 1.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kaspar Schiess
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-17 00:00:00 +01:00
17
+ date: 2011-02-02 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,10 +27,8 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
29
  - 2
30
- - 1
31
- - 2
32
- - 3
33
- version: 2.1.2.3
30
+ - 0
31
+ version: "2.0"
34
32
  type: :runtime
35
33
  version_requirements: *id001
36
34
  - !ruby/object:Gem::Dependency
@@ -59,6 +57,19 @@ dependencies:
59
57
  version: "0"
60
58
  type: :development
61
59
  version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: sdoc
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ type: :development
72
+ version_requirements: *id004
62
73
  description:
63
74
  email: kaspar.schiess@absurd.li
64
75
  executables: []
@@ -75,6 +86,7 @@ files:
75
86
  - README
76
87
  - lib/parslet/atoms/alternative.rb
77
88
  - lib/parslet/atoms/base.rb
89
+ - lib/parslet/atoms/context.rb
78
90
  - lib/parslet/atoms/entity.rb
79
91
  - lib/parslet/atoms/lookahead.rb
80
92
  - lib/parslet/atoms/named.rb
@@ -82,8 +94,11 @@ files:
82
94
  - lib/parslet/atoms/repetition.rb
83
95
  - lib/parslet/atoms/sequence.rb
84
96
  - lib/parslet/atoms/str.rb
97
+ - lib/parslet/atoms/visitor.rb
85
98
  - lib/parslet/atoms.rb
99
+ - lib/parslet/convenience.rb
86
100
  - lib/parslet/error_tree.rb
101
+ - lib/parslet/export.rb
87
102
  - lib/parslet/expression/treetop.rb
88
103
  - lib/parslet/expression.rb
89
104
  - lib/parslet/parser.rb
@@ -91,11 +106,13 @@ files:
91
106
  - lib/parslet/pattern/context.rb
92
107
  - lib/parslet/pattern.rb
93
108
  - lib/parslet/rig/rspec.rb
109
+ - lib/parslet/source.rb
94
110
  - lib/parslet/transform.rb
95
111
  - lib/parslet.rb
96
112
  - example/documentation.rb
97
113
  - example/email_parser.rb
98
114
  - example/empty.rb
115
+ - example/erb.rb
99
116
  - example/ip_address.rb
100
117
  - example/minilisp.rb
101
118
  - example/parens.rb