sequitur 0.1.17 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/famished-tiger/Sequitur.svg?branch=master)](https://travis-ci.org/famished-tiger/Sequitur)
|
6
|
+
[![Linux Build Status](https://travis-ci.org/famished-tiger/Sequitur.svg?branch=master)](https://travis-ci.org/famished-tiger/Sequitur)
|
7
|
+
[![Windows Build status](https://ci.appveyor.com/api/projects/status/nvi1be8mb0494dqw?svg=true)](https://ci.appveyor.com/project/famished-tiger/sequitur)
|
7
8
|
[![Coverage Status](https://coveralls.io/repos/famished-tiger/Sequitur/badge.png?branch=master)](https://coveralls.io/r/famished-tiger/Sequitur)
|
8
9
|
[![Gem Version](https://badge.fury.io/rb/sequitur.svg)](http://badge.fury.io/rb/sequitur)
|
9
10
|
[![Dependency Status](https://gemnasium.com/famished-tiger/Sequitur.png)](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
|