moory 0.3.2 → 0.3.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/Gemfile.lock +1 -1
- data/README.md +22 -10
- data/examples/readme_example.rb +38 -0
- data/lib/moory/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48186775b1c7f9b85822f58dadc0f2f355b1fc872e6ab7abcb1883da9b9d74e9
|
|
4
|
+
data.tar.gz: 4edd7b2f0a957aaeb6d016d25b9fc7f638f69dc20e2d925c9a11b0a13863a092
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5c5a11ad922e36aa09687535e52273661520b64b42c0867a6d0f5c9b9b120a2408e98737515f10be6dfeffc83ee55b55a3699c8dc007e2c7b59b1b9b09b8a06
|
|
7
|
+
data.tar.gz: 62c3df5b0cd326376f1434d2d6a8c3b3f3b7c1a3abdd05a0c9425f3f118bde51cccad786d48186d2155d7b32e900ef455858014fef72a9e581a8b367d19eae67
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -3,20 +3,20 @@ Welcome to the Moory gem!
|
|
|
3
3
|
|
|
4
4
|
You can use this gem to create various kinds of finite machines using a simple specification language.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
The [wiki](https://github.com/elclavijero/moory/wiki) is where to go if you are for looking for tutorial material. Perhaps also look in the examples directory. Therein you'll find use of the Acceptor, Decoder (Mealy machine), and something useless but (hopefully) illuminating.
|
|
7
|
+
|
|
8
|
+
Until you do, here is an example showing how you might use the Acceptor.
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
## Example: Creating an acceptor for ab*
|
|
9
12
|
|
|
10
13
|
### Motivation
|
|
11
14
|
|
|
12
|
-
Imagine that you want to create an incredible machine
|
|
13
|
-
you would not reach for a Regexp. That would be far too easy. Instead you derive from
|
|
14
|
-
the regular expression a Deterministic Finite Automaton (DFA) that does the job. Here's what it
|
|
15
|
-
might look like:
|
|
15
|
+
Imagine that you want to create an incredible machine. One capable of determining whether a given character string belongs to the language described by the regular expression `ab*`. You're not going to use a Regexp. That would be far too easy. Instead you derive from the regular expression a Deterministic Finite Automaton (DFA) that does the job. Here's what it might look like:
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|
|
19
|
-
Of course, you've set up and solved a system of equations verifying that the design is correct.
|
|
19
|
+
Of course, you've set up and solved a system of equations verifying that the design is correct. Now how do you implement this in Ruby? You won't bother trying to apply the State design pattern, because it is a pain. Instead, you'll employ Moory, which is one of the 200+ gems that exist to make creating finite machines easy.
|
|
20
20
|
|
|
21
21
|
### Implementing the Acceptor
|
|
22
22
|
|
|
@@ -45,7 +45,7 @@ ab_star = Moory::Acceptor.create(
|
|
|
45
45
|
)
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
I'll explain the syntax of the transitions later
|
|
48
|
+
I'll explain the syntax of the transitions later (see the [wiki](https://github.com/elclavijero/moory/wiki)) but you have done enough to confidently type:
|
|
49
49
|
|
|
50
50
|
```ruby
|
|
51
51
|
ab_star.accepts?(string: "ab")
|
|
@@ -61,7 +61,7 @@ ab_star.accepts?(string: "aab") # => false
|
|
|
61
61
|
ab_star.accepts?(string: "aba") # => false
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
You aren't stuck with testing the strings against the initial state. You can ask the machine to begin its match in any state:
|
|
65
65
|
|
|
66
66
|
```ruby
|
|
67
67
|
ab_star.accepts?(string: "bbb", in_state: '1')
|
|
@@ -74,11 +74,23 @@ But what about including characters that don't belong to the machine's alphabet?
|
|
|
74
74
|
ab_star.accepts?(string: "bbc", in_state: '1')
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
Well this one will be unceremoniously rejected with a runtime error (unless you are using version 0.1.0, where I forgot to handle bad input, sorry!)
|
|
77
|
+
Well this one will be unceremoniously rejected with a runtime error (unless you are using version 0.1.0, where I forgot to handle bad input, sorry!). Incidentally, if you want to change that behaviour, you should override the `default_proc`.
|
|
78
|
+
```ruby
|
|
79
|
+
ab_star.default_proc = proc { |msg| puts "I'm going to ignore that #{msg}" }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Now look
|
|
83
|
+
```ruby
|
|
84
|
+
ab_star.accepts?(string: "abcbb")
|
|
85
|
+
# I'm going to ignore that c
|
|
86
|
+
# => true
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
That's better.
|
|
78
90
|
|
|
79
91
|
### Before you go...
|
|
80
92
|
|
|
81
|
-
There's more to Moory than its Acceptor. I'll show you how to use its other features in
|
|
93
|
+
There's more to Moory than its Acceptor. I'll show you how to use its other features in the [wiki](https://github.com/elclavijero/moory/wiki).
|
|
82
94
|
|
|
83
95
|
|
|
84
96
|
## Installation
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'moory'
|
|
2
|
+
|
|
3
|
+
# Create an acceptor for the language described by ab*
|
|
4
|
+
ab_star = Moory::Acceptor.create(
|
|
5
|
+
initial: '0',
|
|
6
|
+
transitions: %q{
|
|
7
|
+
0 : a : 1
|
|
8
|
+
0 : b : 2
|
|
9
|
+
1 : a : 2
|
|
10
|
+
1 : b : 1
|
|
11
|
+
2 : a : 2
|
|
12
|
+
2 : b : 2
|
|
13
|
+
},
|
|
14
|
+
final: %w{ 1 }
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Check some strings
|
|
18
|
+
ab_star.accepts?(string: "ab") # => true
|
|
19
|
+
ab_star.accepts?(string: "abbb") # => true
|
|
20
|
+
ab_star.accepts?(string: "aab") # => false
|
|
21
|
+
ab_star.accepts?(string: "aba") # => false
|
|
22
|
+
|
|
23
|
+
# Check a string against another starting state
|
|
24
|
+
ab_star.accepts?(string: "bbb", in_state: '1')
|
|
25
|
+
# => true
|
|
26
|
+
|
|
27
|
+
# Uncomment the next line, and you'll see a runtime error
|
|
28
|
+
# ab_star.accepts?(string: "bbc", in_state: '1')
|
|
29
|
+
|
|
30
|
+
# Assign a default_proc, which is called when the Acceptor
|
|
31
|
+
# encounters a character not in its alphabet e.g. 'c'
|
|
32
|
+
ab_star.default_proc = proc { |msg| puts "I'm going to ignore that #{msg}" }
|
|
33
|
+
|
|
34
|
+
# Deliberately give the Acceptor a bad character.
|
|
35
|
+
ab_star.accepts?(string: "abcbb")
|
|
36
|
+
# I'm going to ignore that c
|
|
37
|
+
# => true
|
|
38
|
+
|
data/lib/moory/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam W. Grant
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-07-
|
|
11
|
+
date: 2018-07-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -70,6 +70,7 @@ files:
|
|
|
70
70
|
- bin/console
|
|
71
71
|
- bin/setup
|
|
72
72
|
- examples/ab_star.rb
|
|
73
|
+
- examples/readme_example.rb
|
|
73
74
|
- examples/silly.rb
|
|
74
75
|
- examples/single_as_and_bs.rb
|
|
75
76
|
- images/ab_star.png
|