sequitur 0.1.17 → 0.1.18
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/.rubocop.yml +82 -79
- data/.travis.yml +12 -9
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -4
- data/LICENSE.txt +1 -1
- data/README.md +20 -19
- data/appveyor.yml +20 -0
- data/lib/sequitur.rb +4 -4
- data/lib/sequitur/constants.rb +2 -2
- data/lib/sequitur/dynamic_grammar.rb +0 -2
- data/lib/sequitur/formatter/base_formatter.rb +5 -7
- data/lib/sequitur/formatter/base_text.rb +1 -3
- data/lib/sequitur/formatter/debug.rb +0 -2
- data/lib/sequitur/grammar_visitor.rb +0 -2
- data/lib/sequitur/production.rb +7 -9
- data/lib/sequitur/production_ref.rb +9 -9
- data/lib/sequitur/sequitur_grammar.rb +3 -3
- data/lib/sequitur/symbol_sequence.rb +8 -10
- data/spec/sequitur/digram_spec.rb +48 -48
- data/spec/sequitur/production_spec.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aab8594b29205b00f9ea39da791ea0fbae413934
|
4
|
+
data.tar.gz: 936518eec769379e776b2b034c52bd450872994d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95470830db25990b9988ec6c45766182d91537913c2a92ca037f47b62421a09f40ba9fb8b3b447287e163669befe77229853e918633c83f1a7ad444246365b61
|
7
|
+
data.tar.gz: bf018a2bd8a38e00eb352c0d6226bb37c4fc7228724c3e47e2954714a911b6af7dc98ae15218f17c9ae18637d1813edae4e92e756de79b26157e183d5a54696f
|
data/.rubocop.yml
CHANGED
@@ -1,79 +1,82 @@
|
|
1
|
-
AllCops:
|
2
|
-
Exclude:
|
3
|
-
- 'examples/**/*'
|
4
|
-
- 'features/**/*'
|
5
|
-
- 'gems/**/*'
|
6
|
-
- 'lab/**/*'
|
7
|
-
|
8
|
-
AbcSize:
|
9
|
-
Max: 20
|
10
|
-
|
11
|
-
# This is disabled because some demos use UTF-8
|
12
|
-
AsciiComments:
|
13
|
-
Enabled: false
|
14
|
-
|
15
|
-
Attr:
|
16
|
-
Enabled: false
|
17
|
-
|
18
|
-
CaseIndentation:
|
19
|
-
IndentWhenRelativeTo: end
|
20
|
-
IndentOneStep: true
|
21
|
-
|
22
|
-
# Rubocop enforces the use of is_a? instead of kind_of?
|
23
|
-
# Which is contrary to modelling practice.
|
24
|
-
ClassCheck:
|
25
|
-
Enabled: false
|
26
|
-
|
27
|
-
ClassLength:
|
28
|
-
Max: 250
|
29
|
-
CountComments: false
|
30
|
-
|
31
|
-
ConstantName:
|
32
|
-
Enabled: false
|
33
|
-
|
34
|
-
CyclomaticComplexity:
|
35
|
-
Enabled: false
|
36
|
-
|
37
|
-
DefWithParentheses:
|
38
|
-
Enabled: false
|
39
|
-
|
40
|
-
Documentation:
|
41
|
-
Enabled: false
|
42
|
-
|
43
|
-
EmptyLines:
|
44
|
-
Enabled: false
|
45
|
-
|
46
|
-
Encoding:
|
47
|
-
Enabled: false
|
48
|
-
|
49
|
-
IndentationWidth :
|
50
|
-
Enabled: false
|
51
|
-
|
52
|
-
|
53
|
-
# Avoid methods longer than 50 lines of code
|
54
|
-
MethodLength:
|
55
|
-
Max: 50
|
56
|
-
CountComments: false
|
57
|
-
|
58
|
-
# Avoid modules longer than 400 lines of code
|
59
|
-
ModuleLength:
|
60
|
-
Max: 400
|
61
|
-
|
62
|
-
NonNilCheck:
|
63
|
-
Enabled: false
|
64
|
-
|
65
|
-
NumericLiterals:
|
66
|
-
Enabled: false
|
67
|
-
|
68
|
-
RaiseArgs:
|
69
|
-
Enabled: false
|
70
|
-
|
71
|
-
RedundantReturn:
|
72
|
-
Enabled: false
|
73
|
-
|
74
|
-
SpaceInsideBrackets:
|
75
|
-
Enabled: false
|
76
|
-
|
77
|
-
TrailingWhitespace:
|
78
|
-
Enabled: false
|
79
|
-
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- 'examples/**/*'
|
4
|
+
- 'features/**/*'
|
5
|
+
- 'gems/**/*'
|
6
|
+
- 'lab/**/*'
|
7
|
+
|
8
|
+
AbcSize:
|
9
|
+
Max: 20
|
10
|
+
|
11
|
+
# This is disabled because some demos use UTF-8
|
12
|
+
AsciiComments:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Attr:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
CaseIndentation:
|
19
|
+
IndentWhenRelativeTo: end
|
20
|
+
IndentOneStep: true
|
21
|
+
|
22
|
+
# Rubocop enforces the use of is_a? instead of kind_of?
|
23
|
+
# Which is contrary to modelling practice.
|
24
|
+
ClassCheck:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
ClassLength:
|
28
|
+
Max: 250
|
29
|
+
CountComments: false
|
30
|
+
|
31
|
+
ConstantName:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
CyclomaticComplexity:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
DefWithParentheses:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Documentation:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
EmptyLines:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Encoding:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
IndentationWidth :
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
|
53
|
+
# Avoid methods longer than 50 lines of code
|
54
|
+
MethodLength:
|
55
|
+
Max: 50
|
56
|
+
CountComments: false
|
57
|
+
|
58
|
+
# Avoid modules longer than 400 lines of code
|
59
|
+
ModuleLength:
|
60
|
+
Max: 400
|
61
|
+
|
62
|
+
NonNilCheck:
|
63
|
+
Enabled: false
|
64
|
+
|
65
|
+
NumericLiterals:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
RaiseArgs:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
RedundantReturn:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
SpaceInsideBrackets:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
TrailingWhitespace:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
VariableName:
|
81
|
+
Enabled: false
|
82
|
+
|
data/.travis.yml
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
- 2.
|
6
|
-
- 2.2.
|
7
|
-
-
|
8
|
-
-
|
3
|
+
- ruby-head
|
4
|
+
- jruby-head
|
5
|
+
- 2.3.3
|
6
|
+
- 2.2.6
|
7
|
+
- 2.1.9
|
8
|
+
- 2.0.0
|
9
|
+
- jruby
|
9
10
|
|
10
|
-
gemfile:
|
11
|
-
- Gemfile
|
12
|
-
|
13
11
|
matrix:
|
14
12
|
allow_failures:
|
13
|
+
- rvm: jruby
|
14
|
+
- rvm: ruby-head
|
15
15
|
- rvm: jruby-head
|
16
|
+
|
17
|
+
gemfile:
|
18
|
+
- Gemfile
|
16
19
|
|
17
20
|
# whitelist
|
18
21
|
branches:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
### 0.1.18 / 2016-12-21
|
2
|
+
* [NEW] Added AppVeyor CI to Github commits. AppVeyor allows to build and test commits on Windows servers.
|
3
|
+
This is complementary to Travis CI which does Linux builds.
|
4
|
+
* [NEW] File `appveyor.yml` Contains the AppVeyor configuration.
|
5
|
+
* [CHANGE] File `README.md` Added AppVeyor badge.
|
6
|
+
* [CHANGE] File `.travis.yml`: updated Ruby versions to test for. Added MRI 2.3.x, dropped MRI 1.9.3
|
7
|
+
* [CHANGE] File 'sequitur.gemspec' Lowest supported Ruby version is now 2.0.0.
|
8
|
+
* [CHANGE] Many files. Code re-styling in order to please Rubocop 0.46.0
|
9
|
+
|
10
|
+
|
1
11
|
### 0.1.17 / 2015-09-05
|
2
12
|
* [CHANGE] File `.travis.yml`: Added versions MRI 2.2.0, JRuby 9.0.1.0
|
3
13
|
|
data/Gemfile
CHANGED
@@ -3,9 +3,8 @@ source 'https://rubygems.org'
|
|
3
3
|
|
4
4
|
|
5
5
|
group :development do
|
6
|
-
gem 'rake', '>= 10.0.0'
|
7
|
-
gem 'rspec', '>= 2.1.0'
|
8
|
-
gem 'simplecov', '>= 0.8.0'
|
9
6
|
gem 'coveralls', '>= 0.7.0'
|
7
|
+
gem 'rake', '>= 10.0.0'
|
8
|
+
gem 'rspec', '>= 2.1.0'
|
9
|
+
gem 'simplecov', '>= 0.8.0'
|
10
10
|
end
|
11
|
-
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,8 @@ Sequitur
|
|
3
3
|
_Ruby gem implementing the Sequitur algorithm_
|
4
4
|
[Homepage](https://github.com/famished-tiger/Sequitur)
|
5
5
|
|
6
|
-
[](https://travis-ci.org/famished-tiger/Sequitur)
|
6
|
+
[](https://travis-ci.org/famished-tiger/Sequitur)
|
7
|
+
[](https://ci.appveyor.com/project/famished-tiger/sequitur)
|
7
8
|
[](https://coveralls.io/r/famished-tiger/Sequitur)
|
8
9
|
[](http://badge.fury.io/rb/sequitur)
|
9
10
|
[](https://gemnasium.com/famished-tiger/Sequitur)
|
@@ -24,8 +25,8 @@ The following are good entry points to learn about the algorithm:
|
|
24
25
|
* Algorithm works with different input token types (no limited to single character)
|
25
26
|
|
26
27
|
### The theory in a nutshell ###
|
27
|
-
Given a sequence of input tokens (say, characters), the Sequitur algorithm
|
28
|
-
will represent that input sequence as a set of rules. As the algorithm detects
|
28
|
+
Given a sequence of input tokens (say, characters), the Sequitur algorithm
|
29
|
+
will represent that input sequence as a set of rules. As the algorithm detects
|
29
30
|
automatically repeated token patterns, the resulting rule set can encode repetitions in the input
|
30
31
|
in a very compact way.
|
31
32
|
Of interest is the fact that the algorithm runs in time linear in the length of the input sequence.
|
@@ -46,7 +47,7 @@ is three time the pattern encoded by the rule called P1.
|
|
46
47
|
-The second rule (named P1) represents the sequence a b c.
|
47
48
|
|
48
49
|
**Can you give another example?**
|
49
|
-
Yep. Assume this time that the input is *'ababcabcdabcde'*.
|
50
|
+
Yep. Assume this time that the input is *'ababcabcdabcde'*.
|
50
51
|
Then Sequitur algorithm will generate the rule set:
|
51
52
|
```
|
52
53
|
start : P1 P2 P3 P3 e.
|
@@ -73,7 +74,7 @@ repeated elements)
|
|
73
74
|
|
74
75
|
**Time for a quick demo**
|
75
76
|
|
76
|
-
The following Ruby snippet show how to apply Sequitur on the input string from the last example above.
|
77
|
+
The following Ruby snippet show how to apply Sequitur on the input string from the last example above.
|
77
78
|
|
78
79
|
```ruby
|
79
80
|
|
@@ -91,7 +92,7 @@ can you make good use of the algorithm's result.
|
|
91
92
|
**Printing the resulting rules**
|
92
93
|
The very first natural step is to be able to print out the (grammar) rules.
|
93
94
|
Here's how:
|
94
|
-
|
95
|
+
|
95
96
|
|
96
97
|
```ruby
|
97
98
|
require 'sequitur'
|
@@ -104,9 +105,9 @@ Here's how:
|
|
104
105
|
|
105
106
|
# Now render the rules. Each rule is displayed with the format:
|
106
107
|
# rule_id : a_sequence_grammar_symbols.
|
107
|
-
# Where:
|
108
|
+
# Where:
|
108
109
|
# - rule_id is either 'start' or a name like 'Pxxxx' (xxxx is a sequential number)
|
109
|
-
# - a grammar symbol is either a terminal symbol
|
110
|
+
# - a grammar symbol is either a terminal symbol
|
110
111
|
# (i.e. a character from the input) or a rule id
|
111
112
|
formatter.render(grammar.visitor)
|
112
113
|
|
@@ -121,7 +122,7 @@ Here's how:
|
|
121
122
|
The Sequitur algorithm generates a -simplified- context-free grammar, therefore we dedicate this section
|
122
123
|
to the terminology about context-free grammars. As the Internet provides tons of information can be found
|
123
124
|
on the subject, we limit ourselves to the minimal terminology of interest when using the sequitur gem.
|
124
|
-
|
125
|
+
|
125
126
|
First of all, what is a **grammar**? To simplify the matter, one can see a grammar as a set of
|
126
127
|
grammar rules. These rules are called production rules or more briefly **productions**.
|
127
128
|
|
@@ -133,12 +134,12 @@ P : body.
|
|
133
134
|
Where:
|
134
135
|
- The colon ':' character separates the head (= left-hand side) and the body (right-hand side, *rhs* in short)
|
135
136
|
of the rule.
|
136
|
-
- The left-hand side consists just of one symbol, P. P is a categorized as a *nonterminal symbol* and for our purposes
|
137
|
-
a nonterminal symbol can be seen as the "name" of the production. By contrast, a terminal symbol is just one element
|
138
|
-
from the input sequence (symbols as defined in formal grammar theory shouldn't be confused with Ruby's `Symbol` class).
|
139
|
-
- the body is a sequence -possibly empty- of *symbols* (terminal or nonterminal).
|
137
|
+
- The left-hand side consists just of one symbol, P. P is a categorized as a *nonterminal symbol* and for our purposes
|
138
|
+
a nonterminal symbol can be seen as the "name" of the production. By contrast, a terminal symbol is just one element
|
139
|
+
from the input sequence (symbols as defined in formal grammar theory shouldn't be confused with Ruby's `Symbol` class).
|
140
|
+
- the body is a sequence -possibly empty- of *symbols* (terminal or nonterminal).
|
140
141
|
|
141
|
-
Basically, a production rule tells that P is equivalent to the sequence of symbols found in the
|
142
|
+
Basically, a production rule tells that P is equivalent to the sequence of symbols found in the
|
142
143
|
right-hand side of the production. A nonterminal symbol that appears in the rhs of a production can be
|
143
144
|
seen as a reference to the production with same name.
|
144
145
|
|
@@ -166,7 +167,7 @@ that returns the productions of the grammar as an array of `Sequitur::Production
|
|
166
167
|
|
167
168
|
# Retrieve all productions of the grammar
|
168
169
|
all_prods = grammar.productions
|
169
|
-
|
170
|
+
|
170
171
|
# Retrieve the start production
|
171
172
|
start_prod = grammar.production[0]
|
172
173
|
```
|
@@ -193,7 +194,7 @@ A ProductionRef is reference to a Production object. The latter one can be acces
|
|
193
194
|
### Installation ###
|
194
195
|
The sequitur gem installation is fairly standard.
|
195
196
|
If your project has a `Gemfile` file, add `sequitur` to it. Otherwise, install the gem like this:
|
196
|
-
|
197
|
+
|
197
198
|
```bash
|
198
199
|
$[sudo] gem install sequitur
|
199
200
|
```
|
@@ -201,11 +202,11 @@ $[sudo] gem install sequitur
|
|
201
202
|
|
202
203
|
|
203
204
|
### Good to know ###
|
204
|
-
The above examples might give the impression that the input stream must consist of single
|
205
|
+
The above examples might give the impression that the input stream must consist of single
|
205
206
|
character tokens. This is simply not true.
|
206
207
|
This implementation is flexible enough to cope with other kinds of input values.
|
207
208
|
The next example shows how integer values can be correctly processed by Sequitur.
|
208
|
-
Assume that the input is the array of Fixnums *[1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]*.
|
209
|
+
Assume that the input is the array of Fixnums *[1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5]*.
|
209
210
|
|
210
211
|
```ruby
|
211
212
|
require 'sequitur' # Load the Sequitur library
|
@@ -247,4 +248,4 @@ More examples are available in the examples folder.
|
|
247
248
|
|
248
249
|
Copyright
|
249
250
|
---------
|
250
|
-
Copyright (c) 2014, Dimitri Geshef. Sequitur is released under the MIT License see [LICENSE.txt](https://github.com/famished-tiger/Sequitur/blob/master/LICENSE.txt) for details.
|
251
|
+
Copyright (c) 2014-2017, Dimitri Geshef. Sequitur is released under the MIT License see [LICENSE.txt](https://github.com/famished-tiger/Sequitur/blob/master/LICENSE.txt) for details.
|
data/appveyor.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
version: '{build}'
|
2
|
+
max_jobs: 3
|
3
|
+
environment:
|
4
|
+
matrix:
|
5
|
+
- Ruby_version: 200
|
6
|
+
- Ruby_version: 200-x64
|
7
|
+
- Ruby_version: 21
|
8
|
+
- Ruby_version: 21-x64
|
9
|
+
- Ruby_version: 22
|
10
|
+
- Ruby_version: 22-x64
|
11
|
+
- Ruby_version: 23
|
12
|
+
- Ruby_version: 23-x64
|
13
|
+
install:
|
14
|
+
- cmd: >-
|
15
|
+
SET PATH=C:\Ruby%Ruby_version%\bin;%PATH%
|
16
|
+
|
17
|
+
bundle install --retry=3 --clean
|
18
|
+
build: off
|
19
|
+
test_script:
|
20
|
+
- cmd: bundle exec rake
|
data/lib/sequitur.rb
CHANGED
@@ -17,10 +17,10 @@ module Sequitur
|
|
17
17
|
# @return [SequiturGrammar] a grammar that encodes the input.
|
18
18
|
def self.build_from(tokens)
|
19
19
|
input_sequence = case tokens
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
when String then tokens.chars
|
21
|
+
when Enumerator then tokens
|
22
|
+
else tokens.to_enum
|
23
|
+
end
|
24
24
|
|
25
25
|
return SequiturGrammar.new(input_sequence)
|
26
26
|
end
|
data/lib/sequitur/constants.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
|
4
4
|
module Sequitur # Module used as a namespace
|
5
5
|
# The version number of the gem.
|
6
|
-
Version = '0.1.
|
6
|
+
Version = '0.1.18'.freeze
|
7
7
|
|
8
8
|
# Brief description of the gem.
|
9
|
-
Description = 'Ruby implementation of the Sequitur algorithm'
|
9
|
+
Description = 'Ruby implementation of the Sequitur algorithm'.freeze
|
10
10
|
|
11
11
|
# Constant Sequitur::RootDir contains the absolute path of Sequitur's
|
12
12
|
# start directory. Note: it also ends with a slash character.
|
@@ -13,17 +13,15 @@ module Sequitur
|
|
13
13
|
@output = anIO
|
14
14
|
end
|
15
15
|
|
16
|
-
public
|
17
|
-
|
18
16
|
# Given a grammar or a grammar visitor, perform the visit
|
19
17
|
# and render the visit events in the output stream.
|
20
18
|
# @param aGrmOrVisitor [DynamicGrammar or GrammarVisitor]
|
21
19
|
def render(aGrmOrVisitor)
|
22
|
-
if aGrmOrVisitor.kind_of?(GrammarVisitor)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
a_visitor = if aGrmOrVisitor.kind_of?(GrammarVisitor)
|
21
|
+
aGrmOrVisitor
|
22
|
+
else
|
23
|
+
aGrmOrVisitor.visitor
|
24
|
+
end
|
27
25
|
|
28
26
|
a_visitor.subscribe(self)
|
29
27
|
a_visitor.start
|
@@ -18,8 +18,6 @@ module Sequitur
|
|
18
18
|
@prod_lookup = {}
|
19
19
|
end
|
20
20
|
|
21
|
-
public
|
22
|
-
|
23
21
|
# Method called by a GrammarVisitor to which the formatter subscribed.
|
24
22
|
# Notification of a visit event: the visitor is about to visit a grammar
|
25
23
|
# @param aGrammar [DynamicGrammar-like object]
|
@@ -82,7 +80,7 @@ module Sequitur
|
|
82
80
|
# @param aProduction [Production]
|
83
81
|
def prod_name(aProduction)
|
84
82
|
prod_index = prod_lookup[aProduction]
|
85
|
-
name =
|
83
|
+
name = prod_index.zero? ? 'start' : "P#{prod_index}"
|
86
84
|
return name
|
87
85
|
end
|
88
86
|
end # class
|
data/lib/sequitur/production.rb
CHANGED
@@ -29,19 +29,17 @@ class Production
|
|
29
29
|
@digrams = []
|
30
30
|
end
|
31
31
|
|
32
|
-
public
|
33
|
-
|
34
32
|
# Identity testing.
|
35
33
|
# @param other [] another production or production reference.
|
36
34
|
# @return true when the receiver and other are the same.
|
37
35
|
def ==(other)
|
38
36
|
return true if object_id == other.object_id
|
39
37
|
|
40
|
-
if other.is_a?(ProductionRef)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
result = if other.is_a?(ProductionRef)
|
39
|
+
(other == self)
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
45
43
|
|
46
44
|
return result
|
47
45
|
end
|
@@ -60,7 +58,7 @@ class Production
|
|
60
58
|
|
61
59
|
# Decrement the reference count by one.
|
62
60
|
def decr_refcount()
|
63
|
-
|
61
|
+
raise StandardError, 'Internal error' if @refcount.zero?
|
64
62
|
@refcount -= 1
|
65
63
|
end
|
66
64
|
|
@@ -139,7 +137,7 @@ class Production
|
|
139
137
|
if aSymbol.unbound?
|
140
138
|
msg = 'Fail to append reference to nil production in '
|
141
139
|
msg << to_string
|
142
|
-
|
140
|
+
raise StandardError, msg
|
143
141
|
end
|
144
142
|
new_symb = aSymbol.dup
|
145
143
|
else
|
@@ -42,10 +42,10 @@ class ProductionRef
|
|
42
42
|
# Emit the text representation of a production reference.
|
43
43
|
# @return [String]
|
44
44
|
def to_s()
|
45
|
-
return
|
45
|
+
return production.object_id.to_s
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
alias to_string to_s
|
49
49
|
|
50
50
|
|
51
51
|
# Equality testing.
|
@@ -57,11 +57,11 @@ class ProductionRef
|
|
57
57
|
def ==(other)
|
58
58
|
return true if object_id == other.object_id
|
59
59
|
|
60
|
-
if other.is_a?(ProductionRef)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
result = if other.is_a?(ProductionRef)
|
61
|
+
(production == other.production)
|
62
|
+
else
|
63
|
+
(production == other)
|
64
|
+
end
|
65
65
|
|
66
66
|
return result
|
67
67
|
end
|
@@ -72,7 +72,7 @@ class ProductionRef
|
|
72
72
|
# referenced production
|
73
73
|
# @return [Fixnum] the hash value
|
74
74
|
def hash()
|
75
|
-
|
75
|
+
raise StandardError, 'Nil production' if production.nil?
|
76
76
|
return production.hash
|
77
77
|
end
|
78
78
|
|
@@ -84,7 +84,7 @@ class ProductionRef
|
|
84
84
|
|
85
85
|
production.decr_refcount if production
|
86
86
|
unless aProduction.kind_of?(Production)
|
87
|
-
|
87
|
+
raise StandardError, "Illegal production type #{aProduction.class}"
|
88
88
|
end
|
89
89
|
@production = aProduction
|
90
90
|
production.incr_refcount
|
@@ -71,8 +71,8 @@ class SequiturGrammar < DynamicGrammar
|
|
71
71
|
if found_so_far.include? its_key
|
72
72
|
orig_digr = found_so_far[its_key]
|
73
73
|
# Disregard sequence like a a a
|
74
|
-
if (
|
75
|
-
|
74
|
+
if (orig_digr.production == a_prod) && a_digr.repeating? &&
|
75
|
+
(orig_digr == a_digr)
|
76
76
|
next
|
77
77
|
end
|
78
78
|
|
@@ -111,7 +111,7 @@ class SequiturGrammar < DynamicGrammar
|
|
111
111
|
# Return a production that is used less than twice in the grammar.
|
112
112
|
def detect_useless_production()
|
113
113
|
useless = productions.index { |prod| prod.refcount < 2 }
|
114
|
-
useless = nil if useless && useless
|
114
|
+
useless = nil if useless && useless.zero?
|
115
115
|
|
116
116
|
return useless
|
117
117
|
end
|
@@ -20,8 +20,6 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
20
20
|
invalidate_refs
|
21
21
|
end
|
22
22
|
|
23
|
-
public
|
24
|
-
|
25
23
|
# Clear the symbol sequence.
|
26
24
|
def clear()
|
27
25
|
refs = references
|
@@ -66,14 +64,14 @@ module Sequitur # Module for classes implementing the Sequitur algorithm
|
|
66
64
|
def ==(other)
|
67
65
|
return true if object_id == other.object_id
|
68
66
|
|
69
|
-
case other
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
67
|
+
same = case other
|
68
|
+
when SymbolSequence
|
69
|
+
symbols == other.symbols
|
70
|
+
when Array
|
71
|
+
symbols == other
|
72
|
+
else
|
73
|
+
false
|
74
|
+
end
|
77
75
|
|
78
76
|
return same
|
79
77
|
end
|
@@ -1,48 +1,48 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
# Load the class under test
|
4
|
-
require_relative '../../lib/sequitur/digram'
|
5
|
-
|
6
|
-
module Sequitur # Re-open the module to get rid of qualified names
|
7
|
-
describe Digram do
|
8
|
-
let(:two_symbols) { [:b, :c] }
|
9
|
-
let(:production) { double('sample-production') }
|
10
|
-
|
11
|
-
context 'Standard creation & initialization:' do
|
12
|
-
it 'should be created with 3 arguments' do
|
13
|
-
instance = Digram.new(:b, :c, production)
|
14
|
-
|
15
|
-
expect(instance.symbols).to eq(two_symbols)
|
16
|
-
expect(instance.production).to eq(production)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should return the production that it refers to' do
|
20
|
-
instance = Digram.new(:b, :c, production)
|
21
|
-
expect(instance.production).to eq(production)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should whether its symbols are the same' do
|
25
|
-
instance1 = Digram.new(:a, :a, production)
|
26
|
-
expect(instance1).to be_repeating
|
27
|
-
|
28
|
-
instance1 = Digram.new(:a, :b, production)
|
29
|
-
expect(instance1).not_to be_repeating
|
30
|
-
end
|
31
|
-
end # context
|
32
|
-
|
33
|
-
context 'Provided services:' do
|
34
|
-
it 'should compare itself to another digram' do
|
35
|
-
instance1 = Digram.new(:a, :b, production)
|
36
|
-
same = Digram.new(:a, :b, production)
|
37
|
-
different = Digram.new(:b, :c, production)
|
38
|
-
|
39
|
-
expect(instance1).to eq(instance1)
|
40
|
-
expect(instance1).to eq(same)
|
41
|
-
expect(instance1).not_to eq(different)
|
42
|
-
expect(same).not_to eq(different)
|
43
|
-
end
|
44
|
-
end # context
|
45
|
-
end # describe
|
46
|
-
end # module
|
47
|
-
|
48
|
-
# End of file
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
# Load the class under test
|
4
|
+
require_relative '../../lib/sequitur/digram'
|
5
|
+
|
6
|
+
module Sequitur # Re-open the module to get rid of qualified names
|
7
|
+
describe Digram do
|
8
|
+
let(:two_symbols) { [:b, :c] }
|
9
|
+
let(:production) { double('sample-production') }
|
10
|
+
|
11
|
+
context 'Standard creation & initialization:' do
|
12
|
+
it 'should be created with 3 arguments' do
|
13
|
+
instance = Digram.new(:b, :c, production)
|
14
|
+
|
15
|
+
expect(instance.symbols).to eq(two_symbols)
|
16
|
+
expect(instance.production).to eq(production)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return the production that it refers to' do
|
20
|
+
instance = Digram.new(:b, :c, production)
|
21
|
+
expect(instance.production).to eq(production)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should whether its symbols are the same' do
|
25
|
+
instance1 = Digram.new(:a, :a, production)
|
26
|
+
expect(instance1).to be_repeating
|
27
|
+
|
28
|
+
instance1 = Digram.new(:a, :b, production)
|
29
|
+
expect(instance1).not_to be_repeating
|
30
|
+
end
|
31
|
+
end # context
|
32
|
+
|
33
|
+
context 'Provided services:' do
|
34
|
+
it 'should compare itself to another digram' do
|
35
|
+
instance1 = Digram.new(:a, :b, production)
|
36
|
+
same = Digram.new(:a, :b, production)
|
37
|
+
different = Digram.new(:b, :c, production)
|
38
|
+
|
39
|
+
expect(instance1).to eq(instance1)
|
40
|
+
expect(instance1).to eq(same)
|
41
|
+
expect(instance1).not_to eq(different)
|
42
|
+
expect(same).not_to eq(different)
|
43
|
+
end
|
44
|
+
end # context
|
45
|
+
end # describe
|
46
|
+
end # module
|
47
|
+
|
48
|
+
# End of file
|
@@ -202,7 +202,7 @@ describe Production do
|
|
202
202
|
|
203
203
|
it 'should detect any repetition pattern' do
|
204
204
|
# Positive cases
|
205
|
-
cases = %w(abab abcdab abcdcd abcdefcd
|
205
|
+
cases = %w(abab abcdab abcdcd abcdefcd)
|
206
206
|
cases.each do |word|
|
207
207
|
instance = Production.new
|
208
208
|
word.each_char { |symb| instance.append_symbol(symb) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequitur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- LICENSE.txt
|
122
122
|
- README.md
|
123
123
|
- Rakefile
|
124
|
+
- appveyor.yml
|
124
125
|
- examples/integer_sample.rb
|
125
126
|
- examples/porridge.rb
|
126
127
|
- examples/simple_case.rb
|
@@ -164,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
165
|
requirements:
|
165
166
|
- - ">="
|
166
167
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
168
|
+
version: 2.0.0
|
168
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
170
|
requirements:
|
170
171
|
- - ">="
|
@@ -172,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
173
|
version: '0'
|
173
174
|
requirements: []
|
174
175
|
rubyforge_project:
|
175
|
-
rubygems_version: 2.
|
176
|
+
rubygems_version: 2.6.7
|
176
177
|
signing_key:
|
177
178
|
specification_version: 4
|
178
179
|
summary: Ruby implementation of the Sequitur algorithm
|