interscript 2.4.5 → 3.0.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/README.md +15 -0
- data/docs/demo/20191118-interscript-demo-cast.gif +0 -0
- data/exe/codemod-imp-to-isc +5 -0
- data/exe/diagnose_parse_failures +47 -0
- data/exe/interscript +2 -1
- data/exe/verify_isc_deep +211 -0
- data/exe/verify_isc_equivalence +128 -0
- data/interscript.gemspec +27 -20
- data/lib/interscript/command.rb +21 -12
- data/lib/interscript/compiler/javascript.rb +34 -35
- data/lib/interscript/compiler/json_ir.rb +214 -0
- data/lib/interscript/compiler/python.rb +354 -0
- data/lib/interscript/compiler/ruby.rb +23 -22
- data/lib/interscript/compiler.rb +20 -3
- data/lib/interscript/detector.rb +14 -7
- data/lib/interscript/dsl/aliases.rb +1 -1
- data/lib/interscript/dsl/document.rb +6 -3
- data/lib/interscript/dsl/group/parallel.rb +1 -1
- data/lib/interscript/dsl/group.rb +18 -9
- data/lib/interscript/dsl/items.rb +28 -16
- data/lib/interscript/dsl/metadata.rb +19 -18
- data/lib/interscript/dsl/stage.rb +1 -1
- data/lib/interscript/dsl/symbol_mm.rb +4 -2
- data/lib/interscript/dsl/tests.rb +1 -1
- data/lib/interscript/dsl.rb +21 -13
- data/lib/interscript/interpreter.rb +32 -21
- data/lib/interscript/isc/codemod.rb +791 -0
- data/lib/interscript/isc/document_builder.rb +354 -0
- data/lib/interscript/isc/generator.rb +191 -0
- data/lib/interscript/isc/grammar/concerns/aliases.rb +29 -0
- data/lib/interscript/isc/grammar/concerns/dependencies.rb +23 -0
- data/lib/interscript/isc/grammar/concerns/items.rb +176 -0
- data/lib/interscript/isc/grammar/concerns/metadata.rb +142 -0
- data/lib/interscript/isc/grammar/concerns/primitives.rb +112 -0
- data/lib/interscript/isc/grammar/concerns/stages.rb +129 -0
- data/lib/interscript/isc/grammar/concerns/system.rb +37 -0
- data/lib/interscript/isc/grammar/concerns/tests.rb +31 -0
- data/lib/interscript/isc/grammar/concerns.rb +18 -0
- data/lib/interscript/isc/grammar/core.rb +23 -0
- data/lib/interscript/isc/grammar/isc.artifact.json +1 -0
- data/lib/interscript/isc/grammar/isc.parg +196 -0
- data/lib/interscript/isc/grammar.rb +12 -0
- data/lib/interscript/isc/items.rb +185 -0
- data/lib/interscript/isc/model/alias.rb +20 -0
- data/lib/interscript/isc/model/constraint.rb +20 -0
- data/lib/interscript/isc/model/dependency.rb +19 -0
- data/lib/interscript/isc/model/document.rb +31 -0
- data/lib/interscript/isc/model/item.rb +50 -0
- data/lib/interscript/isc/model/rule.rb +23 -0
- data/lib/interscript/isc/model/stage.rb +20 -0
- data/lib/interscript/isc/model/stage_item.rb +33 -0
- data/lib/interscript/isc/model/test.rb +21 -0
- data/lib/interscript/isc/model.rb +19 -0
- data/lib/interscript/isc/node_adapter.rb +310 -0
- data/lib/interscript/isc/normalizer.rb +127 -0
- data/lib/interscript/isc/parser.rb +78 -0
- data/lib/interscript/isc/serializer.rb +248 -0
- data/lib/interscript/isc/transform.rb +138 -0
- data/lib/interscript/isc/yaml_bridge.rb +236 -0
- data/lib/interscript/isc.rb +30 -0
- data/lib/interscript/ml/byt5_onnx.rb +102 -0
- data/lib/interscript/ml/imf.rb +182 -0
- data/lib/interscript/ml/model.rb +52 -0
- data/lib/interscript/ml/provisioning.rb +189 -0
- data/lib/interscript/ml/translator.rb +38 -0
- data/lib/interscript/ml/vocab.rb +48 -0
- data/lib/interscript/ml.rb +25 -0
- data/lib/interscript/node/alias_def.rb +5 -5
- data/lib/interscript/node/dependency.rb +7 -7
- data/lib/interscript/node/document.rb +10 -10
- data/lib/interscript/node/group.rb +11 -9
- data/lib/interscript/node/item/alias.rb +14 -10
- data/lib/interscript/node/item/any.rb +14 -7
- data/lib/interscript/node/item/capture.rb +14 -9
- data/lib/interscript/node/item/group.rb +22 -17
- data/lib/interscript/node/item/repeat.rb +3 -3
- data/lib/interscript/node/item/stage.rb +4 -5
- data/lib/interscript/node/item/string.rb +18 -13
- data/lib/interscript/node/item.rb +27 -17
- data/lib/interscript/node/metadata.rb +6 -5
- data/lib/interscript/node/rule/funcall.rb +4 -5
- data/lib/interscript/node/rule/run.rb +4 -5
- data/lib/interscript/node/rule/sub.rb +55 -55
- data/lib/interscript/node/rule.rb +6 -5
- data/lib/interscript/node/stage.rb +11 -14
- data/lib/interscript/node/tests.rb +6 -6
- data/lib/interscript/node.rb +14 -17
- data/lib/interscript/stdlib/functions/rababa_adapter.rb +56 -0
- data/lib/interscript/stdlib/functions/secryst_adapter.rb +37 -0
- data/lib/interscript/stdlib/functions.rb +49 -0
- data/lib/interscript/stdlib.rb +25 -95
- data/lib/interscript/utils/helpers.rb +8 -5
- data/lib/interscript/utils/regexp_converter.rb +143 -144
- data/lib/interscript/version.rb +1 -1
- data/lib/interscript/visualize/json.rb +12 -13
- data/lib/interscript/visualize/nodes.rb +13 -13
- data/lib/interscript/visualize.rb +18 -18
- data/lib/interscript.rb +59 -45
- metadata +88 -31
- data/.github/workflows/assets.yml +0 -91
- data/.github/workflows/rake.yml +0 -52
- data/.github/workflows/release.yml +0 -68
- data/.gitignore +0 -79
- data/.rspec +0 -3
- data/Gemfile +0 -38
- data/Rakefile +0 -139
- data/bin/console +0 -10
- data/bin/interscript +0 -5
- data/bin/maps_analyze_staging +0 -168
- data/bin/maps_debug_compilers +0 -58
- data/bin/maps_debug_ordering +0 -88
- data/bin/maps_debug_ruby_compile +0 -24
- data/bin/maps_debug_step_by_step +0 -44
- data/bin/maps_optimize_order +0 -112
- data/bin/maps_v1_analyze_regexps +0 -45
- data/bin/maps_v1_to_v2 +0 -426
- data/bin/set_version +0 -16
- data/bin/setup +0 -8
- data/requirements.txt +0 -1
|
@@ -5,23 +5,23 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
5
5
|
attr_accessor :reverse_run
|
|
6
6
|
attr_accessor :priority
|
|
7
7
|
|
|
8
|
-
def initialize
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
def initialize(from, to,
|
|
9
|
+
before: nil, not_before: nil,
|
|
10
|
+
after: nil, not_after: nil,
|
|
11
|
+
priority: nil, reverse_run: nil)
|
|
12
12
|
self.from = Interscript::Node::Item.try_convert from
|
|
13
|
-
if to == :upcase
|
|
14
|
-
|
|
13
|
+
self.to = if to == :upcase
|
|
14
|
+
:upcase
|
|
15
15
|
elsif to == :downcase
|
|
16
|
-
|
|
16
|
+
:downcase
|
|
17
17
|
else
|
|
18
|
-
|
|
18
|
+
Interscript::Node::Item.try_convert to
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
self.priority = priority
|
|
22
22
|
|
|
23
|
-
#raise TypeError, "Can't supply both before and not_before" if before && not_before
|
|
24
|
-
#raise TypeError, "Can't supply both after and not_after" if after && not_after
|
|
23
|
+
# raise TypeError, "Can't supply both before and not_before" if before && not_before
|
|
24
|
+
# raise TypeError, "Can't supply both after and not_after" if after && not_after
|
|
25
25
|
|
|
26
26
|
self.reverse_run = reverse_run
|
|
27
27
|
|
|
@@ -32,34 +32,33 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def max_length
|
|
35
|
-
len =
|
|
36
|
-
len +=
|
|
37
|
-
len +=
|
|
38
|
-
len +=
|
|
39
|
-
len +=
|
|
40
|
-
len +=
|
|
35
|
+
len = from.max_length
|
|
36
|
+
len += before.max_length if before
|
|
37
|
+
len += after.max_length if after
|
|
38
|
+
len += not_before.max_length if not_before
|
|
39
|
+
len += not_after.max_length if not_after
|
|
40
|
+
len += priority if priority
|
|
41
41
|
len
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def to_hash
|
|
45
|
-
puts
|
|
45
|
+
puts from.inspect if $DEBUG
|
|
46
46
|
puts params.inspect if $DEBUG
|
|
47
|
-
hash = {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
hash[:
|
|
59
|
-
hash[:
|
|
60
|
-
hash[:
|
|
61
|
-
hash[:
|
|
62
|
-
hash[:priority] = self.priority if self.priority
|
|
47
|
+
hash = {class: self.class.to_s,
|
|
48
|
+
from: from.to_hash,
|
|
49
|
+
to: (Symbol === to) ? to : to.to_hash,
|
|
50
|
+
reverse_run: reverse_run,
|
|
51
|
+
before: before&.to_hash,
|
|
52
|
+
not_before: not_before&.to_hash,
|
|
53
|
+
after: after&.to_hash,
|
|
54
|
+
not_after: not_after&.to_hash,
|
|
55
|
+
priority: priority}
|
|
56
|
+
|
|
57
|
+
hash[:before] = before&.to_hash if before
|
|
58
|
+
hash[:not_before] = not_before&.to_hash if not_before
|
|
59
|
+
hash[:after] = after&.to_hash if after
|
|
60
|
+
hash[:not_after] = not_after&.to_hash if not_after
|
|
61
|
+
hash[:priority] = priority if priority
|
|
63
62
|
|
|
64
63
|
hash
|
|
65
64
|
end
|
|
@@ -76,12 +75,12 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
76
75
|
end
|
|
77
76
|
|
|
78
77
|
# A special case: sub "a", "" shouldn't be present in a reverse map
|
|
79
|
-
rrun =
|
|
78
|
+
rrun = reverse_run.nil? ? nil : !reverse_run
|
|
80
79
|
if rrun.nil? && !has_assertions? &&
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
(xfrom == "" ||
|
|
81
|
+
(Interscript::Node::Item::String === xfrom && xfrom.data == "") ||
|
|
82
|
+
(Interscript::Node::Item::Alias === xfrom && xfrom.name == :none)
|
|
83
|
+
)
|
|
85
84
|
|
|
86
85
|
rrun = true
|
|
87
86
|
end
|
|
@@ -92,10 +91,9 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
92
91
|
|
|
93
92
|
reverse_run: rrun,
|
|
94
93
|
|
|
95
|
-
priority: priority ? -priority : nil
|
|
96
|
-
)
|
|
94
|
+
priority: priority ? -priority : nil)
|
|
97
95
|
end
|
|
98
|
-
|
|
96
|
+
|
|
99
97
|
def has_assertions?
|
|
100
98
|
!!(before || not_before || not_after || after)
|
|
101
99
|
end
|
|
@@ -116,7 +114,7 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
116
114
|
to = out.compact
|
|
117
115
|
|
|
118
116
|
from = from.dup.tap do |i|
|
|
119
|
-
i.children = i.children[1
|
|
117
|
+
i.children = i.children[1..]
|
|
120
118
|
end.compact
|
|
121
119
|
end
|
|
122
120
|
|
|
@@ -140,10 +138,10 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
140
138
|
end
|
|
141
139
|
|
|
142
140
|
# This part is about moving backreferences
|
|
143
|
-
state = {left:[], right:[]}
|
|
141
|
+
state = {left: [], right: []}
|
|
144
142
|
|
|
145
|
-
from
|
|
146
|
-
to
|
|
143
|
+
from = reverse_transfer_visit(from, :from, state)
|
|
144
|
+
to = reverse_transfer_visit(to, :to, state)
|
|
147
145
|
|
|
148
146
|
[from, to]
|
|
149
147
|
end
|
|
@@ -198,23 +196,23 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
198
196
|
|
|
199
197
|
def ==(other)
|
|
200
198
|
super &&
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
199
|
+
from == other.from &&
|
|
200
|
+
to == other.to &&
|
|
201
|
+
before == other.before &&
|
|
202
|
+
after == other.after &&
|
|
203
|
+
not_before == other.not_before &&
|
|
204
|
+
not_after == other.not_after &&
|
|
205
|
+
priority == other.priority
|
|
208
206
|
end
|
|
209
207
|
|
|
210
208
|
def inspect
|
|
211
209
|
out = "sub "
|
|
212
210
|
params = []
|
|
213
211
|
params << @from.inspect
|
|
214
|
-
if Symbol === @to
|
|
215
|
-
|
|
212
|
+
params << if Symbol === @to
|
|
213
|
+
@to.to_s
|
|
216
214
|
else
|
|
217
|
-
|
|
215
|
+
@to.inspect
|
|
218
216
|
end
|
|
219
217
|
params << "reverse_run: #{@reverse_run.inspect}" unless @reverse_run.nil?
|
|
220
218
|
|
|
@@ -226,4 +224,6 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule
|
|
|
226
224
|
params << "priority: #{@priority.inspect}" if @priority
|
|
227
225
|
out << params.join(", ")
|
|
228
226
|
end
|
|
227
|
+
# standard:disable Layout/TrailingEmptyLines (deliberate)
|
|
229
228
|
end
|
|
229
|
+
# standard:enable Layout/TrailingEmptyLines
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
class Interscript::Node::Rule < Interscript::Node
|
|
2
|
+
# Autoload all rule types (OCP: new rule type = one autoload).
|
|
3
|
+
autoload :Sub, "interscript/node/rule/sub"
|
|
4
|
+
autoload :Run, "interscript/node/rule/run"
|
|
5
|
+
autoload :Funcall, "interscript/node/rule/funcall"
|
|
6
|
+
|
|
2
7
|
def ==(other)
|
|
3
|
-
super &&
|
|
8
|
+
super && reverse_run == other.reverse_run
|
|
4
9
|
end
|
|
5
10
|
end
|
|
6
|
-
|
|
7
|
-
require "interscript/node/rule/sub"
|
|
8
|
-
require "interscript/node/rule/run"
|
|
9
|
-
require "interscript/node/rule/funcall"
|
|
@@ -9,34 +9,31 @@ class Interscript::Node::Stage < Interscript::Node::Group::Sequential
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def to_hash
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
{class: self.class.to_s,
|
|
13
|
+
name: name,
|
|
14
|
+
children: @children.map { |x| x.to_hash }}
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def reverse
|
|
18
18
|
return self if dont_reverse
|
|
19
19
|
|
|
20
|
-
@reverse ||=
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
).tap do |r|
|
|
25
|
-
r.children = self.children.reverse.map(&:reverse)
|
|
26
|
-
end
|
|
20
|
+
@reverse ||= self.class.new(name,
|
|
21
|
+
doc_name: Interscript::Node::Document.reverse_name(doc_name),
|
|
22
|
+
reverse_run: reverse_run.nil? ? nil : !reverse_run).tap do |r|
|
|
23
|
+
r.children = children.reverse.map(&:reverse)
|
|
27
24
|
end
|
|
28
25
|
end
|
|
29
26
|
|
|
30
27
|
def ==(other)
|
|
31
28
|
super &&
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
name == other.name &&
|
|
30
|
+
reverse_run == other.reverse_run &&
|
|
31
|
+
dont_reverse == other.dont_reverse
|
|
35
32
|
end
|
|
36
33
|
|
|
37
34
|
def inspect
|
|
38
35
|
args = []
|
|
39
|
-
args <<
|
|
36
|
+
args << @name.to_s if @name != :main
|
|
40
37
|
args << "dont_reverse: true" if dont_reverse
|
|
41
38
|
name = ""
|
|
42
39
|
name = "(#{args.join(", ")})" unless args.empty?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Interscript::Node::Tests < Interscript::Node
|
|
2
2
|
attr_accessor :data
|
|
3
|
-
def initialize data=[]
|
|
3
|
+
def initialize data = []
|
|
4
4
|
@data = data
|
|
5
5
|
end
|
|
6
6
|
|
|
@@ -9,17 +9,17 @@ class Interscript::Node::Tests < Interscript::Node
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def reverse
|
|
12
|
-
self.class.new(data.map do |from,to,reverse_run|
|
|
13
|
-
[to, from, reverse_run
|
|
12
|
+
self.class.new(data.map do |from, to, reverse_run|
|
|
13
|
+
[to, from, reverse_run.nil? ? nil : !reverse_run]
|
|
14
14
|
end)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def ==(other)
|
|
18
|
-
super &&
|
|
18
|
+
super && data == other.data
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def to_hash
|
|
22
|
-
{
|
|
23
|
-
|
|
22
|
+
{class: self.class.to_s,
|
|
23
|
+
data: @data}
|
|
24
24
|
end
|
|
25
25
|
end
|
data/lib/interscript/node.rb
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
|
|
2
1
|
class Interscript::Node
|
|
2
|
+
# Autoload all node types. Adding a new node type = one autoload
|
|
3
|
+
# line here. No require_relative (OCP).
|
|
4
|
+
autoload :Group, "interscript/node/group"
|
|
5
|
+
autoload :Document, "interscript/node/document"
|
|
6
|
+
autoload :MetaData, "interscript/node/metadata"
|
|
7
|
+
autoload :AliasDef, "interscript/node/alias_def"
|
|
8
|
+
autoload :Dependency, "interscript/node/dependency"
|
|
9
|
+
autoload :Tests, "interscript/node/tests"
|
|
10
|
+
autoload :Stage, "interscript/node/stage"
|
|
11
|
+
autoload :Rule, "interscript/node/rule"
|
|
12
|
+
autoload :Item, "interscript/node/item"
|
|
13
|
+
|
|
3
14
|
def initialize
|
|
4
15
|
raise NotImplementedError, "You can't construct a Node directly"
|
|
5
16
|
end
|
|
@@ -9,21 +20,7 @@ class Interscript::Node
|
|
|
9
20
|
end
|
|
10
21
|
|
|
11
22
|
def to_hash
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
}
|
|
23
|
+
{class: self.class.to_s,
|
|
24
|
+
question: "is something missing?"}
|
|
15
25
|
end
|
|
16
26
|
end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
require "interscript/node/group"
|
|
20
|
-
require "interscript/node/document"
|
|
21
|
-
|
|
22
|
-
require "interscript/node/metadata"
|
|
23
|
-
require 'interscript/node/alias_def'
|
|
24
|
-
require 'interscript/node/dependency'
|
|
25
|
-
require 'interscript/node/tests'
|
|
26
|
-
|
|
27
|
-
require "interscript/node/stage"
|
|
28
|
-
require "interscript/node/rule"
|
|
29
|
-
require "interscript/node/item"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class Interscript::Stdlib
|
|
2
|
+
module Functions
|
|
3
|
+
class RababaAdapter
|
|
4
|
+
@rababa_diacritizers = {}
|
|
5
|
+
@mutex = Mutex.new
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def call(output, config:)
|
|
9
|
+
diacritizer = diacritizer_for(config)
|
|
10
|
+
diacritizer.diacritize_text(output)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def reverse(output, config: nil)
|
|
14
|
+
# The legacy rababa reverse path strips harakat directly. It does
|
|
15
|
+
# not need the model loaded — keep it dependency-free so maps
|
|
16
|
+
# that only call `rababa_reverse` work without Rababa installed.
|
|
17
|
+
output.gsub(/[ًٌٍَُِّْ]/, "")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset_cache
|
|
21
|
+
@mutex.synchronize { @rababa_diacritizers.clear }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def diacritizer_for(config_key)
|
|
27
|
+
require_rababa!
|
|
28
|
+
@mutex.synchronize do
|
|
29
|
+
@rababa_diacritizers[config_key] ||= build_diacritizer(config_key)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_diacritizer(config_key)
|
|
34
|
+
config_value = Interscript.rababa_configs.fetch(config_key) do
|
|
35
|
+
raise Interscript::ExternalUtilError,
|
|
36
|
+
"No rababa config registered under '#{config_key}'"
|
|
37
|
+
end
|
|
38
|
+
model_uri = config_value["model"]
|
|
39
|
+
rababa_config = config_value["config"]
|
|
40
|
+
model_path = Interscript.rababa_provision(config_key, model_uri)
|
|
41
|
+
Rababa::Diacritizer.new(model_path, rababa_config)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def require_rababa!
|
|
45
|
+
return if defined?(Rababa)
|
|
46
|
+
begin
|
|
47
|
+
require "rababa"
|
|
48
|
+
rescue LoadError
|
|
49
|
+
raise Interscript::ExternalUtilError,
|
|
50
|
+
"Rababa is not loaded. Please read docs/Usage_with_Rababa.adoc"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class Interscript::Stdlib
|
|
2
|
+
module Functions
|
|
3
|
+
class SecrystAdapter
|
|
4
|
+
@translators = {}
|
|
5
|
+
@mutex = Mutex.new
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
def call(output, model:)
|
|
9
|
+
translator = translator_for(model)
|
|
10
|
+
output.split("\n").map(&:chomp).map { |line| translator.translate(line) }.join("\n")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def reset_cache
|
|
14
|
+
@mutex.synchronize { @translators.clear }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def translator_for(model_key)
|
|
20
|
+
require_secryst!
|
|
21
|
+
@mutex.synchronize do
|
|
22
|
+
@translators[model_key] ||= build_translator(model_key)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def build_translator(model_key)
|
|
27
|
+
Interscript.secryst_index_locations.each do |remote|
|
|
28
|
+
Interscript::ML::Provisioning.add_remote(remote)
|
|
29
|
+
end
|
|
30
|
+
Interscript::ML::Translator.new(model_file: model_key)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
class Interscript::Stdlib
|
|
2
|
+
module Functions
|
|
3
|
+
autoload :RababaAdapter, "interscript/stdlib/functions/rababa_adapter"
|
|
4
|
+
autoload :SecrystAdapter, "interscript/stdlib/functions/secryst_adapter"
|
|
5
|
+
|
|
6
|
+
def self.title_case(output, word_separator: " ")
|
|
7
|
+
output = output.gsub(/^(.)/, &:upcase)
|
|
8
|
+
output = output.gsub(/#{word_separator}(.)/, &:upcase) unless word_separator == ""
|
|
9
|
+
output
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.downcase(output, word_separator: nil)
|
|
13
|
+
if word_separator
|
|
14
|
+
output = output.gsub(/^(.)/, &:downcase)
|
|
15
|
+
output.gsub(/#{word_separator}(.)/, &:downcase) unless word_separator == ""
|
|
16
|
+
else
|
|
17
|
+
output.downcase
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.compose(output, _: nil)
|
|
22
|
+
output.unicode_normalize(:nfc)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.decompose(output, _: nil)
|
|
26
|
+
output.unicode_normalize(:nfd)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.separate(output, separator: " ")
|
|
30
|
+
output.chars.join(separator)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.unseparate(output, separator: " ")
|
|
34
|
+
output.split(separator).join("")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.secryst(output, model:)
|
|
38
|
+
SecrystAdapter.call(output, model: model)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.rababa(output, config:)
|
|
42
|
+
RababaAdapter.call(output, config: config)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.rababa_reverse(output, config: nil)
|
|
46
|
+
RababaAdapter.reverse(output)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/interscript/stdlib.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class Interscript::Stdlib
|
|
2
2
|
ALIASES = {
|
|
3
|
-
any_character:
|
|
3
|
+
any_character: ".",
|
|
4
4
|
none: "",
|
|
5
5
|
space: " ",
|
|
6
6
|
whitespace: "[\\b \\t\\0\\r\\n]",
|
|
@@ -19,7 +19,7 @@ class Interscript::Stdlib
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
def self.re_only_alias?(a)
|
|
22
|
-
|
|
22
|
+
!%i[none space].include?(a)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def self.boundary_like_alias?(a)
|
|
@@ -30,10 +30,10 @@ class Interscript::Stdlib
|
|
|
30
30
|
|
|
31
31
|
def self.parallel_regexp_compile(subs_hash)
|
|
32
32
|
# puts subs_hash.inspect
|
|
33
|
-
regexp = subs_hash.each_with_index.map do |p,i|
|
|
34
|
-
"(?<_%d>%s)" % [i,p[0]]
|
|
33
|
+
regexp = subs_hash.each_with_index.map do |p, i|
|
|
34
|
+
"(?<_%d>%s)" % [i, p[0]]
|
|
35
35
|
end.join("|")
|
|
36
|
-
|
|
36
|
+
Regexp.compile(regexp)
|
|
37
37
|
# puts subs_regexp.inspect
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -41,16 +41,20 @@ class Interscript::Stdlib
|
|
|
41
41
|
string.gsub(subs_regexp) do |match|
|
|
42
42
|
lm = Regexp.last_match
|
|
43
43
|
# Extract the match name
|
|
44
|
-
idx = lm.named_captures.compact.keys.first[1
|
|
44
|
+
idx = lm.named_captures.compact.keys.first[1..].to_i
|
|
45
45
|
subs_hash[idx]
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def self.parallel_regexp_gsub_debug(string, subs_regexp, subs_array)
|
|
50
50
|
# only gathering debug info, test data is available in maps_analyze_staging
|
|
51
|
+
# standard:disable Style/GlobalVars (deliberate $DEBUG / -d-flag debug idiom)
|
|
51
52
|
$subs_matches = []
|
|
53
|
+
# standard:enable Style/GlobalVars
|
|
54
|
+
# standard:disable Style/GlobalVars (deliberate $DEBUG / -d-flag debug idiom)
|
|
52
55
|
$subs_regexp = subs_regexp
|
|
53
|
-
|
|
56
|
+
# standard:enable Style/GlobalVars
|
|
57
|
+
# $subs_array = subs_array
|
|
54
58
|
string.gsub(subs_regexp) do |match|
|
|
55
59
|
lm = Regexp.last_match
|
|
56
60
|
# puts lm.inspect
|
|
@@ -58,35 +62,36 @@ class Interscript::Stdlib
|
|
|
58
62
|
matched = lm.named_captures.compact.keys.first
|
|
59
63
|
# puts matched.inspect
|
|
60
64
|
# puts [lm.begin(matched), lm.end(matched)].inspect
|
|
61
|
-
idx = matched[1
|
|
65
|
+
idx = matched[1..].to_i
|
|
62
66
|
debug_info = {begin: lm.begin(matched), end: lm.end(matched), idx: idx, result: subs_array[idx]}
|
|
67
|
+
# standard:disable Style/GlobalVars (deliberate $DEBUG / -d-flag debug idiom)
|
|
63
68
|
$subs_matches << debug_info
|
|
69
|
+
# standard:enable Style/GlobalVars
|
|
64
70
|
subs_array[idx]
|
|
65
71
|
end
|
|
66
72
|
end
|
|
67
73
|
|
|
68
|
-
|
|
69
74
|
def self.parallel_replace_compile_hash(a)
|
|
70
75
|
h = {}
|
|
71
|
-
a.each do |from,to|
|
|
76
|
+
a.each do |from, to|
|
|
72
77
|
h[from] = to
|
|
73
78
|
end
|
|
74
79
|
h
|
|
75
80
|
end
|
|
76
81
|
|
|
77
|
-
def self.parallel_replace_hash(str,h)
|
|
82
|
+
def self.parallel_replace_hash(str, h)
|
|
78
83
|
newstr = ""
|
|
79
84
|
len = str.length
|
|
80
85
|
max_key_len = h.keys.map(&:length).max
|
|
81
86
|
i = 0
|
|
82
87
|
while i < len
|
|
83
88
|
max_key_len.downto(1).each do |checked_len|
|
|
84
|
-
substr = str[i,checked_len]
|
|
89
|
+
substr = str[i, checked_len]
|
|
85
90
|
if h[substr]
|
|
86
91
|
newstr << h[substr]
|
|
87
92
|
i += substr.length
|
|
88
|
-
elsif checked_len==1
|
|
89
|
-
newstr << str[i,1]
|
|
93
|
+
elsif checked_len == 1
|
|
94
|
+
newstr << str[i, 1]
|
|
90
95
|
i += 1
|
|
91
96
|
end
|
|
92
97
|
end
|
|
@@ -105,7 +110,7 @@ class Interscript::Stdlib
|
|
|
105
110
|
from = Array(from)
|
|
106
111
|
from.each do |f|
|
|
107
112
|
branch = tree
|
|
108
|
-
chars = f.
|
|
113
|
+
chars = f.chars
|
|
109
114
|
chars[0..-2].each do |c|
|
|
110
115
|
branch[c.ord] ||= {}
|
|
111
116
|
branch = branch[c.ord]
|
|
@@ -130,8 +135,8 @@ class Interscript::Stdlib
|
|
|
130
135
|
match, repl = nil, nil
|
|
131
136
|
|
|
132
137
|
j = 0
|
|
133
|
-
while j < len-i
|
|
134
|
-
cc = str[i+j]
|
|
138
|
+
while j < len - i
|
|
139
|
+
cc = str[i + j]
|
|
135
140
|
if branch.include? cc.ord
|
|
136
141
|
branch = branch[cc.ord]
|
|
137
142
|
sub << cc
|
|
@@ -167,7 +172,7 @@ class Interscript::Stdlib
|
|
|
167
172
|
# Deterministic on Linux:
|
|
168
173
|
# ary.sort_by{ |rule| -rule.max_length }
|
|
169
174
|
|
|
170
|
-
ary.each_with_index.sort_by{ |rule,idx| -rule.max_length*100000 + idx }.map(&:first)
|
|
175
|
+
ary.each_with_index.sort_by { |rule, idx| -rule.max_length * 100000 + idx }.map(&:first)
|
|
171
176
|
end
|
|
172
177
|
|
|
173
178
|
def self.available_functions
|
|
@@ -186,84 +191,9 @@ class Interscript::Stdlib
|
|
|
186
191
|
unseparate: :separate,
|
|
187
192
|
|
|
188
193
|
rababa: :rababa_reverse,
|
|
189
|
-
rababa_reverse: :rababa
|
|
194
|
+
rababa_reverse: :rababa
|
|
190
195
|
}
|
|
191
196
|
end
|
|
192
197
|
|
|
193
|
-
|
|
194
|
-
def self.title_case(output, word_separator: " ")
|
|
195
|
-
output = output.gsub(/^(.)/, &:upcase)
|
|
196
|
-
output = output.gsub(/#{word_separator}(.)/, &:upcase) unless word_separator == ''
|
|
197
|
-
output
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def self.downcase(output, word_separator: nil)
|
|
201
|
-
if word_separator
|
|
202
|
-
output = output.gsub(/^(.)/, &:downcase)
|
|
203
|
-
output = output.gsub(/#{word_separator}(.)/, &:downcase) unless word_separator == ''
|
|
204
|
-
else
|
|
205
|
-
output.downcase
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def self.compose(output, _:nil)
|
|
210
|
-
output.unicode_normalize(:nfc)
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def self.decompose(output, _:nil)
|
|
214
|
-
output.unicode_normalize(:nfd)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def self.separate(output, separator: " ")
|
|
218
|
-
output.split("").join(separator)
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def self.unseparate(output, separator: " ")
|
|
222
|
-
output.split(separator).join("")
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
@secryst_models = {}
|
|
226
|
-
def self.secryst(output, model:)
|
|
227
|
-
require "secryst" rescue nil # Try to load secryst, but don't fail hard if not possible.
|
|
228
|
-
unless defined? Secryst
|
|
229
|
-
raise Interscript::ExternalUtilError, "Secryst is not loaded. Please read docs/Usage_with_Secryst.adoc"
|
|
230
|
-
end
|
|
231
|
-
Interscript.secryst_index_locations.each do |remote|
|
|
232
|
-
Secryst::Provisioning.add_remote(remote)
|
|
233
|
-
end
|
|
234
|
-
@secryst_models[model] ||= Secryst::Translator.new(model_file: model)
|
|
235
|
-
output.split("\n").map(&:chomp).map do |i|
|
|
236
|
-
@secryst_models[model].translate(i)
|
|
237
|
-
end.join("\n")
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def self.rababa(output, config:)
|
|
241
|
-
require "rababa" rescue nil # Try to load rababa, but don't fail hard if not possible.
|
|
242
|
-
unless defined? Rababa
|
|
243
|
-
raise Interscript::ExternalUtilError, "Rababa is not loaded. Please read docs/Usage_with_Rababa.adoc"
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
config_value = Interscript.rababa_configs[config]
|
|
247
|
-
model_uri = config_value['model']
|
|
248
|
-
rababa_config = config_value['config']
|
|
249
|
-
model_path = Interscript.rababa_provision(config, model_uri)
|
|
250
|
-
|
|
251
|
-
@rababa_diacritizer ||= Rababa::Diacritizer.new(model_path, rababa_config)
|
|
252
|
-
|
|
253
|
-
@rababa_diacritizer.diacritize_text(output)
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
def self.rababa_reverse(output, config:)
|
|
257
|
-
# require "rababa" rescue nil # Try to load rababa, but don't fail hard if not possible.
|
|
258
|
-
# unless defined? Rababa
|
|
259
|
-
# raise StandardError, "Rababa is not loaded. Please read docs/Usage_with_Rababa.adoc"
|
|
260
|
-
# end
|
|
261
|
-
|
|
262
|
-
# A call to allocate allows us to remove diacritics without initializing the model
|
|
263
|
-
# Rababa::Diacritizer.allocate.remove_diacritics(output)
|
|
264
|
-
|
|
265
|
-
# Unfortunately, this is broken as of now.
|
|
266
|
-
output.gsub(/[\u064e\u064b\u064f\u064c\u0650\u064d\u0652\u0651]/, '')
|
|
267
|
-
end
|
|
268
|
-
end
|
|
198
|
+
autoload :Functions, "interscript/stdlib/functions"
|
|
269
199
|
end
|