farseer 0.5.0 → 0.7.0
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/CHANGELOG.md +103 -0
- data/SECURITY.md +14 -0
- data/lib/farseer/and.rb +37 -0
- data/lib/farseer/any.rb +20 -0
- data/lib/farseer/chars.rb +8 -6
- data/lib/farseer/many.rb +21 -0
- data/lib/farseer/opt.rb +16 -0
- data/lib/farseer/or.rb +24 -0
- data/lib/farseer/regexp.rb +23 -0
- data/lib/farseer/result.rb +2 -2
- data/lib/farseer/version.rb +1 -1
- data/lib/farseer/word.rb +17 -0
- data/lib/farseer.rb +0 -19
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22cbc0c49fc2a306b2e0e7291dd58e09047bd2eef4b679d2be9f9e307c6db2e1
|
4
|
+
data.tar.gz: a3a1a49b2748d129931af363e3a4bcbb9fdbd174956de07a4de0daceb0cc07cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b3bc436e67fcd46f61964cb6e3e70c7f3a8c374a1712680f4a91901daaf9ae071c79428ac40da19038619e8a05556cbbfd0167d43b5841020b082d730f909a6
|
7
|
+
data.tar.gz: 2303e7849b72c10e9353ff9faf362c3d8e0113f24247dbd95104ea45d2c5877e96bcf2444d402853909f14590f4a3c8295f813f99ebc23e1c4bbccbb33c11ae8
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [0.7.0] - 2024-06-04
|
11
|
+
### Added
|
12
|
+
- `Farseer::And` to run a sequence of parsers that must all succeed.
|
13
|
+
- `Farseer::Or` to try multiple parsers until one works.
|
14
|
+
- `Farseer::Word` to parse a keyword at the beginning of a string.
|
15
|
+
- `Farseer::Regexp` to parse a token using `regexp`.
|
16
|
+
- `mutant` development dependency for mutation testing.
|
17
|
+
- Achieve `100%` mutation test coverage.
|
18
|
+
- `byebug` development dependency for debugging.
|
19
|
+
|
20
|
+
### Removed
|
21
|
+
- All helper methods of `Farseer`.
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Update development dependencies.
|
25
|
+
|
26
|
+
## [0.6.0] - 2024-06-03
|
27
|
+
### Added
|
28
|
+
- `Farseer::Opt` to parse `0` to `1` times the wrapped parser. (`?`)
|
29
|
+
- `Farseer::Any` to parse `0` to multiple times the wrapped parser. (`*`)
|
30
|
+
- `Farseer::Many` to parse `1` to multiple times the wrapped parser. (`+`)
|
31
|
+
- A couple of instances of `Farseer::Chars` as constants:
|
32
|
+
- `Farseer::Chars::DIGITS` to parse digits from `0` to `9`.
|
33
|
+
- `Farseer::Chars::BASIC_MATH_OP` to parse symbols `+`, `-`, `*`, `/`.
|
34
|
+
- Enabled more `Lint` `rubocop` rules.
|
35
|
+
- Enabled `Performance` `rubocop` rules.
|
36
|
+
|
37
|
+
### Changed
|
38
|
+
- Updated development dependencies
|
39
|
+
|
40
|
+
## [0.5.0] - 2024-06-03
|
41
|
+
### Added
|
42
|
+
- `Farseer::Char` as a single character parser.
|
43
|
+
- `Farseer::Chars` as a single character from set parser.
|
44
|
+
- Multiple instances of `Farseer::Char` as constants:
|
45
|
+
- `Farseer::Char::L_PARENS` for `(`.
|
46
|
+
- `Farseer::Char::R_PARENS` for `)`.
|
47
|
+
- `Farseer::Char::PLUS` for `+`.
|
48
|
+
- `Farseer::Char::MINUS` for `-`.
|
49
|
+
- `Farseer::Char::STAR` for `*`.
|
50
|
+
- `Farseer::Char::SLASH` for `/`.
|
51
|
+
- Enabled `Lint` `rubocop` rules.
|
52
|
+
- Enabled a couple more `Layout` `rubocop` rules.
|
53
|
+
|
54
|
+
### Changed
|
55
|
+
- Update `muina` version requirement to `~> 0.5`
|
56
|
+
|
57
|
+
## [0.4.0] - 2024-06-03
|
58
|
+
### Added
|
59
|
+
- `Farseer.any_char_parser` to parse a single character from a given set.
|
60
|
+
- `irb` development dependency.
|
61
|
+
- `.gitignore.local` symlink to `.git/info/exclude`.
|
62
|
+
|
63
|
+
### Changed
|
64
|
+
- Stop using `module_function` and change methods into singleton methods.
|
65
|
+
- Update `bundler` version.
|
66
|
+
|
67
|
+
## [0.3.0] - 2024-06-02
|
68
|
+
### Added
|
69
|
+
- `Farseer#ws_parser` to parse all leading whitespace.
|
70
|
+
- Multiple development dependencies:
|
71
|
+
- `flay`, `flog`, `guard`, `guard-rspec`, `guard-rubocop`, `lefthook`, and
|
72
|
+
`rubocop-performance` with corresponding `binstubs`.
|
73
|
+
- `Guardfile` with `rspec` and `rubocop` guards.
|
74
|
+
- `.lefthook.yml` including `pre-commit` and `pre-push` hooks, and `audit` and
|
75
|
+
`full_audit` tasks.
|
76
|
+
|
77
|
+
### Changed
|
78
|
+
- Bump `muina` required version to `~> 0.4`.
|
79
|
+
- Enabled `Lint` `rubocop` department.
|
80
|
+
|
81
|
+
|
82
|
+
## [0.2.0] - 2024-06-02
|
83
|
+
### Added
|
84
|
+
- `Farseer::Result` to hold the result of succesful parses.
|
85
|
+
- `Farseer#char_parser` to parse a single specific character.
|
86
|
+
- `muina` as a dependency.
|
87
|
+
- `bin/console` to jump into `irb` with the project loaded.
|
88
|
+
|
89
|
+
|
90
|
+
## [0.1.0] - 2024-06-02
|
91
|
+
### Added
|
92
|
+
- Initial gem relase.
|
93
|
+
- Set up code quality dependencies:
|
94
|
+
- `rake`: for running common tasks.
|
95
|
+
- `rubocop`: for linting.
|
96
|
+
- `rspec`: for testing.
|
97
|
+
- `simplecov`: for code coverage.
|
98
|
+
- License the project with `The Unlicense`.
|
99
|
+
- `Rakefile` with `gem`, `rubocop`, and `rspec` tasks.
|
100
|
+
- `SECURITY.md` to keep track of maintained versions.
|
101
|
+
- `Farseer::VERSION`: Keep the gem version in a constant.
|
102
|
+
- `.ruby-version` for rbenv, with version `3.2.2`
|
103
|
+
- This `CHANGELOG.md`
|
data/SECURITY.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported Versions
|
4
|
+
|
5
|
+
Currently supported version are:
|
6
|
+
|
7
|
+
| Version | Supported |
|
8
|
+
| ------- | ------------------ |
|
9
|
+
| 0.6.0 | :white_check_mark: |
|
10
|
+
| < 0.6.0 | :x: |
|
11
|
+
|
12
|
+
## Reporting a Vulnerability
|
13
|
+
|
14
|
+
If you find any vulnerability please open an issue.
|
data/lib/farseer/and.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class And
|
5
|
+
def initialize(*parsers)
|
6
|
+
@parsers = parsers.flatten
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(input)
|
11
|
+
return Maybe.none if @parsers.empty?
|
12
|
+
|
13
|
+
initial = Maybe.return(Result.new('', input))
|
14
|
+
|
15
|
+
@parsers.reduce(initial) do |maybe_acc, parser|
|
16
|
+
bind_accumulator(maybe_acc, parser)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def bind_accumulator(maybe_acc, parser)
|
21
|
+
maybe_acc.bind do |acc_result|
|
22
|
+
parse_with_rest(parser, acc_result)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_with_rest(parser, acc_result)
|
27
|
+
parser.parse(acc_result.rest).bind do |result|
|
28
|
+
combine_results(acc_result, result)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def combine_results(acc_result, result)
|
33
|
+
combined_tokens = acc_result.token + result.token
|
34
|
+
Maybe.return(Result.new(combined_tokens, result.rest))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/farseer/any.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class Any
|
5
|
+
def initialize(parser)
|
6
|
+
@parser = parser
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(input)
|
11
|
+
helper(input, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def helper(input, tokens)
|
15
|
+
@parser.parse(input)
|
16
|
+
.bind { |r| helper(r.rest, tokens + r.token) }
|
17
|
+
.map_none { Result.new(tokens, input) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/farseer/chars.rb
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module Farseer
|
4
4
|
class Chars
|
5
|
-
def initialize(chars)
|
6
|
-
@chars = chars
|
5
|
+
def initialize(*chars)
|
6
|
+
@chars = chars.flatten
|
7
7
|
freeze
|
8
8
|
end
|
9
9
|
|
10
|
+
DIGITS = new(('0'..'9').to_a)
|
11
|
+
BASIC_MATH_OP = new(['+', '-', '*', '/'])
|
12
|
+
|
10
13
|
def parse(input)
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
Maybe.none
|
14
|
+
case input[0]
|
15
|
+
when *@chars then Maybe.return(Result.new(input[0], input[1..]))
|
16
|
+
else Maybe.none
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/lib/farseer/many.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class Many
|
5
|
+
def initialize(parser)
|
6
|
+
@parser = parser
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(input)
|
11
|
+
@parser.parse(input)
|
12
|
+
.bind { |r| helper(r.rest, r.token) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def helper(input, tokens)
|
16
|
+
parse(input)
|
17
|
+
.bind { |r| helper(r.rest, tokens + r.token) }
|
18
|
+
.map_none { Result.new(tokens, input) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/farseer/opt.rb
ADDED
data/lib/farseer/or.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class Or
|
5
|
+
def initialize(*parsers)
|
6
|
+
@parsers = parsers.flatten
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(input)
|
11
|
+
case @parsers.length
|
12
|
+
when 0 then Maybe.none
|
13
|
+
when 1 then @parsers.first.parse(input)
|
14
|
+
else parse_helper(input)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse_helper(input)
|
19
|
+
@parsers.reduce do |acc, parser|
|
20
|
+
acc.parse(input).bind_none { parser.parse(input) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class Regexp
|
5
|
+
WS_REGEXP = /^(?'token'\s*)(?'rest'.*)$/
|
6
|
+
RegexpError = Class.new(ArgumentError)
|
7
|
+
|
8
|
+
def initialize(regexp)
|
9
|
+
raise RegexpError unless regexp.names == ['token', 'rest']
|
10
|
+
|
11
|
+
@regexp = regexp
|
12
|
+
freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
WS = new(WS_REGEXP)
|
16
|
+
|
17
|
+
def parse(input)
|
18
|
+
match = input.match(@regexp)
|
19
|
+
|
20
|
+
Maybe.return(Result.new(match[:token], match[:rest]))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/farseer/result.rb
CHANGED
data/lib/farseer/version.rb
CHANGED
data/lib/farseer/word.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Farseer
|
4
|
+
class Word
|
5
|
+
def initialize(word)
|
6
|
+
@word = word
|
7
|
+
freeze
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(input)
|
11
|
+
case
|
12
|
+
when input.start_with?(@word) then Maybe.return(Result.new(@word, input[@word.length..]))
|
13
|
+
else Maybe.none
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/farseer.rb
CHANGED
@@ -6,26 +6,7 @@ loader = Zeitwerk::Loader::for_gem
|
|
6
6
|
loader.setup
|
7
7
|
|
8
8
|
module Farseer
|
9
|
-
WS_REGEX = /^(\s*)(.*)$/
|
10
9
|
Maybe = Muina::Maybe
|
11
|
-
|
12
|
-
def self.any_char_parser
|
13
|
-
->(chars, input) { Chars.new(chars).parse(input) }
|
14
|
-
.curry
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.char_parser
|
18
|
-
->(char, input) { Char.new(char).parse(input) }
|
19
|
-
.curry
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.ws_parser
|
23
|
-
->(input) {
|
24
|
-
match = input.match(WS_REGEX)
|
25
|
-
|
26
|
-
Maybe.return(Result.new(match[1], match[2]))
|
27
|
-
}
|
28
|
-
end
|
29
10
|
end
|
30
11
|
|
31
12
|
loader.eager_load
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: farseer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vaporyhumo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: muina
|
@@ -45,13 +45,22 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- CHANGELOG.md
|
48
49
|
- LICENSE
|
49
50
|
- README.md
|
51
|
+
- SECURITY.md
|
50
52
|
- lib/farseer.rb
|
53
|
+
- lib/farseer/and.rb
|
54
|
+
- lib/farseer/any.rb
|
51
55
|
- lib/farseer/char.rb
|
52
56
|
- lib/farseer/chars.rb
|
57
|
+
- lib/farseer/many.rb
|
58
|
+
- lib/farseer/opt.rb
|
59
|
+
- lib/farseer/or.rb
|
60
|
+
- lib/farseer/regexp.rb
|
53
61
|
- lib/farseer/result.rb
|
54
62
|
- lib/farseer/version.rb
|
63
|
+
- lib/farseer/word.rb
|
55
64
|
homepage: https://github.com/vaporyhumo/farseer
|
56
65
|
licenses:
|
57
66
|
- Unlicense
|