peglite 0.0.2 → 0.0.3
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.
- data/.gemspec +1 -1
- data/CHANGELOG.yaml +5 -0
- data/Gemfile.lock +14 -0
- data/ToDo +11 -0
- data/examples/json.rb +36 -0
- data/lib/peglite.rb +17 -20
- data/test/address.rb +5 -5
- metadata +3 -1
data/.gemspec
CHANGED
data/CHANGELOG.yaml
CHANGED
data/Gemfile.lock
ADDED
data/ToDo
CHANGED
data/examples/json.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'peglite'
|
2
|
+
|
3
|
+
class MyJson < PegLite
|
4
|
+
rule json: "object | array"
|
5
|
+
rule node: "object | array | value"
|
6
|
+
rule object: "_ LCURLY _ ( pair ( _ COMMA _ pair )* )? _ RCURLY _"
|
7
|
+
rule pair: "string _ COLON _ node"
|
8
|
+
rule array: "_ LSQUARE _ ( node ( _ COMMA _ node)* )? _ RSQUARE _"
|
9
|
+
rule value: "string | number | boolean | null"
|
10
|
+
rule string: (/"((?:\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})|[^"\x00-\x1f])*)"/)
|
11
|
+
rule number: (/(\-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][\-\+]?[0-9]+)?)/)
|
12
|
+
rule boolean: "true | false"
|
13
|
+
rule true: /(true)/
|
14
|
+
rule false: /(false)/
|
15
|
+
rule null: /(null)/
|
16
|
+
|
17
|
+
# TODO Parse findings are correct but need methods to reshape them
|
18
|
+
end
|
19
|
+
|
20
|
+
# Test from Parslet's json.rb
|
21
|
+
# https://github.com/kschiess/parslet/blob/master/example/json.rb
|
22
|
+
s = %{
|
23
|
+
[ 1, 2, 3, null,
|
24
|
+
"asdfasdf asdfds", { "a": -1.2 }, { "b": true, "c": false },
|
25
|
+
0.1e24, true, false, [ 1 ] ]
|
26
|
+
}
|
27
|
+
|
28
|
+
out = XXX MyJson.new(debug: false).parse(s)
|
29
|
+
|
30
|
+
p out; puts
|
31
|
+
|
32
|
+
out == [
|
33
|
+
1, 2, 3, nil,
|
34
|
+
"asdfasdf asdfds", { "a" => -1.2 }, { "b" => true, "c" => false },
|
35
|
+
0.1e24, true, false, [ 1 ]
|
36
|
+
] || raise("MyJson is a failure")
|
data/lib/peglite.rb
CHANGED
@@ -7,33 +7,40 @@ require 'yaml'; def YYY *args; args.each \
|
|
7
7
|
|
8
8
|
#------------------------------------------------------------------------------
|
9
9
|
class PegLite
|
10
|
-
VERSION = '0.0.
|
10
|
+
VERSION = '0.0.3'
|
11
11
|
|
12
|
-
$PegLiteRules = {} # TODO get rid of global variable smell
|
13
12
|
def self.rule args
|
14
13
|
name, rule = args.first
|
15
14
|
name = name.to_s
|
16
15
|
$PegLiteTopRule ||= name
|
17
16
|
if rule.kind_of? Regexp
|
18
17
|
regex = Regexp.new(rule.to_s.sub(/:/, ':\\A'))
|
19
|
-
|
18
|
+
rule = {
|
20
19
|
'type' => 'rgx',
|
21
20
|
'rule' => regex,
|
22
21
|
'min' => 1,
|
23
22
|
'max' => 1,
|
24
23
|
}
|
25
24
|
elsif rule.kind_of? String
|
26
|
-
|
25
|
+
rule = PegLite::Compiler.new(rule).compile
|
27
26
|
else
|
28
27
|
fail "Don't know how to make rule '#{name}' from '#{rule}'"
|
29
28
|
end
|
29
|
+
self.send :define_method, "rule_#{name}" do
|
30
|
+
match rule
|
31
|
+
end
|
30
32
|
end
|
31
33
|
|
32
34
|
# TODO define all the Pegex Atoms here
|
33
35
|
rule _: (/\s*/)
|
34
36
|
rule __: (/\s+/)
|
37
|
+
rule LCURLY: (/\{/)
|
38
|
+
rule RCURLY: (/\}/)
|
39
|
+
rule LSQUARE: (/\[/)
|
40
|
+
rule RSQUARE: (/\]/)
|
35
41
|
rule EQUAL: (/=/)
|
36
42
|
rule COMMA: (/,/)
|
43
|
+
rule COLON: (/:/)
|
37
44
|
rule PLUS: (/\+/)
|
38
45
|
rule NL: (/\n/)
|
39
46
|
rule EOL: (/\r?\n/)
|
@@ -53,7 +60,6 @@ class PegLite
|
|
53
60
|
|
54
61
|
@pos = 0
|
55
62
|
@far = 0
|
56
|
-
@rules = $PegLiteRules
|
57
63
|
yield self if block_given?
|
58
64
|
end
|
59
65
|
|
@@ -69,12 +75,9 @@ class PegLite
|
|
69
75
|
def match rule=nil
|
70
76
|
if not rule.kind_of? Hash
|
71
77
|
rule ||= caller.first.scan(/(\w+)/).last.first
|
72
|
-
|
73
|
-
if
|
74
|
-
|
75
|
-
end
|
76
|
-
fail "Can't find rule for '#{rule_name}'" \
|
77
|
-
if not(rule and rule.kind_of? Hash)
|
78
|
+
method_name = "rule_#{rule}"
|
79
|
+
return send method_name if respond_to? method_name
|
80
|
+
fail "Can't find rule for '#{rule}'"
|
78
81
|
end
|
79
82
|
|
80
83
|
pos, count, matched, type, child, min, max =
|
@@ -128,15 +131,9 @@ class PegLite
|
|
128
131
|
# TODO move trace/debug out of default match_ref method
|
129
132
|
def match_ref ref
|
130
133
|
trace "Try #{ref}" if @debug
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
if @rules[ref]
|
135
|
-
m = match @rules[ref]
|
136
|
-
else
|
137
|
-
fail "No rule defined for '#{ref}'"
|
138
|
-
end
|
139
|
-
end
|
134
|
+
method = [ ref, "rule_#{ref}" ].find{|e| respond_to? e}
|
135
|
+
fail "No rule defined for '#{ref}'" unless method
|
136
|
+
m = send method
|
140
137
|
if m
|
141
138
|
m = (@wrap and not m.empty?) ? [{ref => m}] : m
|
142
139
|
trace "Got #{ref}" if @debug
|
data/test/address.rb
CHANGED
@@ -74,12 +74,12 @@ end
|
|
74
74
|
# This class defines a complete address parser using PegLite
|
75
75
|
class AddressParser < PegLite
|
76
76
|
rule address: "name street place"
|
77
|
-
rule name:
|
78
|
-
rule street:
|
77
|
+
rule name: /(.*?)\n/
|
78
|
+
rule street: /(.*?)\n/
|
79
79
|
rule place: "city COMMA _ state __ zip NL"
|
80
|
-
rule city:
|
81
|
-
rule state:
|
82
|
-
rule zip:
|
80
|
+
rule city: /(\w+(?: \w+)?)/
|
81
|
+
rule state: /(WA|OR|CA)/ # Left Coast Rulez
|
82
|
+
rule zip: /(\d{5})/
|
83
83
|
end
|
84
84
|
|
85
85
|
# Extend AddressParser
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peglite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -22,10 +22,12 @@ files:
|
|
22
22
|
- .gemspec
|
23
23
|
- CHANGELOG.yaml
|
24
24
|
- Gemfile
|
25
|
+
- Gemfile.lock
|
25
26
|
- LICENSE
|
26
27
|
- README.rdoc
|
27
28
|
- Rakefile
|
28
29
|
- ToDo
|
30
|
+
- examples/json.rb
|
29
31
|
- examples/parslet1.rb
|
30
32
|
- examples/parslet2.rb
|
31
33
|
- lib/peglite.rb
|