gullah 0.0.1 → 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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGES.md +6 -0
- data/README.md +8 -4
- data/lib/gullah/node.rb +13 -0
- data/lib/gullah/parse.rb +3 -3
- data/lib/gullah/version.rb +1 -1
- data/test/basic_test.rb +12 -12
- data/test/parse_demo_test.rb +35 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8aa15a5c7da0a8578bc3462d2342205dbba603f316384bebd2a500c8e15cb3f1
|
4
|
+
data.tar.gz: 0e16604686a51b37e14ae5272e218702b317b3a6447e159ccf8b0e685f176780
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ccb50387a8a3fb97cb4cf2ea4bb01946c6e300bda78b1af10aa83d8c0ff22c74de8551bc5dbb96ffec6ba0410a2946f8a24e946abe63a5076713f1d62dbfa12
|
7
|
+
data.tar.gz: c1916ff70ac408e8b870c2af1d7cdeb5036778b6876bf277e15ec9a9f2eb65e6c55e51ddb8d526ec99550e6bf508014e239aac532b1759f1c054b57de191bf8a
|
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -20,11 +20,11 @@ A simple, fault-tolerant bottom-up parser written in Ruby.
|
|
20
20
|
rule :N, 'nouns'
|
21
21
|
rule :A, 'adjectives'
|
22
22
|
|
23
|
-
leaf :determiners, /\b(the|
|
23
|
+
leaf :determiners, /\b(the|an?)\b/i
|
24
24
|
leaf :nouns, /\b(cat|mat)\b/i
|
25
25
|
leaf :prepositions, /\b(on|in|around|above|beside)\b/i
|
26
26
|
leaf :verbs, /\b(sat|slept|moped)\b/
|
27
|
-
leaf :adjectives, /\b(big|small|hairy|bald)\b/i
|
27
|
+
leaf :adjectives, /\b(big|small|hairy|bald|fat)\b/i
|
28
28
|
|
29
29
|
ignore :whatever, /[^\w\s]+/
|
30
30
|
end
|
@@ -33,8 +33,8 @@ A simple, fault-tolerant bottom-up parser written in Ruby.
|
|
33
33
|
parses = Cat.parse 'The fat cat sat on the mat.'
|
34
34
|
assert_equal 1, parses.length, 'there is only one parse of this sentence'
|
35
35
|
parse = parses.first
|
36
|
-
assert_equal 1, parse.
|
37
|
-
root = parse.
|
36
|
+
assert_equal 1, parse.roots.reject(&:ignorable?).length, 'there is a root node for this parse'
|
37
|
+
root = parse.roots.reject(&:ignorable?).first
|
38
38
|
assert_equal :S, root.name, 'the root node is a sentence'
|
39
39
|
verb = root.descendants.find { |d| d.name == :VP }&.descendants&.find { |d| d.name == :V }
|
40
40
|
assert_equal 'sat', verb&.text, 'we have the expected verb'
|
@@ -85,3 +85,7 @@ Another possibility, if I have sufficient spare time and am sufficiently ambitio
|
|
85
85
|
# Acknowledgements
|
86
86
|
|
87
87
|
I would like to thank my family and co-workers for tolerating me saying "Gullah" much more often than any of them expected.
|
88
|
+
|
89
|
+
# Dedication
|
90
|
+
|
91
|
+
I dedicate this gem to my son Jude, a.k.a [TurkeyMcMac](https://github.com/TurkeyMcMac). He was a better programmer than I will ever be and was only getting better. More importantly, he was a kind, funny, thoughtful person. I miss him every day. I love you, Jude.
|
data/lib/gullah/node.rb
CHANGED
@@ -7,6 +7,7 @@ module Gullah
|
|
7
7
|
# The parent node of this node, if any.
|
8
8
|
attr_reader :parent
|
9
9
|
|
10
|
+
# @private
|
10
11
|
attr_reader :rule # :nodoc:
|
11
12
|
|
12
13
|
##
|
@@ -26,6 +27,7 @@ module Gullah
|
|
26
27
|
# An alternative method for when a more telegraphic coding style is useful.
|
27
28
|
alias atts attributes
|
28
29
|
|
30
|
+
# @private
|
29
31
|
def initialize(parse, s, e, rule) # :nodoc:
|
30
32
|
@rule = rule
|
31
33
|
@leaf = rule.is_a?(Leaf) || trash?
|
@@ -100,6 +102,7 @@ module Gullah
|
|
100
102
|
end
|
101
103
|
|
102
104
|
# is this node some sort of boundary to further matching
|
105
|
+
# @private
|
103
106
|
def traversible? # :nodoc:
|
104
107
|
!(boundary? || trash? || error?)
|
105
108
|
end
|
@@ -337,6 +340,7 @@ module Gullah
|
|
337
340
|
root.descendants.select { |n| n.start >= self.end }
|
338
341
|
end
|
339
342
|
|
343
|
+
# @private
|
340
344
|
def clone # :nodoc:
|
341
345
|
super.tap do |c|
|
342
346
|
c._attributes = deep_clone(attributes)
|
@@ -416,13 +420,16 @@ module Gullah
|
|
416
420
|
## ADVISORILY PRIVATE
|
417
421
|
|
418
422
|
# :stopdoc:
|
423
|
+
# @!visibility private
|
419
424
|
|
425
|
+
# @private
|
420
426
|
def _summary=(str) # :nodoc:
|
421
427
|
@summary = str
|
422
428
|
end
|
423
429
|
|
424
430
|
# used during parsing
|
425
431
|
# make sure we don't have any repeated symbols in a unary branch
|
432
|
+
# @private
|
426
433
|
def _loop_check?(seen = nil) # :nodoc:
|
427
434
|
return true if seen == name
|
428
435
|
|
@@ -437,26 +444,32 @@ module Gullah
|
|
437
444
|
@leaf ? false : children.first._loop_check?(seen)
|
438
445
|
end
|
439
446
|
|
447
|
+
# @private
|
440
448
|
def _attributes=(attributes) # :nodoc:
|
441
449
|
@attributes = attributes
|
442
450
|
end
|
443
451
|
|
452
|
+
# @private
|
444
453
|
def _parent=(other) # :nodoc:
|
445
454
|
@parent = other
|
446
455
|
end
|
447
456
|
|
457
|
+
# @private
|
448
458
|
def _children=(children) # :nodoc:
|
449
459
|
@children = children
|
450
460
|
end
|
451
461
|
|
462
|
+
# @private
|
452
463
|
def _descendants(skip) # :nodoc:
|
453
464
|
Descendants.new(self, skip)
|
454
465
|
end
|
455
466
|
|
467
|
+
# @private
|
456
468
|
def _ancestors(skip) # :nodoc:
|
457
469
|
Ancestors.new(self, skip)
|
458
470
|
end
|
459
471
|
|
472
|
+
# @private
|
460
473
|
def _failed_test=(bool) # :nodoc:
|
461
474
|
@failed_test = bool
|
462
475
|
end
|
data/lib/gullah/parse.rb
CHANGED
@@ -81,14 +81,14 @@ module Gullah
|
|
81
81
|
# and the ancestor node where the test was run as erroneous,
|
82
82
|
# so they will increase the +incorrectness_count+ by 2.
|
83
83
|
def incorrectness_count
|
84
|
-
@incorrectness_count ||= roots.
|
84
|
+
@incorrectness_count ||= roots.count(&:failed?)
|
85
85
|
end
|
86
86
|
|
87
87
|
##
|
88
88
|
# The count of nodes which have some structure test which was never
|
89
89
|
# successfully run.
|
90
90
|
def pending_count
|
91
|
-
@pending_count ||= roots.
|
91
|
+
@pending_count ||= roots.count(&:pending_tests?)
|
92
92
|
end
|
93
93
|
|
94
94
|
##
|
@@ -122,7 +122,7 @@ module Gullah
|
|
122
122
|
#
|
123
123
|
# parses = Grammar.parse "this grammar uses the usual whitespace rule"
|
124
124
|
#
|
125
|
-
# parses.first.nodes.
|
125
|
+
# parses.first.nodes.count { |n| n.name == :_ws } # => 6
|
126
126
|
def nodes
|
127
127
|
NodeIterator.new self
|
128
128
|
end
|
data/lib/gullah/version.rb
CHANGED
data/test/basic_test.rb
CHANGED
@@ -43,7 +43,7 @@ class BasicTest < Minitest::Test
|
|
43
43
|
parses.each do |p|
|
44
44
|
assert_equal 1, p.roots.length, 'parse has a root node'
|
45
45
|
root = p.roots.first
|
46
|
-
assert_equal 2, root.subtree.
|
46
|
+
assert_equal 2, root.subtree.count(&:nonterminal?), 'parse has 2 nonterminal nodes'
|
47
47
|
assert root.subtree.select(&:nonterminal?).each do |_n|
|
48
48
|
assert_equal 2, b.children.length, 'nonterminal nodes each have 2 children'
|
49
49
|
end
|
@@ -96,10 +96,10 @@ class BasicTest < Minitest::Test
|
|
96
96
|
parse = parses.first
|
97
97
|
assert_equal 8, parse.roots.length, 'there are 8 nodes in the parse'
|
98
98
|
assert parse.roots.all?(&:leaf?), 'all nodes are leaf nodes'
|
99
|
-
assert_equal 3, parse.roots.
|
100
|
-
assert_equal 3, parse.roots.
|
101
|
-
assert_equal 4, parse.roots.
|
102
|
-
assert_equal 1, parse.roots.
|
99
|
+
assert_equal 3, parse.roots.count { |n| n.name == :ws }, 'there are 3 whitespace nodes'
|
100
|
+
assert_equal 3, parse.roots.count(&:ignorable?), 'there are 3 ignorable nodes'
|
101
|
+
assert_equal 4, parse.roots.count { |n| n.name == :word }, 'there are 4 word nodes'
|
102
|
+
assert_equal 1, parse.roots.count(&:trash?), 'there is 1 trash node'
|
103
103
|
last_node = parse.roots.last
|
104
104
|
assert last_node.trash?, 'the last node is the trash node'
|
105
105
|
end
|
@@ -156,9 +156,9 @@ class BasicTest < Minitest::Test
|
|
156
156
|
assert_equal 1, parse.roots.reject(&:ignorable?).count, 'there is a root node for this parse'
|
157
157
|
root = parse.roots.first
|
158
158
|
assert_equal :s, root.name, 'found expected root'
|
159
|
-
assert_equal 2, root.subtree.
|
160
|
-
assert_equal 1, root.subtree.
|
161
|
-
assert_equal 1, root.subtree.
|
159
|
+
assert_equal 2, root.subtree.count { |n| n.name == :thing }, 'two things'
|
160
|
+
assert_equal 1, root.subtree.count { |n| n.name == :word }, 'one word'
|
161
|
+
assert_equal 1, root.subtree.count { |n| n.name == :integer }, 'one integer'
|
162
162
|
end
|
163
163
|
|
164
164
|
class SubRulesWithTest
|
@@ -185,8 +185,8 @@ class BasicTest < Minitest::Test
|
|
185
185
|
things = root.subtree.select { |n| n.name == :thing }
|
186
186
|
assert_equal 2, things.count, 'two things'
|
187
187
|
assert things.all? { |n| n.attributes[:satisfied].include?(%i[foo etc]) }, 'passing tests stuff in extra bits'
|
188
|
-
assert_equal 1, root.subtree.
|
189
|
-
assert_equal 1, root.subtree.
|
188
|
+
assert_equal 1, root.subtree.count { |n| n.name == :word }, 'one word'
|
189
|
+
assert_equal 1, root.subtree.count { |n| n.name == :integer }, 'one integer'
|
190
190
|
end
|
191
191
|
|
192
192
|
class SubRulesWithAncestorTest
|
@@ -218,8 +218,8 @@ class BasicTest < Minitest::Test
|
|
218
218
|
assert thing.attributes[:satisfied_descendant].include?([:foo, root.position]),
|
219
219
|
'descendant is marked when ancestor test passes'
|
220
220
|
end
|
221
|
-
assert_equal 1, root.subtree.
|
222
|
-
assert_equal 1, root.subtree.
|
221
|
+
assert_equal 1, root.subtree.count { |n| n.name == :word }, 'one word'
|
222
|
+
assert_equal 1, root.subtree.count { |n| n.name == :integer }, 'one integer'
|
223
223
|
end
|
224
224
|
|
225
225
|
class LeftAncestor
|
data/test/parse_demo_test.rb
CHANGED
@@ -30,4 +30,39 @@ class ParseDemoTest < Minitest::Test
|
|
30
30
|
assert_equal 8, parse.size
|
31
31
|
assert_equal 'S[NP[D,_ws,N],_ws,VP[V]]', parse.summary
|
32
32
|
end
|
33
|
+
|
34
|
+
class Cat
|
35
|
+
extend Gullah
|
36
|
+
|
37
|
+
rule :S, 'NP VP'
|
38
|
+
rule :NP, 'D NB'
|
39
|
+
rule :NB, 'A* N'
|
40
|
+
rule :VP, 'VP PP'
|
41
|
+
rule :VP, 'V'
|
42
|
+
rule :PP, 'P NP'
|
43
|
+
rule :P, 'prepositions'
|
44
|
+
rule :V, 'verbs'
|
45
|
+
rule :D, 'determiners'
|
46
|
+
rule :N, 'nouns'
|
47
|
+
rule :A, 'adjectives'
|
48
|
+
|
49
|
+
leaf :determiners, /\b(the|an?)\b/i
|
50
|
+
leaf :nouns, /\b(cat|mat)\b/i
|
51
|
+
leaf :prepositions, /\b(on|in|around|above|beside)\b/i
|
52
|
+
leaf :verbs, /\b(sat|slept|moped)\b/
|
53
|
+
leaf :adjectives, /\b(big|small|hairy|bald|fat)\b/i
|
54
|
+
|
55
|
+
ignore :whatever, /[^\w\s]+/
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_cat
|
59
|
+
parses = Cat.parse 'The fat cat sat on the mat.'
|
60
|
+
assert_equal 1, parses.length, 'there is only one parse of this sentence'
|
61
|
+
parse = parses.first
|
62
|
+
assert_equal 1, parse.roots.reject(&:ignorable?).length, 'there is a root node for this parse'
|
63
|
+
root = parse.roots.reject(&:ignorable?).first
|
64
|
+
assert_equal :S, root.name, 'the root node is a sentence'
|
65
|
+
verb = root.descendants.find { |d| d.name == :VP }&.descendants&.find { |d| d.name == :V }
|
66
|
+
assert_equal 'sat', verb&.text, 'we have the expected verb'
|
67
|
+
end
|
33
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gullah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David F. Houghton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
142
|
- !ruby/object:Gem::Version
|
143
143
|
version: '0'
|
144
144
|
requirements: []
|
145
|
-
rubygems_version: 3.
|
145
|
+
rubygems_version: 3.4.15
|
146
146
|
signing_key:
|
147
147
|
specification_version: 4
|
148
148
|
summary: A bottom up parser generator
|