interscript 0.1.4 → 2.0.5

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.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +29 -0
  5. data/LICENSE.adoc +31 -0
  6. data/README.md +3 -0
  7. data/Rakefile +53 -0
  8. data/bin/console +14 -0
  9. data/bin/interscript +3 -39
  10. data/bin/maps_analyze_staging +168 -0
  11. data/bin/maps_debug_compilers +58 -0
  12. data/bin/maps_debug_ordering +88 -0
  13. data/bin/maps_debug_ruby_compile +24 -0
  14. data/bin/maps_debug_step_by_step +44 -0
  15. data/bin/maps_optimize_order +112 -0
  16. data/bin/maps_v1_analyze_regexps +45 -0
  17. data/bin/maps_v1_to_v2 +426 -0
  18. data/exe/interscript +6 -0
  19. data/interscript.gemspec +31 -0
  20. data/lib/interscript.rb +76 -128
  21. data/lib/interscript/command.rb +6 -5
  22. data/lib/interscript/compiler.rb +22 -0
  23. data/lib/interscript/compiler/javascript.rb +292 -0
  24. data/lib/interscript/compiler/ruby.rb +262 -0
  25. data/lib/interscript/dsl.rb +67 -0
  26. data/lib/interscript/dsl/aliases.rb +23 -0
  27. data/lib/interscript/dsl/document.rb +46 -0
  28. data/lib/interscript/dsl/group.rb +45 -0
  29. data/lib/interscript/dsl/group/parallel.rb +6 -0
  30. data/lib/interscript/dsl/items.rb +89 -0
  31. data/lib/interscript/dsl/metadata.rb +26 -0
  32. data/lib/interscript/dsl/stage.rb +6 -0
  33. data/lib/interscript/dsl/symbol_mm.rb +11 -0
  34. data/lib/interscript/dsl/tests.rb +12 -0
  35. data/lib/interscript/interpreter.rb +251 -0
  36. data/lib/interscript/node.rb +25 -0
  37. data/lib/interscript/node/alias_def.rb +15 -0
  38. data/lib/interscript/node/dependency.rb +13 -0
  39. data/lib/interscript/node/document.rb +45 -0
  40. data/lib/interscript/node/group.rb +34 -0
  41. data/lib/interscript/node/group/parallel.rb +9 -0
  42. data/lib/interscript/node/group/sequential.rb +2 -0
  43. data/lib/interscript/node/item.rb +52 -0
  44. data/lib/interscript/node/item/alias.rb +42 -0
  45. data/lib/interscript/node/item/any.rb +61 -0
  46. data/lib/interscript/node/item/capture.rb +50 -0
  47. data/lib/interscript/node/item/group.rb +51 -0
  48. data/lib/interscript/node/item/repeat.rb +40 -0
  49. data/lib/interscript/node/item/stage.rb +23 -0
  50. data/lib/interscript/node/item/string.rb +51 -0
  51. data/lib/interscript/node/metadata.rb +18 -0
  52. data/lib/interscript/node/rule.rb +6 -0
  53. data/lib/interscript/node/rule/funcall.rb +18 -0
  54. data/lib/interscript/node/rule/run.rb +15 -0
  55. data/lib/interscript/node/rule/sub.rb +65 -0
  56. data/lib/interscript/node/stage.rb +19 -0
  57. data/lib/interscript/node/tests.rb +15 -0
  58. data/lib/interscript/stdlib.rb +211 -0
  59. data/lib/interscript/utils/regexp_converter.rb +283 -0
  60. data/lib/interscript/version.rb +1 -1
  61. data/requirements.txt +1 -0
  62. metadata +73 -223
  63. data/README.adoc +0 -297
  64. data/bin/rspec +0 -29
  65. data/lib/g2pwrapper.py +0 -34
  66. data/lib/interscript/mapping.rb +0 -125
  67. data/lib/model-7 +0 -0
  68. data/lib/tha-pt-b-7 +0 -0
  69. data/maps/acadsin-zho-Hani-Latn-2002.yaml +0 -38912
  70. data/maps/alalc-aze-Cyrl-Latn-1997.yaml +0 -141
  71. data/maps/alalc-bel-cyrl-latn-1997.yaml +0 -125
  72. data/maps/alalc-ben-Beng-Latn-2017.yaml +0 -130
  73. data/maps/alalc-bul-Cyrl-Latn-1997.yaml +0 -94
  74. data/maps/alalc-ell-Grek-Latn-1997.yaml +0 -625
  75. data/maps/alalc-ell-Grek-Latn-2010.yaml +0 -628
  76. data/maps/alalc-kat-Geok-Latn-1997.yaml +0 -112
  77. data/maps/alalc-kat-Geor-Latn-1997.yaml +0 -146
  78. data/maps/alalc-kor-Hang-Latn-1997.yaml +0 -94
  79. data/maps/alalc-mkd-Cyrl-Latn-2013.yaml +0 -103
  80. data/maps/alalc-mkd-cyrl-latn-1997.yaml +0 -114
  81. data/maps/alalc-rus-Cyrl-Latn-1997.yaml +0 -222
  82. data/maps/alalc-rus-Cyrl-Latn-2012.yaml +0 -162
  83. data/maps/alalc-srp-Cyrl-Latn-1997.yaml +0 -114
  84. data/maps/alalc-srp-cyrl-latn-2013.yaml +0 -135
  85. data/maps/alalc-ukr-Cyrl-Latn-1997.yaml +0 -141
  86. data/maps/alalc-ukr-Cyrl-Latn-2011.yaml +0 -16
  87. data/maps/apcbg-bul-Cyrl-Latn-1995.yaml +0 -283
  88. data/maps/bas-rus-Cyrl-Latn-2017-bss.yaml +0 -175
  89. data/maps/bas-rus-Cyrl-Latn-2017-oss.yaml +0 -169
  90. data/maps/bgn-jpn-Hrkt-Latn-1962.yaml +0 -294
  91. data/maps/bgn-kor-Hang-Latn-1943.yaml +0 -31
  92. data/maps/bgn-kor-Kore-Latn-1943.yaml +0 -31
  93. data/maps/bgna-bul-Cyrl-Latn-2006.yaml +0 -208
  94. data/maps/bgna-bul-Cyrl-Latn-2009.yaml +0 -208
  95. data/maps/bgnpcgn-arm-Armn-Latn-1981.yaml +0 -108
  96. data/maps/bgnpcgn-aze-Cyrl-Latn-1993.yaml +0 -104
  97. data/maps/bgnpcgn-bak-Cyrl-Latn-2007.yaml +0 -184
  98. data/maps/bgnpcgn-bel-cyrl-latn-1979.yaml +0 -285
  99. data/maps/bgnpcgn-bul-Cyrl-Latn-1952.yaml +0 -115
  100. data/maps/bgnpcgn-bul-Cyrl-Latn-2013.yaml +0 -38
  101. data/maps/bgnpcgn-chn-Hans-Latn-1979.yaml +0 -7456
  102. data/maps/bgnpcgn-ell-Grek-Latn-1962.yaml +0 -702
  103. data/maps/bgnpcgn-ell-Grek-Latn-1996.yaml +0 -20
  104. data/maps/bgnpcgn-jpn-Hrkt-Latn-1976.yaml +0 -257
  105. data/maps/bgnpcgn-kat-Geor-Latn-1981.yaml +0 -127
  106. data/maps/bgnpcgn-kat-Geor-Latn-2009.yaml +0 -43
  107. data/maps/bgnpcgn-kor-Hang-Latn-kn-1945.yaml +0 -253
  108. data/maps/bgnpcgn-kor-Hang-Latn-rok-2011.yaml +0 -48
  109. data/maps/bgnpcgn-kor-Kore-Latn-rok-2011.yaml +0 -48
  110. data/maps/bgnpcgn-mkd-Cyrl-Latn-1981.yaml +0 -159
  111. data/maps/bgnpcgn-mkd-Cyrl-Latn-2013.yaml +0 -190
  112. data/maps/bgnpcgn-per-Arab-Latn-1956.yaml +0 -93
  113. data/maps/bgnpcgn-rus-Cyrl-Latn-1947.yaml +0 -314
  114. data/maps/bgnpcgn-srp-Cyrl-Latn-2005.yaml +0 -166
  115. data/maps/bgnpcgn-ukr-Cyrl-Latn-1965.yaml +0 -163
  116. data/maps/bgnpcgn-ukr-Cyrl-Latn-2019.yaml +0 -208
  117. data/maps/by-bel-Cyrl-Latn-1998.yaml +0 -168
  118. data/maps/by-bel-Cyrl-Latn-2007.yaml +0 -115
  119. data/maps/elot-ell-Grek-Latn-743-1982-tl.yaml +0 -685
  120. data/maps/elot-ell-Grek-Latn-743-1982-ts.yaml +0 -681
  121. data/maps/elot-ell-Grek-Latn-743-2001-tl.yaml +0 -20
  122. data/maps/elot-ell-Grek-Latn-743-2001-ts.yaml +0 -32
  123. data/maps/ggg-kat-Geor-Latn-2002.yaml +0 -89
  124. data/maps/gki-bel-cyrl-latn-1992.yaml +0 -33
  125. data/maps/gki-bel-cyrl-latn-2000.yaml +0 -201
  126. data/maps/gost-rus-cyrl-latn-16876-71-1983.yaml +0 -186
  127. data/maps/hk-yue-Hani-Latn-1888.yaml +0 -38497
  128. data/maps/icao-bel-Cyrl-Latn-9303.yaml +0 -141
  129. data/maps/icao-bul-Cyrl-Latn-9303.yaml +0 -122
  130. data/maps/icao-heb-Hebr-Latn-9303.yaml +0 -151
  131. data/maps/icao-mkd-Cyrl-Latn-9303.yaml +0 -117
  132. data/maps/icao-per-Arab-Latn-9303.yaml +0 -104
  133. data/maps/icao-rus-Cyrl-Latn-9303.yaml +0 -118
  134. data/maps/icao-srp-Cyrl-Latn-9303.yaml +0 -117
  135. data/maps/icao-ukr-Cyrl-Latn-9303.yaml +0 -120
  136. data/maps/iso-ell-Grek-Latn-843-1997-t1.yaml +0 -610
  137. data/maps/iso-ell-Grek-Latn-843-1997-t2.yaml +0 -41
  138. data/maps/iso-jpn-Hrkt-Latn-3602-1989.yaml +0 -62
  139. data/maps/iso-rus-Cyrl-Latn-9-1995.yaml +0 -272
  140. data/maps/iso-tha-Thai-Latn-11940-1998.yaml +0 -109
  141. data/maps/kp-kor-Hang-Latn-2002.yaml +0 -901
  142. data/maps/lshk-yue-Hani-Latn-jyutping-1993.yaml +0 -44820
  143. data/maps/mext-jpn-Hrkt-Latn-1954.yaml +0 -411
  144. data/maps/moct-kor-Hang-Latn-2000.yaml +0 -803
  145. data/maps/mofa-jpn-Hrkt-Latn-1989.yaml +0 -541
  146. data/maps/mvd-bel-Cyrl-Latn-2008.yaml +0 -225
  147. data/maps/mvd-bel-Cyrl-Latn-2010.yaml +0 -63
  148. data/maps/mvd-rus-Cyrl-Latn-2008.yaml +0 -110
  149. data/maps/mvd-rus-Cyrl-Latn-2010.yaml +0 -37
  150. data/maps/nil-kor-Hang-Hang-jamo.yaml +0 -11193
  151. data/maps/odni-bel-Cyrl-Latn-2015.yaml +0 -148
  152. data/maps/odni-bul-Cyrl-Latn-2015.yaml +0 -96
  153. data/maps/odni-kat-Geor-Latn-2015.yaml +0 -88
  154. data/maps/odni-rus-Cyrl-Latn-2015.yaml +0 -77
  155. data/maps/odni-srp-Cyrl-Latn-2015.yaml +0 -129
  156. data/maps/odni-ukr-Cyrl-Latn-2015.yaml +0 -157
  157. data/maps/odni-uzb-Cyrl-Latn-2015.yaml +0 -167
  158. data/maps/royin-tha-Thai-Latn-1939-generic.yaml +0 -90
  159. data/maps/royin-tha-Thai-Latn-1968.yaml +0 -179
  160. data/maps/royin-tha-Thai-Latn-1999-chained.yaml +0 -180
  161. data/maps/royin-tha-Thai-Latn-1999.yaml +0 -76
  162. data/maps/sac-zho-Hans-Latn-1979.yaml +0 -24759
  163. data/maps/stategeocadastre-ukr-Cyrl-Latn-1993.yaml +0 -222
  164. data/maps/ua-ukr-Cyrl-Latn-1996.yaml +0 -193
  165. data/maps/un-bel-Cyrl-Latn-2007.yaml +0 -114
  166. data/maps/un-ben-Beng-Latn-2016.yaml +0 -534
  167. data/maps/un-ell-Grek-Latn-1987-tl.yaml +0 -32
  168. data/maps/un-ell-Grek-Latn-1987-ts.yaml +0 -20
  169. data/maps/un-ell-Grek-Latn-phonetic-1987.yaml +0 -780
  170. data/maps/un-mon-Mong-Latn-2013.yaml +0 -93
  171. data/maps/un-rus-Cyrl-Latn-1987.yaml +0 -166
  172. data/maps/un-ukr-cyrl-latn-1998.yaml +0 -30
  173. data/maps/var-jpn-Hrkt-Latn-hepburn-1886.yaml +0 -406
  174. data/maps/var-jpn-Hrkt-Latn-hepburn-1954.yaml +0 -386
  175. data/maps/var-kor-Hang-Latn-mr-1939.yaml +0 -1054
  176. data/maps/var-kor-Kore-Hang-2013.yaml +0 -59754
  177. data/maps/var-kor-Kore-Latn-mr-1939.yaml +0 -37
  178. data/maps/var-tha-Thai-Thai-phonemic.yaml +0 -59
  179. data/maps/var-tha-Thai-Zsym-ipa.yaml +0 -301
  180. data/maps/var-zho-Hani-Latn-1979.yaml +0 -38908
  181. data/spec/interscript/mapping_spec.rb +0 -42
  182. data/spec/interscript_spec.rb +0 -26
  183. data/spec/spec_helper.rb +0 -3
@@ -0,0 +1,6 @@
1
+ class Interscript::DSL::Group::Parallel < Interscript::DSL::Group
2
+ def initialize(&block)
3
+ @node = Interscript::Node::Group::Parallel.new
4
+ self.instance_exec(&block)
5
+ end
6
+ end
@@ -0,0 +1,89 @@
1
+ module Interscript::DSL::Items
2
+ include Interscript::DSL::SymbolMM
3
+
4
+ def method_missing sym, *args, **kwargs, &block
5
+ super if args.length > 0
6
+ super if kwargs.length > 0
7
+ super if sym.to_s =~ /[?!=]\z/
8
+ super unless sym.to_s =~ /\A[\w\d]+\z/
9
+ super if block_given?
10
+
11
+ Interscript::Node::Item::Alias.new(sym)
12
+ end
13
+
14
+ def any(*chars)
15
+ puts "any(#{chars.inspect}) from #{self.inspect}" if $DEBUG
16
+ Interscript::Node::Item::Any.new(*chars)
17
+ end
18
+
19
+ # a?
20
+ def maybe(*chars)
21
+ puts "maybe(#{chars.inspect}) from #{self.inspect}" if $DEBUG
22
+ Interscript::Node::Item::Maybe.new(*chars)
23
+ end
24
+
25
+ def maybe_some(*chars)
26
+ puts "maybe_some(#{chars.inspect}) from #{self.inspect}" if $DEBUG
27
+ Interscript::Node::Item::MaybeSome.new(*chars)
28
+ end
29
+
30
+ def some(*chars)
31
+ puts "some(#{chars.inspect}) from #{self.inspect}" if $DEBUG
32
+ Interscript::Node::Item::Some.new(*chars)
33
+ end
34
+
35
+ # (...)
36
+ def capture(expr)
37
+ puts "capture(#{expr.inspect}) from #{self.inspect}" if $DEBUG
38
+ Interscript::Node::Item::CaptureGroup.new(expr)
39
+ end
40
+
41
+ # \1
42
+ def ref(int)
43
+ puts "ref(#{int.inspect}) from #{self.inspect}" if $DEBUG
44
+ Interscript::Node::Item::CaptureRef.new(int)
45
+ end
46
+
47
+ # Implementation of `map.x`
48
+ def map; Interscript::DSL::Items::Maps; end
49
+
50
+ # Implementation of `stage.x`
51
+ def stage; Stages.new; end
52
+
53
+ # Implementation of `map.x`
54
+ module Maps
55
+ class << self
56
+ # Select a remote map
57
+ def [] map
58
+ Symbol === map or raise TypeError, "A map name must be a Symbol, not #{alias_name.class}"
59
+ Map.new(map)
60
+ end
61
+ alias method_missing []
62
+ end
63
+ end
64
+
65
+ # Implementation of `map.x.aliasname` and `map.x.stage.stagename`
66
+ class Map
67
+ def initialize name; @name = name; end
68
+
69
+ # Implementation of `map.x.aliasname`
70
+ def [] alias_name
71
+ Symbol === alias_name or raise TypeError, "An alias name must be a Symbol, not #{alias_name.class}"
72
+ Interscript::Node::Item::Alias.new(alias_name, map: @name)
73
+ end
74
+ alias method_missing []
75
+
76
+ # Implementation of `map.x.stage.stagename`
77
+ def stage; Stages.new(@name); end
78
+ end
79
+
80
+ # Implementation of `map.x.stage.stagename` and `stage.stagename`
81
+ class Stages
82
+ def initialize map=nil; @map = map; end
83
+
84
+ def [] stage
85
+ Interscript::Node::Item::Stage.new(stage, map: @map)
86
+ end
87
+ alias method_missing []
88
+ end
89
+ end
@@ -0,0 +1,26 @@
1
+ class Interscript::DSL::Metadata
2
+ attr_accessor :node
3
+
4
+ def initialize(yaml: false, &block)
5
+ raise ArgumentError, "Can't evaluate metadata from Ruby context" unless yaml
6
+ @node = Interscript::Node::MetaData.new
7
+ self.instance_exec(&block)
8
+ end
9
+
10
+ %i{authority_id id language source_script
11
+ destination_script name url creation_date
12
+ adoption_date description character notes
13
+ source confirmation_date}.each do |sym|
14
+ define_method sym do |stuff|
15
+ @node[sym] = stuff
16
+ end
17
+ end
18
+
19
+ %i{special_rules original_description original_notes
20
+ implementation_notes}.each do |sym|
21
+ define_method sym do |stuff|
22
+ warn "Metadata key #{sym} is non-standard"
23
+ @node[sym] = stuff
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ class Interscript::DSL::Stage < Interscript::DSL::Group
2
+ def initialize(name = :main, &block)
3
+ @node = Interscript::Node::Stage.new(name)
4
+ self.instance_exec(&block)
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Interscript::DSL::SymbolMM
2
+ def method_missing sym, *args, **kwargs, &block
3
+ super if args.length > 0
4
+ super if kwargs.length > 0
5
+ super if sym.to_s =~ /[?!=]\z/
6
+ super unless sym.to_s =~ /\A[\w\d]+\z/
7
+ super if block_given?
8
+
9
+ sym.to_sym
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class Interscript::DSL::Tests
2
+ attr_accessor :node
3
+
4
+ def initialize(&block)
5
+ @node = Interscript::Node::Tests.new
6
+ self.instance_exec(&block)
7
+ end
8
+
9
+ def test(from,to)
10
+ @node << [from, to]
11
+ end
12
+ end
@@ -0,0 +1,251 @@
1
+ class Interscript::Interpreter < Interscript::Compiler
2
+ attr_accessor :map
3
+ def compile(map, _:nil)
4
+ @map = map
5
+ self
6
+ end
7
+
8
+ def call(str, stage=:main, each: false, &block)
9
+ stage = @map.stages[stage]
10
+ s =
11
+ if each
12
+ e = Enumerator.new do |yielder|
13
+ options = []
14
+ options_set = false
15
+ choices = nil
16
+
17
+ i = 0
18
+
19
+ loop do
20
+ result = nil
21
+
22
+ f = Fiber.new do
23
+ $select_nth_string = true
24
+ result = Stage.new(@map, str).execute_rule(stage)
25
+ $select_nth_string = false
26
+ Fiber.yield(:end)
27
+ end
28
+
29
+ iter = 0
30
+
31
+ loop do
32
+ break if f.resume == :end
33
+ # hash is unused for now... some problems may arise in certain
34
+ # scenarios that are not a danger right now, but i'm genuinely
35
+ # unsure how it can be handled.
36
+ #
37
+ # This scenario is described in a commented out test.
38
+ type, value, hash = f.resume
39
+ if options_set
40
+ f.resume(choices[i][iter])
41
+ else
42
+ options[iter] = value
43
+ f.resume(0)
44
+ end
45
+ iter += 1
46
+ end
47
+
48
+ unless options_set
49
+ options_set = true
50
+
51
+ opts = options.map { |i| (0...i).to_a }
52
+ choices = opts[0].product(*opts[1..-1])
53
+ end
54
+
55
+ yielder.yield(result)
56
+
57
+ i += 1
58
+ break if i == choices.length
59
+ end
60
+ end
61
+
62
+ if block_given?
63
+ e.each(&block)
64
+ else
65
+ e
66
+ end
67
+ else
68
+ Stage.new(@map, str).execute_rule(stage)
69
+ end
70
+ end
71
+
72
+ class Stage
73
+ def initialize(map, str)
74
+ @str = str
75
+ @map = map
76
+ end
77
+
78
+ def execute_rule r
79
+ case r
80
+ when Interscript::Node::Group::Parallel
81
+ if r.cached_tree
82
+ @str = Interscript::Stdlib.parallel_replace_tree(@str, r.cached_tree)
83
+ elsif r.subs_regexp && r.subs_replacements
84
+ if $DEBUG_RE
85
+ @str = Interscript::Stdlib.parallel_regexp_gsub_debug(@str, r.subs_regexp, r.subs_replacements)
86
+ else
87
+ @str = Interscript::Stdlib.parallel_regexp_gsub(@str, r.subs_regexp, r.subs_replacements)
88
+ end
89
+ else
90
+ begin
91
+ # Try to build a tree
92
+ subs_array = []
93
+ r.children.each do |i|
94
+ raise ArgumentError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i
95
+ raise ArgumentError, "Can't parallelize rules with :before" if i.before
96
+ raise ArgumentError, "Can't parallelize rules with :after" if i.after
97
+ raise ArgumentError, "Can't parallelize rules with :not_before" if i.not_before
98
+ raise ArgumentError, "Can't parallelize rules with :not_after" if i.not_after
99
+ subs_array << [build_item(i.from, :par), build_item(i.to, :parstr)]
100
+ end
101
+ tree = Interscript::Stdlib.parallel_replace_compile_tree(subs_array) #.sort_by{|k,v| -k.length})
102
+ @str = Interscript::Stdlib.parallel_replace_tree(@str, tree)
103
+ r.cached_tree = tree
104
+ # $using_tree = true
105
+ rescue
106
+ # $using_tree = false
107
+ # Otherwise let's build a megaregexp
108
+ subs_array = []
109
+ Interscript::Stdlib.deterministic_sort_by_max_length(r.children).each do |i| # rule.from.max_length gives somewhat better test results, why is that
110
+ raise ArgumentError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i
111
+
112
+ subs_array << [build_regexp(i), build_item(i.to, :parstr)]
113
+ end
114
+ r.subs_regexp = Interscript::Stdlib.parallel_regexp_compile(subs_array)
115
+ r.subs_replacements = subs_array.map(&:last)
116
+ if $DEBUG_RE
117
+ # puts subs_array.inspect
118
+ $subs_array = subs_array
119
+ @str = Interscript::Stdlib.parallel_regexp_gsub_debug(@str, r.subs_regexp, r.subs_replacements)
120
+ else
121
+ @str = Interscript::Stdlib.parallel_regexp_gsub(@str, r.subs_regexp, r.subs_replacements)
122
+ end
123
+ end
124
+ end
125
+ when Interscript::Node::Group
126
+ r.children.each do |t|
127
+ execute_rule(t)
128
+ end
129
+ when Interscript::Node::Rule::Sub
130
+ if r.to == :upcase
131
+ @str = @str.gsub(Regexp.new(build_regexp(r)), &:upcase)
132
+ else
133
+ @str = @str.gsub(Regexp.new(build_regexp(r)), build_item(r.to, :str))
134
+ end
135
+ when Interscript::Node::Rule::Funcall
136
+ @str = Interscript::Stdlib::Functions.public_send(r.name, @str, **r.kwargs)
137
+ when Interscript::Node::Rule::Run
138
+ if r.stage.map
139
+ doc = @map.dep_aliases[r.stage.map].document
140
+ stage = doc.imported_stages[r.stage.name]
141
+ @str = Stage.new(doc, @str).execute_rule(stage)
142
+ else
143
+ stage = @map.imported_stages[r.stage.name]
144
+ @str = Stage.new(@map, @str).execute_rule(stage)
145
+ end
146
+ end
147
+
148
+ @str
149
+ end
150
+
151
+ def build_regexp(r)
152
+ from = build_item(r.from, :re)
153
+ before = build_item(r.before, :re) if r.before
154
+ after = build_item(r.after, :re) if r.after
155
+ not_before = build_item(r.not_before, :re) if r.not_before
156
+ not_after = build_item(r.not_after, :re) if r.not_after
157
+
158
+ re = ""
159
+ re += "(?<=#{before})" if before
160
+ re += "(?<!#{not_before})" if not_before
161
+ re += from
162
+ re += "(?!#{not_after})" if not_after
163
+ re += "(?=#{after})" if after
164
+ re
165
+ end
166
+
167
+ def build_item i, target=nil, doc=@map
168
+ i = i.nth_string if %i[str parstr].include? target
169
+ i = Interscript::Node::Item.try_convert(i)
170
+ target = :par if target == :parstr
171
+
172
+ out = case i
173
+ when Interscript::Node::Item::Alias
174
+ if i.map
175
+ d = doc.dep_aliases[i.map].document
176
+ a = d.imported_aliases[i.name]
177
+ raise ArgumentError, "Alias #{i.name} of #{i.stage.map} not found" unless a
178
+ build_item(a.data, target, d)
179
+ elsif Interscript::Stdlib::ALIASES.include?(i.name)
180
+ if target != :re && Interscript::Stdlib.re_only_alias?(i.name)
181
+ raise ArgumentError, "Can't use #{i.name} in a #{target} context"
182
+ end
183
+ Interscript::Stdlib::ALIASES[i.name]
184
+ else
185
+ a = doc.imported_aliases[i.name]
186
+ raise ArgumentError, "Alias #{i.name} not found" unless a
187
+ build_item(a.data, target, doc)
188
+ end
189
+ when Interscript::Node::Item::String
190
+ if [:str, :par].include? target
191
+ i.data
192
+ else#if target == :re
193
+ Regexp.escape(i.data)
194
+ end
195
+ when Interscript::Node::Item::Group
196
+ if target == :par
197
+ i.children.map do |j|
198
+ build_item(j, target, doc)
199
+ end.reduce([""]) do |j,k|
200
+ Array(j).product(Array(k)).map(&:join)
201
+ end
202
+ else
203
+ i.children.map { |j| build_item(j, target, doc) }.join
204
+ end
205
+ when Interscript::Node::Item::CaptureGroup
206
+ if target == :par
207
+ raise ArgumentError, "Can't use a CaptureGroup in a #{target} context"
208
+ end
209
+ "(" + build_item(i.data, target, doc) + ")"
210
+ when Interscript::Node::Item::Maybe,
211
+ Interscript::Node::Item::MaybeSome,
212
+ Interscript::Node::Item::Some
213
+
214
+ resuffix = { Interscript::Node::Item::Maybe => "?" ,
215
+ Interscript::Node::Item::Some => "+" ,
216
+ Interscript::Node::Item::MaybeSome => "*" }[i.class]
217
+
218
+ if target == :par
219
+ raise ArgumentError, "Can't use a MaybeSome in a #{target} context"
220
+ end
221
+ if Interscript::Node::Item::String === i.data && i.data.data.length != 1
222
+ "(?:" + build_item(i.data, target, doc) + ")" + resuffix
223
+ else
224
+ build_item(i.data, target, doc) + resuffix
225
+ end
226
+ when Interscript::Node::Item::CaptureRef
227
+ if target == :par
228
+ raise ArgumentError, "Can't use CaptureRef in parallel mode"
229
+ end
230
+ "\\#{i.id}"
231
+ when Interscript::Node::Item::Any
232
+ if target == :str
233
+ # We may never reach this point
234
+ raise ArgumentError, "Can't use Any in a string context"
235
+ elsif target == :par
236
+ i.data.map(&:data)
237
+ elsif target == :re
238
+ case i.value
239
+ when Array
240
+ data = i.data.map { |j| build_item(j, target, doc) }
241
+ "(?:"+data.join("|")+")"
242
+ when String
243
+ "[#{Regexp.escape(i.value)}]"
244
+ when Range
245
+ "[#{Regexp.escape(i.value.first)}-#{Regexp.escape(i.value.last)}]"
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
@@ -0,0 +1,25 @@
1
+
2
+ class Interscript::Node
3
+ def initialize
4
+ raise NotImplementedError, "You can't construct a Node directly"
5
+ end
6
+
7
+ def to_hash
8
+ { :class => self.class.to_s,
9
+ :question => "is something missing?"
10
+ }
11
+ end
12
+ end
13
+
14
+
15
+ require "interscript/node/group"
16
+ require "interscript/node/document"
17
+
18
+ require "interscript/node/metadata"
19
+ require 'interscript/node/alias_def'
20
+ require 'interscript/node/dependency'
21
+ require 'interscript/node/tests'
22
+
23
+ require "interscript/node/stage"
24
+ require "interscript/node/rule"
25
+ require "interscript/node/item"
@@ -0,0 +1,15 @@
1
+ class Interscript::Node::AliasDef < Interscript::Node
2
+ attr_accessor :name, :data, :doc_name
3
+
4
+ def initialize(name, data)
5
+ data = Interscript::Node::Item.try_convert(data)
6
+ @name = name
7
+ @data = data
8
+ end
9
+
10
+ def to_hash
11
+ { :class => self.class.to_s,
12
+ :name => @name,
13
+ :data => @data.to_hash }
14
+ end
15
+ end