parslet 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +6 -1
- data/Rakefile +1 -1
- data/lib/parslet/atoms/base.rb +26 -22
- data/lib/parslet/expression.rb +4 -1
- data/lib/parslet/expression/treetop.rb +7 -9
- metadata +4 -4
data/HISTORY.txt
CHANGED
data/Rakefile
CHANGED
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
|
|
18
18
|
|
19
19
|
# Change these as appropriate
|
20
20
|
s.name = "parslet"
|
21
|
-
s.version = "0.
|
21
|
+
s.version = "0.11.0"
|
22
22
|
s.summary = "Parser construction library with great error reporting in Ruby."
|
23
23
|
s.author = "Kaspar Schiess"
|
24
24
|
s.email = "kaspar.schiess@absurd.li"
|
data/lib/parslet/atoms/base.rb
CHANGED
@@ -35,7 +35,7 @@ class Parslet::Atoms::Base
|
|
35
35
|
# p [:try, self, io.string[io.pos, 20]]
|
36
36
|
begin
|
37
37
|
r = try(io)
|
38
|
-
# p [:return_from, self, flatten(r)]
|
38
|
+
# p [:return_from, self, r, flatten(r)]
|
39
39
|
@last_cause = nil
|
40
40
|
return r
|
41
41
|
rescue Parslet::ParseFailed => ex
|
@@ -89,30 +89,34 @@ class Parslet::Atoms::Base
|
|
89
89
|
fail "BUG: Unknown tag #{tag.inspect}."
|
90
90
|
end
|
91
91
|
def flatten_sequence(list)
|
92
|
-
list.inject('') { |r, e| # and then merge flat elements
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
when [String, String]
|
103
|
-
r << e
|
92
|
+
list.compact.inject('') { |r, e| # and then merge flat elements
|
93
|
+
merge_fold(r, e)
|
94
|
+
}
|
95
|
+
end
|
96
|
+
def merge_fold(l, r)
|
97
|
+
# equal pairs: merge.
|
98
|
+
if l.class == r.class
|
99
|
+
if l.is_a?(Hash)
|
100
|
+
warn_about_duplicate_keys(l, r)
|
101
|
+
return l.merge(r)
|
104
102
|
else
|
105
|
-
|
106
|
-
r # Ignore e, since its not a hash we can merge
|
107
|
-
else
|
108
|
-
# Now e is either nil, in which case we drop it, or something else.
|
109
|
-
# If it is something else, it is probably more important than r,
|
110
|
-
# since we've checked for important values of r above.
|
111
|
-
e||r
|
112
|
-
end
|
103
|
+
return l + r
|
113
104
|
end
|
114
|
-
|
105
|
+
end
|
106
|
+
|
107
|
+
# unequal pairs: hoist to same level.
|
108
|
+
|
109
|
+
# special case: If one of them is a string, the other is more important
|
110
|
+
return l if r.class == String
|
111
|
+
return r if l.class == String
|
112
|
+
|
113
|
+
# otherwise just create an array for one of them to live in
|
114
|
+
return l + [r] if r.class == Hash
|
115
|
+
return [l] + r if l.class == Hash
|
116
|
+
|
117
|
+
fail "Unhandled case when foldr'ing sequence."
|
115
118
|
end
|
119
|
+
|
116
120
|
def flatten_repetition(list)
|
117
121
|
if list.any? { |e| e.instance_of?(Hash) }
|
118
122
|
# If keyed subtrees are in the array, we'll want to discard all
|
data/lib/parslet/expression.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
# Allows specifying rules as strings using the exact same grammar that treetop
|
3
3
|
# does, minus the actions. This is on one hand a good example of a fully fledged
|
4
4
|
# parser and on the other hand might even turn out really useful.
|
5
|
+
#
|
6
|
+
# This can be viewed as an extension to parslet and might even be hosted in
|
7
|
+
# its own gem one fine day.
|
5
8
|
#
|
6
9
|
# NOT FINISHED & EXPERIMENTAL
|
7
10
|
#
|
@@ -22,7 +25,7 @@ class Parslet::Expression
|
|
22
25
|
def transform(tree)
|
23
26
|
transform = Treetop::Transform.new
|
24
27
|
|
25
|
-
pp tree
|
28
|
+
# pp tree
|
26
29
|
transform.apply(tree)
|
27
30
|
end
|
28
31
|
|
@@ -2,18 +2,15 @@ class Parslet::Expression::Treetop
|
|
2
2
|
class Parser < Parslet::Parser
|
3
3
|
root(:expression)
|
4
4
|
|
5
|
-
rule(:expression) {
|
6
|
-
alternatives
|
7
|
-
}
|
5
|
+
rule(:expression) { alternatives }
|
8
6
|
|
7
|
+
# alternative 'a' / 'b'
|
9
8
|
rule(:alternatives) {
|
10
|
-
simple >> (spaced('/') >>
|
11
|
-
simple
|
9
|
+
(simple >> (spaced('/') >> simple).repeat).as(:alt)
|
12
10
|
}
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
}
|
12
|
+
# sequence by simple concatenation 'a' 'b'
|
13
|
+
rule(:simple) { perhaps.repeat(1).as(:seq) }
|
17
14
|
|
18
15
|
rule(:perhaps) {
|
19
16
|
atom.as(:maybe) >> spaced('?') |
|
@@ -43,8 +40,9 @@ class Parslet::Expression::Treetop
|
|
43
40
|
end
|
44
41
|
|
45
42
|
class Transform < Parser::Transform
|
43
|
+
rule(:alt => subtree(:alt)) { Parslet::Atoms::Alternative.new(*alt) }
|
44
|
+
rule(:seq => sequence(:s)) { Parslet::Atoms::Sequence.new(*s) }
|
46
45
|
rule(:unwrap => simple(:u)) { u }
|
47
|
-
rule(sequence(:s)) { |d| Parslet::Atoms::Sequence.new(*d[:s]) }
|
48
46
|
rule(:maybe => simple(:m)) { |d| d[:m].maybe }
|
49
47
|
rule(:string => simple(:s)) { |d| str(d[:s]) }
|
50
48
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 11
|
8
|
+
- 0
|
9
|
+
version: 0.11.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: 2010-11-
|
17
|
+
date: 2010-11-25 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|