parslet 1.6.0 → 1.6.1
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.
- checksums.yaml +4 -4
- data/HISTORY.txt +5 -1
- data/lib/parslet/atoms/base.rb +4 -4
- data/lib/parslet/atoms/context.rb +9 -5
- data/lib/parslet/atoms/infix.rb +2 -2
- data/lib/parslet/atoms/lookahead.rb +5 -4
- data/lib/parslet/context.rb +2 -0
- data/lib/parslet/position.rb +21 -0
- data/lib/parslet/slice.rb +12 -5
- data/lib/parslet/source.rb +14 -5
- data/lib/parslet/source/line_cache.rb +4 -2
- metadata +52 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 041b9dcd017516b0335b4553a0ffcde588d8316c
|
4
|
+
data.tar.gz: 6f57cfc783537bd7041a5f67703a894b6350a1e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dccb1e2066a77937485d82d3ac155725db744a03e2ab37360bfe105ae612447074638bc40b5f88f0ee8ece95a407d161179f82e9bedd8de585d15aaced535382
|
7
|
+
data.tar.gz: d1f451935a0da7518ef301eab7bc0b0d689d1d277e1e28bca4e47e48be486c45f7d9f4839df4587d4490c9833ea9f378e1fdc92eddd77a5122d5ad66bc17ae30
|
data/HISTORY.txt
CHANGED
@@ -3,7 +3,11 @@
|
|
3
3
|
- prsnt? and absnt? are now finally banned into oblivion. Wasting vocals for
|
4
4
|
the win.
|
5
5
|
|
6
|
-
= 1.
|
6
|
+
= 1.7 / ???
|
7
|
+
|
8
|
+
! Small speed gains from improvements on the hot spots.
|
9
|
+
|
10
|
+
= 1.6 / 1May2014
|
7
11
|
|
8
12
|
+ EXPERIMENTAL: Parslet accelerators permit replacing parts of your parser
|
9
13
|
with optimized atoms using pattern matching. Look at
|
data/lib/parslet/atoms/base.rb
CHANGED
@@ -36,7 +36,7 @@ class Parslet::Atoms::Base
|
|
36
36
|
# Cheating has not paid off. Now pay the cost: Rerun the parse,
|
37
37
|
# gathering error information in the process.
|
38
38
|
reporter = options[:reporter] || Parslet::ErrorReporter::Tree.new
|
39
|
-
source.
|
39
|
+
source.bytepos = 0
|
40
40
|
success, value = setup_and_apply(source, reporter, !options[:prefix])
|
41
41
|
|
42
42
|
fail "Assertion failed: success was true when parsing with reporter" \
|
@@ -78,7 +78,7 @@ class Parslet::Atoms::Base
|
|
78
78
|
# @param consume_all [Boolean] true if the current parse must consume
|
79
79
|
# all input by itself.
|
80
80
|
def apply(source, context, consume_all=false)
|
81
|
-
old_pos = source.
|
81
|
+
old_pos = source.bytepos
|
82
82
|
|
83
83
|
success, value = result = context.try_with_cache(self, source, consume_all)
|
84
84
|
|
@@ -91,7 +91,7 @@ class Parslet::Atoms::Base
|
|
91
91
|
offending_input = source.consume(10)
|
92
92
|
|
93
93
|
# Rewind input (as happens always in error case)
|
94
|
-
source.
|
94
|
+
source.bytepos = old_pos
|
95
95
|
|
96
96
|
return context.err_at(
|
97
97
|
self,
|
@@ -106,7 +106,7 @@ class Parslet::Atoms::Base
|
|
106
106
|
end
|
107
107
|
|
108
108
|
# We only reach this point if the parse has failed. Rewind the input.
|
109
|
-
source.
|
109
|
+
source.bytepos = old_pos
|
110
110
|
return result
|
111
111
|
end
|
112
112
|
|
@@ -24,14 +24,14 @@ module Parslet::Atoms
|
|
24
24
|
# advance the input pos by the same amount of bytes.
|
25
25
|
#
|
26
26
|
def try_with_cache(obj, source, consume_all)
|
27
|
-
beg = source.
|
27
|
+
beg = source.bytepos
|
28
28
|
|
29
29
|
# Not in cache yet? Return early.
|
30
30
|
unless entry = lookup(obj, beg)
|
31
31
|
result = obj.try(source, self, consume_all)
|
32
32
|
|
33
33
|
if obj.cached?
|
34
|
-
set obj, beg, [result, source.
|
34
|
+
set obj, beg, [result, source.bytepos-beg]
|
35
35
|
end
|
36
36
|
|
37
37
|
return result
|
@@ -43,7 +43,7 @@ module Parslet::Atoms
|
|
43
43
|
# The data we're skipping here has been read before. (since it is in
|
44
44
|
# the cache) PLUS the actual contents are not interesting anymore since
|
45
45
|
# we know obj matches at beg. So skip reading.
|
46
|
-
source.
|
46
|
+
source.bytepos = beg + advance
|
47
47
|
return result
|
48
48
|
end
|
49
49
|
|
@@ -81,11 +81,15 @@ module Parslet::Atoms
|
|
81
81
|
end
|
82
82
|
|
83
83
|
private
|
84
|
+
# NOTE These methods use #object_id directly, since that seems to bring the
|
85
|
+
# most performance benefit. This is a hot spot; going through
|
86
|
+
# Atoms::Base#hash doesn't yield as much.
|
87
|
+
#
|
84
88
|
def lookup(obj, pos)
|
85
|
-
@cache[pos][obj]
|
89
|
+
@cache[pos][obj.object_id]
|
86
90
|
end
|
87
91
|
def set(obj, pos, val)
|
88
|
-
@cache[pos][obj] = val
|
92
|
+
@cache[pos][obj.object_id] = val
|
89
93
|
end
|
90
94
|
end
|
91
95
|
end
|
data/lib/parslet/atoms/infix.rb
CHANGED
@@ -62,7 +62,7 @@ class Parslet::Atoms::Infix < Parslet::Atoms::Base
|
|
62
62
|
|
63
63
|
# Loop until we fail on operator matching or until input runs out.
|
64
64
|
loop do
|
65
|
-
op_pos = source.
|
65
|
+
op_pos = source.bytepos
|
66
66
|
op_match, prec, assoc = match_operation(source, context, false)
|
67
67
|
|
68
68
|
# If no operator could be matched here, one of several cases
|
@@ -82,7 +82,7 @@ class Parslet::Atoms::Infix < Parslet::Atoms::Base
|
|
82
82
|
result << precedence_climb(
|
83
83
|
source, context, consume_all, next_prec, true)
|
84
84
|
else
|
85
|
-
source.
|
85
|
+
source.bytepos = op_pos
|
86
86
|
return unwrap(result)
|
87
87
|
end
|
88
88
|
end
|
@@ -22,22 +22,23 @@ class Parslet::Atoms::Lookahead < Parslet::Atoms::Base
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def try(source, context, consume_all)
|
25
|
-
|
25
|
+
rewind_pos = source.bytepos
|
26
|
+
error_pos = source.pos
|
26
27
|
|
27
28
|
success, value = bound_parslet.apply(source, context, consume_all)
|
28
29
|
|
29
30
|
if positive
|
30
31
|
return succ(nil) if success
|
31
|
-
return context.err_at(self, source, @error_msgs[:positive],
|
32
|
+
return context.err_at(self, source, @error_msgs[:positive], error_pos)
|
32
33
|
else
|
33
34
|
return succ(nil) unless success
|
34
|
-
return context.err_at(self, source, @error_msgs[:negative],
|
35
|
+
return context.err_at(self, source, @error_msgs[:negative], error_pos)
|
35
36
|
end
|
36
37
|
|
37
38
|
# This is probably the only parslet that rewinds its input in #try.
|
38
39
|
# Lookaheads NEVER consume their input, even on success, that's why.
|
39
40
|
ensure
|
40
|
-
source.
|
41
|
+
source.bytepos = rewind_pos
|
41
42
|
end
|
42
43
|
|
43
44
|
precedence LOOKAHEAD
|
data/lib/parslet/context.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
# Encapsules the concept of a position inside a string.
|
3
|
+
#
|
4
|
+
class Parslet::Position
|
5
|
+
attr_reader :bytepos
|
6
|
+
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
def initialize string, bytepos
|
10
|
+
@string = string
|
11
|
+
@bytepos = bytepos
|
12
|
+
end
|
13
|
+
|
14
|
+
def charpos
|
15
|
+
@string.byteslice(0, @bytepos).size
|
16
|
+
end
|
17
|
+
|
18
|
+
def <=> b
|
19
|
+
self.bytepos <=> b.bytepos
|
20
|
+
end
|
21
|
+
end
|
data/lib/parslet/slice.rb
CHANGED
@@ -23,17 +23,23 @@
|
|
23
23
|
# delegation, we opt for a partial emulation that gets the job done.
|
24
24
|
#
|
25
25
|
class Parslet::Slice
|
26
|
-
attr_reader :str
|
26
|
+
attr_reader :str
|
27
|
+
attr_reader :position
|
27
28
|
attr_reader :line_cache
|
28
29
|
|
29
30
|
# Construct a slice using a string, an offset and an optional line cache.
|
30
31
|
# The line cache should be able to answer to the #line_and_column message.
|
31
32
|
#
|
32
|
-
def initialize(
|
33
|
-
@
|
33
|
+
def initialize(position, string, line_cache=nil)
|
34
|
+
@position = position
|
35
|
+
@str = string
|
34
36
|
@line_cache = line_cache
|
35
37
|
end
|
36
38
|
|
39
|
+
def offset
|
40
|
+
@position.charpos
|
41
|
+
end
|
42
|
+
|
37
43
|
# Compares slices to other slices or strings.
|
38
44
|
#
|
39
45
|
def == other
|
@@ -57,7 +63,7 @@ class Parslet::Slice
|
|
57
63
|
# as the one of this slice.
|
58
64
|
#
|
59
65
|
def +(other)
|
60
|
-
self.class.new(str + other.to_s,
|
66
|
+
self.class.new(@position, str + other.to_s, line_cache)
|
61
67
|
end
|
62
68
|
|
63
69
|
# Returns a <line, column> tuple referring to the original input.
|
@@ -66,7 +72,7 @@ class Parslet::Slice
|
|
66
72
|
raise ArgumentError, "No line cache was given, cannot infer line and column." \
|
67
73
|
unless line_cache
|
68
74
|
|
69
|
-
line_cache.line_and_column(
|
75
|
+
line_cache.line_and_column(@position.bytepos)
|
70
76
|
end
|
71
77
|
|
72
78
|
|
@@ -96,6 +102,7 @@ class Parslet::Slice
|
|
96
102
|
|
97
103
|
# Prints the slice as <code>"string"@offset</code>.
|
98
104
|
def inspect
|
105
|
+
|
99
106
|
str.inspect << "@#{offset}"
|
100
107
|
end
|
101
108
|
end
|
data/lib/parslet/source.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'stringio'
|
3
3
|
require 'strscan'
|
4
4
|
|
5
|
+
require 'parslet/position'
|
5
6
|
require 'parslet/source/line_cache'
|
6
7
|
|
7
8
|
module Parslet
|
@@ -38,11 +39,11 @@ module Parslet
|
|
38
39
|
# input.
|
39
40
|
#
|
40
41
|
def consume(n)
|
41
|
-
|
42
|
+
position = self.pos
|
42
43
|
slice_str = @str.scan(@re_cache[n])
|
43
44
|
slice = Parslet::Slice.new(
|
45
|
+
position,
|
44
46
|
slice_str,
|
45
|
-
original_pos,
|
46
47
|
@line_cache)
|
47
48
|
|
48
49
|
return slice
|
@@ -67,11 +68,19 @@ module Parslet
|
|
67
68
|
end
|
68
69
|
|
69
70
|
# Position of the parse as a character offset into the original string.
|
70
|
-
#
|
71
|
+
#
|
72
|
+
# @note Please be aware of encodings at this point.
|
73
|
+
#
|
71
74
|
def pos
|
75
|
+
Position.new(@str.string, @str.pos)
|
76
|
+
end
|
77
|
+
def bytepos
|
72
78
|
@str.pos
|
73
79
|
end
|
74
|
-
|
80
|
+
|
81
|
+
# @note Please be aware of encodings at this point.
|
82
|
+
#
|
83
|
+
def bytepos=(n)
|
75
84
|
@str.pos = n
|
76
85
|
rescue RangeError
|
77
86
|
end
|
@@ -81,7 +90,7 @@ module Parslet
|
|
81
90
|
# given by #pos.
|
82
91
|
#
|
83
92
|
def line_and_column(position=nil)
|
84
|
-
@line_cache.line_and_column(position || self.
|
93
|
+
@line_cache.line_and_column(position || self.bytepos)
|
85
94
|
end
|
86
95
|
end
|
87
96
|
end
|
@@ -12,9 +12,11 @@ class Parslet::Source
|
|
12
12
|
@line_ends.extend RangeSearch
|
13
13
|
end
|
14
14
|
|
15
|
-
# Returns a <line, column> tuple for the given input position.
|
16
|
-
#
|
15
|
+
# Returns a <line, column> tuple for the given input position. Input
|
16
|
+
# position must be given as byte offset into original string.
|
17
|
+
#
|
17
18
|
def line_and_column(pos)
|
19
|
+
pos = pos.bytepos if pos.respond_to? :bytepos
|
18
20
|
eol_idx = @line_ends.lbound(pos)
|
19
21
|
|
20
22
|
if eol_idx
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parslet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kaspar Schiess
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: blankslate
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
27
|
description:
|
@@ -33,49 +33,8 @@ extra_rdoc_files:
|
|
33
33
|
files:
|
34
34
|
- HISTORY.txt
|
35
35
|
- LICENSE
|
36
|
-
- Rakefile
|
37
36
|
- README
|
38
|
-
-
|
39
|
-
- lib/parslet/accelerator/engine.rb
|
40
|
-
- lib/parslet/accelerator.rb
|
41
|
-
- lib/parslet/atoms/alternative.rb
|
42
|
-
- lib/parslet/atoms/base.rb
|
43
|
-
- lib/parslet/atoms/can_flatten.rb
|
44
|
-
- lib/parslet/atoms/capture.rb
|
45
|
-
- lib/parslet/atoms/context.rb
|
46
|
-
- lib/parslet/atoms/dsl.rb
|
47
|
-
- lib/parslet/atoms/dynamic.rb
|
48
|
-
- lib/parslet/atoms/entity.rb
|
49
|
-
- lib/parslet/atoms/infix.rb
|
50
|
-
- lib/parslet/atoms/lookahead.rb
|
51
|
-
- lib/parslet/atoms/named.rb
|
52
|
-
- lib/parslet/atoms/re.rb
|
53
|
-
- lib/parslet/atoms/repetition.rb
|
54
|
-
- lib/parslet/atoms/scope.rb
|
55
|
-
- lib/parslet/atoms/sequence.rb
|
56
|
-
- lib/parslet/atoms/str.rb
|
57
|
-
- lib/parslet/atoms/visitor.rb
|
58
|
-
- lib/parslet/atoms.rb
|
59
|
-
- lib/parslet/cause.rb
|
60
|
-
- lib/parslet/context.rb
|
61
|
-
- lib/parslet/convenience.rb
|
62
|
-
- lib/parslet/error_reporter/deepest.rb
|
63
|
-
- lib/parslet/error_reporter/tree.rb
|
64
|
-
- lib/parslet/error_reporter.rb
|
65
|
-
- lib/parslet/export.rb
|
66
|
-
- lib/parslet/expression/treetop.rb
|
67
|
-
- lib/parslet/expression.rb
|
68
|
-
- lib/parslet/graphviz.rb
|
69
|
-
- lib/parslet/parser.rb
|
70
|
-
- lib/parslet/pattern/binding.rb
|
71
|
-
- lib/parslet/pattern.rb
|
72
|
-
- lib/parslet/rig/rspec.rb
|
73
|
-
- lib/parslet/scope.rb
|
74
|
-
- lib/parslet/slice.rb
|
75
|
-
- lib/parslet/source/line_cache.rb
|
76
|
-
- lib/parslet/source.rb
|
77
|
-
- lib/parslet/transform.rb
|
78
|
-
- lib/parslet.rb
|
37
|
+
- Rakefile
|
79
38
|
- example/big.erb
|
80
39
|
- example/boolean_algebra.rb
|
81
40
|
- example/calc.rb
|
@@ -133,30 +92,73 @@ files:
|
|
133
92
|
- example/simple_xml.rb
|
134
93
|
- example/string_parser.rb
|
135
94
|
- example/test.lit
|
95
|
+
- lib/parslet.rb
|
96
|
+
- lib/parslet/accelerator.rb
|
97
|
+
- lib/parslet/accelerator/application.rb
|
98
|
+
- lib/parslet/accelerator/engine.rb
|
99
|
+
- lib/parslet/atoms.rb
|
100
|
+
- lib/parslet/atoms/alternative.rb
|
101
|
+
- lib/parslet/atoms/base.rb
|
102
|
+
- lib/parslet/atoms/can_flatten.rb
|
103
|
+
- lib/parslet/atoms/capture.rb
|
104
|
+
- lib/parslet/atoms/context.rb
|
105
|
+
- lib/parslet/atoms/dsl.rb
|
106
|
+
- lib/parslet/atoms/dynamic.rb
|
107
|
+
- lib/parslet/atoms/entity.rb
|
108
|
+
- lib/parslet/atoms/infix.rb
|
109
|
+
- lib/parslet/atoms/lookahead.rb
|
110
|
+
- lib/parslet/atoms/named.rb
|
111
|
+
- lib/parslet/atoms/re.rb
|
112
|
+
- lib/parslet/atoms/repetition.rb
|
113
|
+
- lib/parslet/atoms/scope.rb
|
114
|
+
- lib/parslet/atoms/sequence.rb
|
115
|
+
- lib/parslet/atoms/str.rb
|
116
|
+
- lib/parslet/atoms/visitor.rb
|
117
|
+
- lib/parslet/cause.rb
|
118
|
+
- lib/parslet/context.rb
|
119
|
+
- lib/parslet/convenience.rb
|
120
|
+
- lib/parslet/error_reporter.rb
|
121
|
+
- lib/parslet/error_reporter/deepest.rb
|
122
|
+
- lib/parslet/error_reporter/tree.rb
|
123
|
+
- lib/parslet/export.rb
|
124
|
+
- lib/parslet/expression.rb
|
125
|
+
- lib/parslet/expression/treetop.rb
|
126
|
+
- lib/parslet/graphviz.rb
|
127
|
+
- lib/parslet/parser.rb
|
128
|
+
- lib/parslet/pattern.rb
|
129
|
+
- lib/parslet/pattern/binding.rb
|
130
|
+
- lib/parslet/position.rb
|
131
|
+
- lib/parslet/rig/rspec.rb
|
132
|
+
- lib/parslet/scope.rb
|
133
|
+
- lib/parslet/slice.rb
|
134
|
+
- lib/parslet/source.rb
|
135
|
+
- lib/parslet/source/line_cache.rb
|
136
|
+
- lib/parslet/transform.rb
|
136
137
|
homepage: http://kschiess.github.com/parslet
|
137
138
|
licenses:
|
138
139
|
- MIT
|
139
140
|
metadata: {}
|
140
141
|
post_install_message:
|
141
142
|
rdoc_options:
|
142
|
-
- --main
|
143
|
+
- "--main"
|
143
144
|
- README
|
144
145
|
require_paths:
|
145
146
|
- lib
|
146
147
|
required_ruby_version: !ruby/object:Gem::Requirement
|
147
148
|
requirements:
|
148
|
-
- -
|
149
|
+
- - ">="
|
149
150
|
- !ruby/object:Gem::Version
|
150
151
|
version: '0'
|
151
152
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
153
|
requirements:
|
153
|
-
- -
|
154
|
+
- - ">="
|
154
155
|
- !ruby/object:Gem::Version
|
155
156
|
version: '0'
|
156
157
|
requirements: []
|
157
158
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.
|
159
|
+
rubygems_version: 2.2.2
|
159
160
|
signing_key:
|
160
161
|
specification_version: 4
|
161
162
|
summary: Parser construction library with great error reporting in Ruby.
|
162
163
|
test_files: []
|
164
|
+
has_rdoc:
|