tediparse 2.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 +7 -0
- data/CHANGELOG.md +319 -0
- data/LICENSE +26 -0
- data/README.md +308 -0
- data/Rakefile +33 -0
- data/bin/tediparse +102 -0
- data/doc/Defining.md +97 -0
- data/doc/Generating-Grammars.md +241 -0
- data/doc/Generating.md +332 -0
- data/doc/Navigating.md +670 -0
- data/doc/Parsing.md +133 -0
- data/doc/README.md +51 -0
- data/doc/Serializing.md +100 -0
- data/doc/Tokenizing.md +136 -0
- data/doc/Validating.md +140 -0
- data/lib/ruby/array.rb +226 -0
- data/lib/ruby/blank.rb +52 -0
- data/lib/ruby/exception.rb +14 -0
- data/lib/ruby/hash.rb +14 -0
- data/lib/ruby/module.rb +60 -0
- data/lib/ruby/object.rb +56 -0
- data/lib/ruby/string.rb +89 -0
- data/lib/ruby/to_d.rb +82 -0
- data/lib/ruby/to_date.rb +26 -0
- data/lib/ruby/to_time.rb +21 -0
- data/lib/ruby/try.rb +46 -0
- data/lib/stupidedi/builder.rb +6 -0
- data/lib/stupidedi/color.rb +94 -0
- data/lib/stupidedi/config/code_list_config.rb +45 -0
- data/lib/stupidedi/config/functional_group_config.rb +72 -0
- data/lib/stupidedi/config/interchange_config.rb +86 -0
- data/lib/stupidedi/config/transaction_set_config.rb +73 -0
- data/lib/stupidedi/config.rb +100 -0
- data/lib/stupidedi/either.rb +286 -0
- data/lib/stupidedi/exceptions/invalid_element_error.rb +7 -0
- data/lib/stupidedi/exceptions/invalid_schema_error.rb +7 -0
- data/lib/stupidedi/exceptions/missing_grammar_error.rb +50 -0
- data/lib/stupidedi/exceptions/output_error.rb +7 -0
- data/lib/stupidedi/exceptions/parse_error.rb +7 -0
- data/lib/stupidedi/exceptions/stupidedi_error.rb +7 -0
- data/lib/stupidedi/exceptions/tokenize_error.rb +7 -0
- data/lib/stupidedi/exceptions/zipper_error.rb +7 -0
- data/lib/stupidedi/exceptions.rb +13 -0
- data/lib/stupidedi/inspect.rb +26 -0
- data/lib/stupidedi/interchanges/element_types/separator_val.rb +79 -0
- data/lib/stupidedi/interchanges/element_types/special_val.rb +48 -0
- data/lib/stupidedi/interchanges/element_types.rb +11 -0
- data/lib/stupidedi/interchanges.rb +21 -0
- data/lib/stupidedi/parser/builder_dsl.rb +292 -0
- data/lib/stupidedi/parser/constraint_table.rb +566 -0
- data/lib/stupidedi/parser/generation.rb +147 -0
- data/lib/stupidedi/parser/identifier_stack.rb +248 -0
- data/lib/stupidedi/parser/instruction.rb +112 -0
- data/lib/stupidedi/parser/instruction_table.rb +222 -0
- data/lib/stupidedi/parser/navigation.rb +786 -0
- data/lib/stupidedi/parser/state_machine.rb +62 -0
- data/lib/stupidedi/parser/states/abstract_state.rb +385 -0
- data/lib/stupidedi/parser/states/failure_state.rb +69 -0
- data/lib/stupidedi/parser/states/functional_group_state.rb +101 -0
- data/lib/stupidedi/parser/states/initial_state.rb +62 -0
- data/lib/stupidedi/parser/states/interchange_state.rb +96 -0
- data/lib/stupidedi/parser/states/loop_state.rb +74 -0
- data/lib/stupidedi/parser/states/table_state.rb +90 -0
- data/lib/stupidedi/parser/states/transaction_set_state.rb +120 -0
- data/lib/stupidedi/parser/states/transmission_state.rb +59 -0
- data/lib/stupidedi/parser/tokenization.rb +195 -0
- data/lib/stupidedi/parser.rb +32 -0
- data/lib/stupidedi/reader/input/abstract_input.rb +137 -0
- data/lib/stupidedi/reader/input/delegated_input.rb +112 -0
- data/lib/stupidedi/reader/input/file_input.rb +157 -0
- data/lib/stupidedi/reader/input.rb +31 -0
- data/lib/stupidedi/reader/position.rb +78 -0
- data/lib/stupidedi/reader/result.rb +172 -0
- data/lib/stupidedi/reader/segment_dict.rb +176 -0
- data/lib/stupidedi/reader/separators.rb +90 -0
- data/lib/stupidedi/reader/stream_reader.rb +173 -0
- data/lib/stupidedi/reader/token_reader.rb +465 -0
- data/lib/stupidedi/reader/tokens/component_element_tok.rb +71 -0
- data/lib/stupidedi/reader/tokens/composite_element_tok.rb +85 -0
- data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +74 -0
- data/lib/stupidedi/reader/tokens/segment_tok.rb +74 -0
- data/lib/stupidedi/reader/tokens/simple_element_tok.rb +76 -0
- data/lib/stupidedi/reader.rb +121 -0
- data/lib/stupidedi/schema/abstract_def.rb +76 -0
- data/lib/stupidedi/schema/abstract_element_def.rb +35 -0
- data/lib/stupidedi/schema/abstract_element_use.rb +47 -0
- data/lib/stupidedi/schema/abstract_use.rb +79 -0
- data/lib/stupidedi/schema/code_list.rb +99 -0
- data/lib/stupidedi/schema/component_element_use.rb +76 -0
- data/lib/stupidedi/schema/composite_element_def.rb +103 -0
- data/lib/stupidedi/schema/composite_element_use.rb +78 -0
- data/lib/stupidedi/schema/element_req.rb +57 -0
- data/lib/stupidedi/schema/functional_group_def.rb +124 -0
- data/lib/stupidedi/schema/generation/definition_generator.rb +139 -0
- data/lib/stupidedi/schema/generation/element_generator.rb +221 -0
- data/lib/stupidedi/schema/generation/flat_file_reader.rb +551 -0
- data/lib/stupidedi/schema/generation/functional_group_generator.rb +64 -0
- data/lib/stupidedi/schema/generation/interchange_generator.rb +145 -0
- data/lib/stupidedi/schema/generation/master_loader_generator.rb +121 -0
- data/lib/stupidedi/schema/generation/models.rb +85 -0
- data/lib/stupidedi/schema/generation/module_loader_generator.rb +64 -0
- data/lib/stupidedi/schema/generation/registration_generator.rb +230 -0
- data/lib/stupidedi/schema/generation/runner.rb +161 -0
- data/lib/stupidedi/schema/generation/segment_generator.rb +130 -0
- data/lib/stupidedi/schema/generation/support.rb +78 -0
- data/lib/stupidedi/schema/generation/support_modules_generator.rb +126 -0
- data/lib/stupidedi/schema/generation/version_modules.rb +35 -0
- data/lib/stupidedi/schema/generation.rb +94 -0
- data/lib/stupidedi/schema/interchange_def.rb +103 -0
- data/lib/stupidedi/schema/loop_def.rb +156 -0
- data/lib/stupidedi/schema/repeat_count.rb +86 -0
- data/lib/stupidedi/schema/segment_def.rb +122 -0
- data/lib/stupidedi/schema/segment_req.rb +46 -0
- data/lib/stupidedi/schema/segment_use.rb +99 -0
- data/lib/stupidedi/schema/simple_element_def.rb +51 -0
- data/lib/stupidedi/schema/simple_element_use.rb +83 -0
- data/lib/stupidedi/schema/syntax_note.rb +52 -0
- data/lib/stupidedi/schema/table_def.rb +178 -0
- data/lib/stupidedi/schema/transaction_set_def.rb +125 -0
- data/lib/stupidedi/schema.rb +30 -0
- data/lib/stupidedi/sets.rb +42 -0
- data/lib/stupidedi/transaction_sets/builder/dsl.rb +192 -0
- data/lib/stupidedi/transaction_sets/builder.rb +188 -0
- data/lib/stupidedi/transaction_sets/common/implementations/element_reqs.rb +37 -0
- data/lib/stupidedi/transaction_sets/common/implementations/segment_reqs.rb +31 -0
- data/lib/stupidedi/transaction_sets/common/implementations.rb +11 -0
- data/lib/stupidedi/transaction_sets/common.rb +8 -0
- data/lib/stupidedi/transaction_sets/validation/ambiguity.rb +395 -0
- data/lib/stupidedi/transaction_sets/validation/implementation.rb +12 -0
- data/lib/stupidedi/transaction_sets/validation.rb +9 -0
- data/lib/stupidedi/transaction_sets.rb +25 -0
- data/lib/stupidedi/values/abstract_element_val.rb +19 -0
- data/lib/stupidedi/values/abstract_val.rb +133 -0
- data/lib/stupidedi/values/composite_element_val.rb +102 -0
- data/lib/stupidedi/values/functional_group_val.rb +105 -0
- data/lib/stupidedi/values/interchange_val.rb +102 -0
- data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
- data/lib/stupidedi/values/invalid_segment_val.rb +89 -0
- data/lib/stupidedi/values/loop_val.rb +73 -0
- data/lib/stupidedi/values/repeated_element_val.rb +113 -0
- data/lib/stupidedi/values/segment_val.rb +105 -0
- data/lib/stupidedi/values/segment_val_group.rb +20 -0
- data/lib/stupidedi/values/simple_element_val.rb +80 -0
- data/lib/stupidedi/values/table_val.rb +69 -0
- data/lib/stupidedi/values/transaction_set_val.rb +69 -0
- data/lib/stupidedi/values/transmission_val.rb +56 -0
- data/lib/stupidedi/values.rb +22 -0
- data/lib/stupidedi/version.rb +4 -0
- data/lib/stupidedi/versions/common/element_reqs.rb +13 -0
- data/lib/stupidedi/versions/common/element_types/an.rb +386 -0
- data/lib/stupidedi/versions/common/element_types/dt.rb +572 -0
- data/lib/stupidedi/versions/common/element_types/id.rb +304 -0
- data/lib/stupidedi/versions/common/element_types/nn.rb +312 -0
- data/lib/stupidedi/versions/common/element_types/operators.rb +128 -0
- data/lib/stupidedi/versions/common/element_types/r.rb +342 -0
- data/lib/stupidedi/versions/common/element_types/simple_element.rb +73 -0
- data/lib/stupidedi/versions/common/element_types/tm.rb +347 -0
- data/lib/stupidedi/versions/common/element_types.rb +29 -0
- data/lib/stupidedi/versions/common/segment_reqs.rb +15 -0
- data/lib/stupidedi/versions/common/syntax_notes.rb +172 -0
- data/lib/stupidedi/versions/common.rb +11 -0
- data/lib/stupidedi/versions.rb +25 -0
- data/lib/stupidedi/writer/claredi.rb +178 -0
- data/lib/stupidedi/writer/default.rb +119 -0
- data/lib/stupidedi/writer.rb +7 -0
- data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
- data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
- data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
- data/lib/stupidedi/zipper/memoized_cursor.rb +133 -0
- data/lib/stupidedi/zipper/path.rb +132 -0
- data/lib/stupidedi/zipper/root_cursor.rb +120 -0
- data/lib/stupidedi/zipper/stack_cursor.rb +107 -0
- data/lib/stupidedi/zipper.rb +45 -0
- data/lib/stupidedi.rb +69 -0
- data/lib/tediparse.rb +1 -0
- metadata +249 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module Stupidedi
|
|
3
|
+
using Refinements
|
|
4
|
+
|
|
5
|
+
module Parser
|
|
6
|
+
class BuilderDsl
|
|
7
|
+
include Inspect
|
|
8
|
+
include Tokenization
|
|
9
|
+
|
|
10
|
+
# @private
|
|
11
|
+
SEGMENT_ID = /^[A-Z][A-Z0-9]{1,2}$/
|
|
12
|
+
|
|
13
|
+
# @return [StateMachine]
|
|
14
|
+
attr_reader :machine
|
|
15
|
+
|
|
16
|
+
# @return [Boolean]
|
|
17
|
+
attr_writer :strict
|
|
18
|
+
|
|
19
|
+
# @return [DslReader]
|
|
20
|
+
attr_reader :reader
|
|
21
|
+
|
|
22
|
+
def_delegators :@machine, :pretty_print, :segment, :element, :zipper, :successors, :empty?, :first?, :last?, :deterministic?
|
|
23
|
+
|
|
24
|
+
def initialize(machine, strict = true)
|
|
25
|
+
@machine = machine
|
|
26
|
+
@strict = strict
|
|
27
|
+
@reader = DslReader.new(Reader::Separators.empty,
|
|
28
|
+
Reader::SegmentDict.empty)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def respond_to_missing?(name, include_private = false)
|
|
32
|
+
SEGMENT_ID =~ name.to_s || super
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def strict?
|
|
36
|
+
@strict
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [BuilderDsl]
|
|
40
|
+
def segment!(name, position, *elements)
|
|
41
|
+
segment_tok = mksegment_tok(@reader.segment_dict, name, elements, position)
|
|
42
|
+
machine, reader = @machine.insert(segment_tok, @strict, @reader)
|
|
43
|
+
|
|
44
|
+
if @strict
|
|
45
|
+
unless machine.deterministic?
|
|
46
|
+
matches = machine.active.map do |m|
|
|
47
|
+
segment_def = m.node.zipper.node.definition
|
|
48
|
+
"#{segment_def.id} #{segment_def.name}"
|
|
49
|
+
end.join(", ")
|
|
50
|
+
|
|
51
|
+
raise Exceptions::ParseError,
|
|
52
|
+
"non-deterministic machine state: #{matches}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Validate the new segment (recursively, including its children)
|
|
56
|
+
machine.active.each{|m| critique(m.node.zipper) }
|
|
57
|
+
|
|
58
|
+
# We want to detect when we've ended a syntax node (or more), like
|
|
59
|
+
# starting a new interchange will end all previously "open" syntax
|
|
60
|
+
# nodes. So we compare the state before adding `segment_tok` to the
|
|
61
|
+
# corresponding state after we've added `segment_tok`.
|
|
62
|
+
|
|
63
|
+
machine.prev.tap do |prev|
|
|
64
|
+
prev.active.zip(machine.active) do |p, q|
|
|
65
|
+
# If the new state `q` is a descendent of `p`, we know that `p`
|
|
66
|
+
# and all of its ancestors are unterminated. However, if `q` is
|
|
67
|
+
# not a descendent of `p`, but is a descendent of one of `p`s
|
|
68
|
+
# descendents, then `p` and perhaps some of its ancestors were
|
|
69
|
+
# terminated when the state transitioned to `q`.
|
|
70
|
+
qancestors = Set.new
|
|
71
|
+
|
|
72
|
+
# Operate on the syntax tree (instead of the state tree)
|
|
73
|
+
q = q.node.zipper
|
|
74
|
+
p = p.node.zipper
|
|
75
|
+
|
|
76
|
+
while q.respond_to?(:parent)
|
|
77
|
+
qancestors << q.parent
|
|
78
|
+
q = q.parent
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
while p.respond_to?(:parent)
|
|
82
|
+
break if qancestors.include?(p)
|
|
83
|
+
|
|
84
|
+
# Now that we're sure that this syntax node (loop, table, etc)
|
|
85
|
+
# is done being constructed, we can perform more validations.
|
|
86
|
+
critique(p)
|
|
87
|
+
p = p.parent
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
@machine = machine
|
|
94
|
+
@reader = reader
|
|
95
|
+
|
|
96
|
+
self
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def method_missing(name, *args)
|
|
102
|
+
if SEGMENT_ID =~ name.to_s
|
|
103
|
+
segment!(name, Reader::Position.caller(2), *args)
|
|
104
|
+
else
|
|
105
|
+
super
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# The `zipper` argument should be a _completed_ syntax node, meaning all
|
|
110
|
+
# children have already been added. This is invariably true for segments,
|
|
111
|
+
# because the {StateMachine} does not accept smaller units of syntax.
|
|
112
|
+
def critique(zipper, recursive = false, position = false)
|
|
113
|
+
if zipper.node.simple? or zipper.node.component?
|
|
114
|
+
if zipper.node.invalid?
|
|
115
|
+
raise Exceptions::ParseError,
|
|
116
|
+
"invalid #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
117
|
+
elsif zipper.node.blank?
|
|
118
|
+
if zipper.node.usage.required?
|
|
119
|
+
raise Exceptions::ParseError,
|
|
120
|
+
"required #{zipper.node.descriptor} is blank at #{zipper.node.position.inspect}"
|
|
121
|
+
end
|
|
122
|
+
elsif zipper.node.usage.forbidden?
|
|
123
|
+
raise Exceptions::ParseError,
|
|
124
|
+
"forbidden #{zipper.node.descriptor} is present at #{zipper.node.position.inspect}"
|
|
125
|
+
elsif not zipper.node.allowed?
|
|
126
|
+
raise Exceptions::ParseError,
|
|
127
|
+
"value #{zipper.node.to_s} is not allowed in #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
128
|
+
elsif zipper.node.too_long?
|
|
129
|
+
raise Exceptions::ParseError,
|
|
130
|
+
"value is too long in #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
131
|
+
elsif zipper.node.too_short?
|
|
132
|
+
raise Exceptions::ParseError,
|
|
133
|
+
"value is too short in #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
elsif zipper.node.composite?
|
|
137
|
+
if zipper.node.blank?
|
|
138
|
+
if zipper.node.usage.required?
|
|
139
|
+
# GH-194: Normally the position of a composit element is the
|
|
140
|
+
# position of it's first child; but an empty composit element
|
|
141
|
+
# doesn't have children. So the closest position is of the parent
|
|
142
|
+
raise Exceptions::ParseError,
|
|
143
|
+
"required #{zipper.node.descriptor} is blank at #{zipper.parent.node.position.inspect}"
|
|
144
|
+
end
|
|
145
|
+
elsif zipper.node.usage.forbidden?
|
|
146
|
+
raise Exceptions::ParseError,
|
|
147
|
+
"forbidden #{zipper.node.descriptor} is present at #{zipper.node.position.inspect}"
|
|
148
|
+
else
|
|
149
|
+
if zipper.node.present?
|
|
150
|
+
zipper.children.each_with_index do |z, i|
|
|
151
|
+
critique(z)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
d = zipper.node.definition
|
|
155
|
+
d.syntax_notes.each do |s|
|
|
156
|
+
unless s.satisfied?(zipper)
|
|
157
|
+
raise Exceptions::ParseError,
|
|
158
|
+
"for #{zipper.node.descriptor}, #{s.reason(zipper)} at #{zipper.node.position.inspect}"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
elsif zipper.node.repeated?
|
|
165
|
+
unless zipper.node.usage.repeat_count.include?(zipper.node.children.length)
|
|
166
|
+
raise Exceptions::ParseError,
|
|
167
|
+
"repeating #{zipper.node.descriptor} occurs too many times at #{zipper.node.position.inspect}"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
zipper.children.each{|z| critique(z) }
|
|
171
|
+
|
|
172
|
+
elsif zipper.node.segment?
|
|
173
|
+
if zipper.node.invalid?
|
|
174
|
+
if zipper.up.node.invalid?
|
|
175
|
+
# parent is an InvalidEnvelopeVal
|
|
176
|
+
raise Exceptions::ParseError,
|
|
177
|
+
"#{zipper.first.node.reason} at #{zipper.first.node.position.inspect}"
|
|
178
|
+
else
|
|
179
|
+
raise Exceptions::ParseError,
|
|
180
|
+
"#{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
181
|
+
end
|
|
182
|
+
else
|
|
183
|
+
zipper.children.each_with_index do |z, i|
|
|
184
|
+
critique(z)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
d = zipper.node.definition
|
|
188
|
+
d.syntax_notes.each do |s|
|
|
189
|
+
raise Exceptions::ParseError,
|
|
190
|
+
"for #{zipper.node.descriptor}, #{s.reason(zipper)} at #{zipper.node.position.inspect}" \
|
|
191
|
+
unless s.satisfied?(zipper)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
elsif zipper.node.loop?
|
|
196
|
+
critique_occurences zipper, recursive
|
|
197
|
+
|
|
198
|
+
elsif zipper.node.table?
|
|
199
|
+
critique_occurences zipper, recursive
|
|
200
|
+
|
|
201
|
+
elsif zipper.node.transaction_set?
|
|
202
|
+
critique_occurences zipper, recursive
|
|
203
|
+
|
|
204
|
+
elsif zipper.node.functional_group?
|
|
205
|
+
critique_occurences zipper, recursive
|
|
206
|
+
|
|
207
|
+
elsif zipper.node.interchange?
|
|
208
|
+
critique_occurences zipper, recursive
|
|
209
|
+
|
|
210
|
+
elsif zipper.node.transmission?
|
|
211
|
+
if recursive
|
|
212
|
+
zipper.children.each_with_index do |z, i|
|
|
213
|
+
critique(z, recursive)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def critique_occurences(zipper, recursive)
|
|
220
|
+
occurences = Hash.new{|h,k| h[k] = 0 }
|
|
221
|
+
|
|
222
|
+
zipper.children.each do |child|
|
|
223
|
+
if child.node.respond_to?(:usage)
|
|
224
|
+
occurences[child.node.usage] += 1
|
|
225
|
+
elsif child.node.invalid?
|
|
226
|
+
raise Exceptions::ParseError,
|
|
227
|
+
"#{child.node.descriptor} at #{child.node.position.inspect}"
|
|
228
|
+
else
|
|
229
|
+
occurences[child.node.definition] += 1
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
if recursive
|
|
233
|
+
critique(child, "", recursive)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
zipper.node.definition.children.each do |child|
|
|
238
|
+
bound = child.repeat_count
|
|
239
|
+
count = occurences.at(child)
|
|
240
|
+
|
|
241
|
+
if count.zero? and child.required?
|
|
242
|
+
raise Exceptions::ParseError,
|
|
243
|
+
"required #{child.descriptor} is missing from #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
244
|
+
elsif bound < count
|
|
245
|
+
raise Exceptions::ParseError,
|
|
246
|
+
"#{child.descriptor} occurs too many times in #{zipper.node.descriptor} at #{zipper.node.position.inspect}"
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# @endgroup
|
|
252
|
+
#########################################################################
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
class << BuilderDsl
|
|
256
|
+
# @group Constructors
|
|
257
|
+
#########################################################################
|
|
258
|
+
|
|
259
|
+
# @return [BuilderDsl]
|
|
260
|
+
def build(config, strict = true)
|
|
261
|
+
new(StateMachine.build(config), strict)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# @endgroup
|
|
265
|
+
#########################################################################
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# @private
|
|
269
|
+
class DslReader
|
|
270
|
+
# @return [Reader::Separators]
|
|
271
|
+
attr_reader :separators
|
|
272
|
+
|
|
273
|
+
# @return [Reader::SegmentDict]
|
|
274
|
+
attr_reader :segment_dict
|
|
275
|
+
|
|
276
|
+
def initialize(separators, segment_dict)
|
|
277
|
+
@separators, @segment_dict = separators, segment_dict
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# @return [DslReader]
|
|
281
|
+
def copy(changes = {})
|
|
282
|
+
@separators = changes.fetch(:separators, @separators)
|
|
283
|
+
@segment_dict = changes.fetch(:segment_dict, @segment_dict)
|
|
284
|
+
self
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def stream?
|
|
288
|
+
false
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|