parsanol 1.3.56-arm-linux → 1.3.57-arm-linux

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/exe/parsanol +7 -0
  3. data/lib/parsanol/3.2/parsanol_native.so +0 -0
  4. data/lib/parsanol/3.3/parsanol_native.so +0 -0
  5. data/lib/parsanol/3.4/parsanol_native.so +0 -0
  6. data/lib/parsanol/4.0/parsanol_native.so +0 -0
  7. data/lib/parsanol/native/libparsanol.so +0 -0
  8. data/lib/parsanol/native/serializer.rb +5 -2
  9. data/lib/parsanol/parg/artifact.rb +213 -0
  10. data/lib/parsanol/parg/authoring.rb +110 -0
  11. data/lib/parsanol/parg/bindings.rb +129 -0
  12. data/lib/parsanol/parg/cli.rb +251 -0
  13. data/lib/parsanol/parg/compiler.rb +465 -0
  14. data/lib/parsanol/parg/derive.rb +28 -0
  15. data/lib/parsanol/parg/document.rb +69 -0
  16. data/lib/parsanol/parg/error.rb +18 -0
  17. data/lib/parsanol/parg/frontend.rb +173 -0
  18. data/lib/parsanol/parg/import.rb +34 -0
  19. data/lib/parsanol/parg/importers/abnf.rb +299 -0
  20. data/lib/parsanol/parg/importers/ebnf.rb +201 -0
  21. data/lib/parsanol/parg/importers/pest.rb +314 -0
  22. data/lib/parsanol/parg/imports.rb +87 -0
  23. data/lib/parsanol/parg/lexer.rb +72 -0
  24. data/lib/parsanol/parg/lints.rb +171 -0
  25. data/lib/parsanol/parg/lsp.rb +208 -0
  26. data/lib/parsanol/parg/lutaml.rb +67 -0
  27. data/lib/parsanol/parg/node.rb +20 -0
  28. data/lib/parsanol/parg/parser.rb +458 -0
  29. data/lib/parsanol/parg/preprocess.rb +36 -0
  30. data/lib/parsanol/parg/render.rb +44 -0
  31. data/lib/parsanol/parg/selfhost.rb +49 -0
  32. data/lib/parsanol/parg/visitor.rb +64 -0
  33. data/lib/parsanol/parg.rb +38 -0
  34. data/lib/parsanol/version.rb +1 -1
  35. data/lib/parsanol/vm.rb +7 -5
  36. data/lib/parsanol.rb +3 -0
  37. data/parsanol.gemspec +3 -1
  38. metadata +31 -4
@@ -0,0 +1,458 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ module PARG
5
+ # Recursive-descent parser for PARG source text.
6
+ #
7
+ # grammar PubidIso version "1.2.0" {
8
+ # digit = %x30-39
9
+ # year = 4digit
10
+ # root = %i"iso" [dash number as part]
11
+ # }
12
+ #
13
+ # Keywords: grammar version as alt from_table column bindings
14
+ # preprocess entry table_lookup
15
+ class Parser
16
+ PATH_CONTINUATION = [".", "["].freeze
17
+ CARD_CONTINUATION = [".", "*"].freeze
18
+
19
+ IN_BLOCK_SECTIONS = %w[entry bindings preprocess test].freeze
20
+
21
+ KEYWORDS = %w[grammar as alt from_table column bindings render derive
22
+ preprocess entry table_lookup].freeze
23
+
24
+ def initialize(text)
25
+ @tokens = Lexer.new(text).tokens
26
+ @pos = 0
27
+ @source_text = text
28
+ end
29
+
30
+ def parse
31
+ document = Document.new
32
+ document.source = @source_text
33
+ skip_newlines
34
+ until eof?
35
+ take_doc_comments
36
+ break if eof?
37
+
38
+ section = expect(:ident)
39
+ case section.value
40
+ when "use" then document.uses << ident.value
41
+ when "grammar" then parse_grammar(document)
42
+ when "entry" then parse_entry(document)
43
+ when "bindings" then parse_bindings(document)
44
+ when "preprocess" then parse_preprocess(document)
45
+ when "render" then parse_render(document)
46
+ when "derive" then parse_derive(document)
47
+ when "test" then parse_test(document)
48
+ else
49
+ raise ParseError,
50
+ "expected a section (grammar/entry/bindings/preprocess/test), " \
51
+ "got #{section.value.inspect} at offset #{section.offset}"
52
+ end
53
+ skip_newlines
54
+ end
55
+ document.validate!
56
+ document.own_entries = document.entries.keys
57
+ document
58
+ end
59
+
60
+ private
61
+
62
+ def skip_newlines
63
+ advance while peek&.type == :newline
64
+ end
65
+
66
+ # Doc comments (##) accumulate and attach to the next rule.
67
+ def take_doc_comments
68
+ docs = []
69
+ while peek&.type == :doc
70
+ docs << advance.value[2..].strip
71
+ skip_newlines
72
+ end
73
+ docs
74
+ end
75
+
76
+ def parse_test(document, default_entry: nil)
77
+ entry = peek&.type == :ident && peek.value != "{" ? advance.value : default_entry
78
+ punct("{")
79
+ skip_newlines
80
+ until peek&.type == :punct && peek.value == "}"
81
+ kind = ident.value
82
+ input = unquote(expect(:str).value)
83
+ expect_pairs = {}
84
+ if kind == "example" && peek&.type == :punct && peek.value == "{"
85
+ advance
86
+ skip_newlines
87
+ until peek&.type == :punct && peek.value == "}"
88
+ key = ident.value
89
+ punct(":")
90
+ expect_pairs[key.to_sym] = parse_test_value
91
+ skip_newlines
92
+ end
93
+ punct("}")
94
+ end
95
+ document.tests << Document::Test.new(entry, kind.to_sym, input, expect_pairs)
96
+ skip_newlines
97
+ end
98
+ punct("}")
99
+ skip_newlines
100
+ end
101
+
102
+ def parse_test_value
103
+ token = advance
104
+ case token&.type
105
+ when :str then unquote(token.value)
106
+ when :num then token.value.to_i
107
+ when :ident
108
+ raise ParseError, "expected true or false" unless %w[true false].include?(token.value)
109
+
110
+ token.value == "true"
111
+ else
112
+ raise ParseError, "expected a string, number, true or false"
113
+ end
114
+ end
115
+
116
+ def eof? = @pos >= @tokens.length
117
+
118
+ def peek = @tokens[@pos]
119
+
120
+ def advance
121
+ token = @tokens[@pos]
122
+ @pos += 1
123
+ token
124
+ end
125
+
126
+ def expect(type, value = nil)
127
+ token = advance
128
+ if token.nil? || token.type != type || (value && token.value != value)
129
+ found = token ? "#{token.type}:#{token.value.inspect}" : "EOF"
130
+ raise ParseError,
131
+ "expected #{value ? value.inspect : type}, got #{found}"
132
+ end
133
+ token
134
+ end
135
+
136
+ def ident(value = nil) = expect(:ident, value)
137
+
138
+ def punct(char) = expect(:punct, char)
139
+
140
+ def parse_grammar(document)
141
+ document.grammar_name = ident.value
142
+ ident("version")
143
+ document.version = unquote(expect(:str).value)
144
+ punct("{")
145
+ skip_newlines
146
+ until peek&.type == :punct && peek.value == "}"
147
+ docs = take_doc_comments
148
+ break if peek.nil? || (peek&.type == :punct && peek.value == "}")
149
+
150
+ # Sections may be authored inside the grammar block: the
151
+ # natural placement for entry/bindings/preprocess/test.
152
+ if peek&.type == :ident && IN_BLOCK_SECTIONS.include?(peek.value)
153
+ section = advance
154
+ case section.value
155
+ when "entry" then parse_entry(document)
156
+ when "bindings" then parse_bindings(document)
157
+ when "preprocess" then parse_preprocess(document)
158
+ when "test" then parse_test(document)
159
+ end
160
+ skip_newlines
161
+ next
162
+ end
163
+ name = rule_name
164
+ document.docs[name] = docs.join("\n") unless docs.empty?
165
+ punct("=")
166
+ node = parse_choice
167
+ if document.rules.key?(name)
168
+ raise ParseError, "duplicate rule #{name.inspect}"
169
+ end
170
+
171
+ document.rules[name] = node
172
+ skip_newlines
173
+ end
174
+ punct("}")
175
+ end
176
+
177
+ def rule_name
178
+ token = ident
179
+ if KEYWORDS.include?(token.value)
180
+ raise ParseError,
181
+ "#{token.value.inspect} is a keyword and cannot name a rule"
182
+ end
183
+ token.value
184
+ end
185
+
186
+ def parse_choice
187
+ branches = [parse_seq]
188
+ while peek&.type == :punct && peek.value == "/"
189
+ advance
190
+ branches << parse_seq
191
+ end
192
+ branches.length == 1 ? branches.first : Node.new(:alt, branches)
193
+ end
194
+
195
+ def parse_seq
196
+ items = [parse_element]
197
+ until stop_element?
198
+ items << parse_element
199
+ end
200
+ items.length == 1 ? items.first : Node.new(:seq, items)
201
+ end
202
+
203
+ def stop_element?
204
+ peek.nil? || peek.type == :newline ||
205
+ (peek.type == :punct && ["/", ")", "]", "}"].include?(peek.value))
206
+ end
207
+
208
+ def parse_element
209
+ token = peek
210
+ if token.nil?
211
+ raise ParseError, "unexpected end of input inside sequence"
212
+ end
213
+
214
+ if token.type == :num
215
+ advance
216
+ min = token.value.to_i
217
+ if peek&.type == :punct && peek.value == "*"
218
+ advance
219
+ max = peek&.type == :num ? advance.value.to_i : nil
220
+ node = Node.new(:rep, parse_postfixed, min, max)
221
+ else
222
+ node = Node.new(:rep, parse_postfixed, min, min)
223
+ end
224
+ return node
225
+ elsif token.type == :punct && token.value == "*"
226
+ advance
227
+ max = peek&.type == :num ? advance.value.to_i : nil
228
+ return Node.new(:rep, parse_postfixed, 0, max)
229
+ end
230
+ parse_postfixed
231
+ end
232
+
233
+ def parse_postfixed
234
+ sign = nil
235
+ if peek&.type == :punct && %w[! &].include?(peek.value)
236
+ sign = advance.value == "&"
237
+ end
238
+ node = parse_primary
239
+ if peek&.type == :ident && peek.value == "as"
240
+ advance
241
+ node = Node.new(:cap, ident.value, node)
242
+ end
243
+ sign.nil? ? node : Node.new(:pred, sign, node)
244
+ end
245
+
246
+ def parse_primary
247
+ token = advance
248
+ raise ParseError, "unexpected end of input" if token.nil?
249
+
250
+ case token.type
251
+ when :str, :sstr then Node.new(:lit, unquote(token.value), false)
252
+ when :istr then Node.new(:lit, unquote(token.value), true)
253
+ when :hex then parse_hex(token.value)
254
+ when :punct then parse_punctuated(token)
255
+ when :ident then parse_ident(token)
256
+ else raise ParseError, "unexpected token #{token.type}:#{token.value}"
257
+ end
258
+ end
259
+
260
+ def parse_punctuated(token)
261
+ case token.value
262
+ when "("
263
+ node = parse_choice
264
+ punct(")")
265
+ node
266
+ when "["
267
+ node = parse_choice
268
+ punct("]")
269
+ Node.new(:opt, node)
270
+ else
271
+ raise ParseError, "unexpected #{token.value.inspect} in expression"
272
+ end
273
+ end
274
+
275
+ def parse_ident(token)
276
+ case token.value
277
+ when "alt"
278
+ ident("from_table")
279
+ table = unquote(expect(:str).value)
280
+ ident("column")
281
+ column = unquote(expect(:str).value)
282
+ Node.new(:table, table, column)
283
+ when *KEYWORDS
284
+ raise ParseError,
285
+ "#{token.value.inspect} is a keyword and cannot be referenced"
286
+ else
287
+ name = token.value
288
+ # Dotted cross-grammar references: `use cen_cenelec` makes
289
+ # cen_cenelec.identifier addressable.
290
+ while peek&.type == :punct && peek.value == "." &&
291
+ @tokens[@pos + 1]&.type == :ident
292
+ advance
293
+ name = "#{name}.#{advance.value}"
294
+ end
295
+ Node.new(:ref, name)
296
+ end
297
+ end
298
+
299
+ def parse_hex(spec)
300
+ if spec.include?("-")
301
+ lo, hi = spec.split("-")
302
+ Node.new(:class, [[lo.to_i(16), hi.to_i(16)]])
303
+ elsif spec.include?(".")
304
+ parts = spec.split(".").map { |h| Node.new(:class, [[h.to_i(16), h.to_i(16)]]) }
305
+ parts.length == 1 ? parts.first : Node.new(:seq, parts)
306
+ else
307
+ byte = spec.to_i(16)
308
+ Node.new(:class, [[byte, byte]])
309
+ end
310
+ end
311
+
312
+ def parse_entry(document)
313
+ name = ident.value
314
+ punct(":")
315
+ document.entries[name] = rule_name
316
+ end
317
+
318
+ def parse_bindings(document)
319
+ rule = ident.value
320
+ punct("{")
321
+ list = document.bindings[rule] ||= []
322
+ skip_newlines
323
+ until peek&.type == :punct && peek.value == "}"
324
+ capture = ident.value
325
+ expect(:arrow)
326
+ path = parse_path
327
+ type = "string"
328
+ card = nil
329
+ preprocess = nil
330
+ if peek&.type == :punct && peek.value == "("
331
+ advance
332
+ type = ident.value
333
+ if peek&.type == :punct && peek.value == ","
334
+ advance
335
+ card = parse_card
336
+ end
337
+ punct(")")
338
+ end
339
+ if peek&.type == :ident && peek.value == "preprocess"
340
+ advance
341
+ punct(":")
342
+ preprocess = ident.value
343
+ end
344
+ list << Document::Binding.new(capture, path, type, card, preprocess)
345
+ skip_newlines
346
+ end
347
+ punct("}")
348
+ end
349
+
350
+ def parse_path
351
+ parts = [ident.value]
352
+ loop do
353
+ token = peek
354
+ break unless token&.type == :punct && PATH_CONTINUATION.include?(token.value)
355
+
356
+ advance
357
+ if token.value == "."
358
+ parts << ".#{ident.value}"
359
+ else
360
+ punct("]")
361
+ parts << "[]"
362
+ end
363
+ end
364
+ parts.join
365
+ end
366
+
367
+ def parse_card
368
+ pieces = []
369
+ loop do
370
+ token = peek
371
+ break unless token&.type == :num ||
372
+ (token&.type == :punct && CARD_CONTINUATION.include?(token.value))
373
+
374
+ pieces << advance.value
375
+ end
376
+ pieces.join
377
+ end
378
+
379
+ # F6 v1: render specs as data - named variants of ordered segments.
380
+ # Segments: field <path>, literal "<text>", cond <path> { segs }.
381
+ # Conditions are field-presence only; expressions disallowed, so the
382
+ # graduation to an output grammar stays mechanical.
383
+ # F6 v1: derive specs - named field-composition templates
384
+ # ("urn:{publisher}:{number}"); {field} interpolates from the bound
385
+ # map. Tier-1 data, language-neutral by construction.
386
+ def parse_derive(document)
387
+ name = ident.value
388
+ template = unquote(expect(:str).value)
389
+ document.derive[name] = template
390
+ end
391
+
392
+ def parse_render(document)
393
+ variant = ident.value
394
+ punct("{")
395
+ segments = document.render[variant] ||= []
396
+ skip_newlines
397
+ until peek&.type == :punct && peek.value == "}"
398
+ segments << parse_render_segment(document)
399
+ skip_newlines
400
+ end
401
+ punct("}")
402
+ end
403
+
404
+ def parse_render_segment(document)
405
+ case (word = ident.value)
406
+ when "field"
407
+ { "type" => "field", "field" => ident.value }
408
+ when "literal"
409
+ { "type" => "literal", "text" => unquote(expect(:str).value) }
410
+ when "cond"
411
+ field = ident.value
412
+ punct("{")
413
+ then_segments = []
414
+ skip_newlines
415
+ until peek&.type == :punct && peek.value == "}"
416
+ then_segments << parse_render_segment(document)
417
+ skip_newlines
418
+ end
419
+ punct("}")
420
+ { "type" => "cond", "field" => field, "then" => then_segments }
421
+ else
422
+ raise ParseError,
423
+ "expected a render segment (field/literal/cond), got #{word.inspect}"
424
+ end
425
+ end
426
+
427
+ def parse_preprocess(document)
428
+ name = ident.value
429
+ punct("{")
430
+ steps = document.preprocess[name] ||= []
431
+ skip_newlines
432
+ until peek&.type == :punct && peek.value == "}"
433
+ op = ident("table_lookup").value
434
+ table = ident.value
435
+ from = ident.value
436
+ expect(:arrow)
437
+ to = ident.value
438
+ steps << { "op" => op, "table" => table, "from" => from, "to" => to }
439
+ skip_newlines
440
+ end
441
+ punct("}")
442
+ end
443
+
444
+ def unquote(raw)
445
+ body = raw.start_with?("%") ? raw[2..] : raw
446
+ body = body[1..-2]
447
+ body.gsub(/\\(.)/) do
448
+ case Regexp.last_match(1)
449
+ when "n" then "\n"
450
+ when "t" then "\t"
451
+ when "r" then "\r"
452
+ else Regexp.last_match(1)
453
+ end
454
+ end
455
+ end
456
+ end
457
+ end
458
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ module PARG
5
+ # Registry of preprocessing operations (OCP): deterministic, data-only
6
+ # transformations applied between capture collection and type cast.
7
+ # New ops register here — neither Bindings nor the compiler changes.
8
+ # Non-deterministic rules are NOT registrable: they belong to the
9
+ # language-specific data-model ingestion end (PN 5).
10
+ module Preprocess
11
+ class << self
12
+ def register(name, &operation)
13
+ operations[name.to_sym] = operation
14
+ end
15
+
16
+ def apply(step, value, source)
17
+ operation = operations.fetch(step["op"].to_sym) do
18
+ raise ArtifactError, "unknown preprocess op #{step['op'].inspect}"
19
+ end
20
+ operation.call(step, value, source)
21
+ end
22
+
23
+ def operations
24
+ @operations ||= {}
25
+ end
26
+ end
27
+
28
+ register :table_lookup do |step, value, source|
29
+ map = source.table_rows(step["table"]).to_h do |row|
30
+ [row[step["from"]].to_s, row[step["to"]]]
31
+ end
32
+ map[value.to_s] || value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ module PARG
5
+ # F6 v1: generic renderer over the artifact's render spec — ordered
6
+ # segments (field / literal / cond-presence) evaluated against a bound
7
+ # attribute map. The spec lives under the artifact checksum, so every
8
+ # engine renders byte-identical strings by construction.
9
+ module Render
10
+ module_function
11
+
12
+ def apply(render, variant, bound)
13
+ segments = render.fetch(variant) do
14
+ raise ArtifactError, "render variant #{variant.inspect} not declared"
15
+ end
16
+ render_segments(segments, bound)
17
+ end
18
+
19
+ def render_segments(segments, bound)
20
+ segments.filter_map { |segment| render_segment(segment, bound) }.join
21
+ end
22
+
23
+ # Bindings produces symbol keys in-process; the JSON contract (and
24
+ # the other engines) use strings — accept both.
25
+ def lookup(bound, field)
26
+ bound[field.to_s] || bound[field.to_sym]
27
+ end
28
+
29
+ def render_segment(segment, bound)
30
+ case segment["type"]
31
+ when "field" then lookup(bound, segment["field"]).to_s
32
+ when "literal" then segment["text"].to_s
33
+ when "cond"
34
+ value = lookup(bound, segment["field"])
35
+ return "" if value.nil?
36
+
37
+ render_segments(segment["then"], bound)
38
+ else
39
+ raise ArtifactError, "unknown render segment #{segment['type'].inspect}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ module PARG
5
+ # F10 phase 2 (gate slice): every .parg source must parse under the parg
6
+ # artifact — the language definition validates itself and every
7
+ # grammar written in it. The artifact is authoritative for document
8
+ # structure; the full shape->IR front end builds on this gate.
9
+ module SelfHost
10
+ module_function
11
+
12
+ def artifact_path
13
+ ENV["PG_ARTIFACT"] || begin
14
+ dir = __dir__
15
+ ancestors = []
16
+ cursor = dir
17
+ 6.times do
18
+ cursor = File.expand_path("..", cursor)
19
+ ancestors << File.join(cursor, "pubid", "pubid-grammar", "artifacts", "parg.json")
20
+ end
21
+ ancestors.find { |candidate| File.file?(candidate) }
22
+ end
23
+ end
24
+
25
+ def available?
26
+ !artifact_path.nil?
27
+ end
28
+
29
+ # Parse `source` under the parg artifact. Returns the shape tree, or
30
+ # raises ParseFailed with the native position when the source is not
31
+ # valid PARG as defined by the self-hosting grammar.
32
+ def validate(source)
33
+ raise ArtifactError, "parg artifact not found (set PG_ARTIFACT)" unless available?
34
+
35
+ envelope = JSON.parse(File.read(artifact_path))
36
+ artifact = Artifact.new(envelope, nil, nil)
37
+ artifact.parse("file", source)
38
+ end
39
+
40
+ # true when the source parses under the self-hosting artifact.
41
+ def valid?(source)
42
+ validate(source)
43
+ true
44
+ rescue Parsanol::ParseFailed, ArtifactError
45
+ false
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ module PARG
5
+ # Visitor over the PARG IR (OCP): transformations and analyses walk the
6
+ # tree through #visit instead of hand-rolled case statements.
7
+ class Visitor
8
+ CHILDREN = {
9
+ lit: [], class: [], re: [], ref: [],
10
+ seq: :a, alt: :a, rep: %i[a], opt: %i[a], pred: %i[b], cap: %i[b],
11
+ table: []
12
+ }.freeze
13
+
14
+ def initialize(node)
15
+ @node = node
16
+ end
17
+
18
+ # Yields every node (self first, depth-first).
19
+ def each(&block)
20
+ walk(@node, block)
21
+ end
22
+
23
+ def map
24
+ rewrite(@node)
25
+ end
26
+
27
+ private
28
+
29
+ def walk(node, block)
30
+ return unless node.is_a?(Node)
31
+
32
+ block.call(node)
33
+ child_nodes(node).each { |child| walk(child, block) }
34
+ end
35
+
36
+ def child_nodes(node)
37
+ case CHILDREN[node.kind]
38
+ when :a then node.a
39
+ when Array then node.a.map { |sym| node.public_send(sym) }
40
+ else []
41
+ end
42
+ end
43
+
44
+ # Rebuilds the tree: the block returns a replacement node or nil to
45
+ # keep the original; children are rewritten first (bottom-up).
46
+ def rewrite(node)
47
+ return node unless node.is_a?(Node)
48
+
49
+ case node.kind
50
+ when :seq, :alt
51
+ node.class.new(node.a.map { |child| rewrite(child) })
52
+ when :rep
53
+ Node.new(node.kind, rewrite(node.a), node.b, node.c)
54
+ when :opt
55
+ Node.new(node.kind, rewrite(node.a))
56
+ when :pred, :cap
57
+ Node.new(node.kind, node.a, rewrite(node.b))
58
+ else
59
+ yield(node) || node
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Parsanol
4
+ # PARG — the parsanol grammar language.
5
+ #
6
+ # A text source format for parsanol grammars: human-readable, ABNF/RFC
7
+ # flavoured, PEG semantics (ordered choice). PARG sources compile to a
8
+ # checksummed artifact envelope whose grammar section is the same portable
9
+ # JSON the native engines register — the text is the contract, the JSON is
10
+ # its compiled form.
11
+ module PARG
12
+ autoload :Error, "parsanol/parg/error"
13
+ autoload :ParseError, "parsanol/parg/error"
14
+ autoload :CompileError, "parsanol/parg/error"
15
+ autoload :ArtifactError, "parsanol/parg/error"
16
+ autoload :Node, "parsanol/parg/node"
17
+ autoload :Lexer, "parsanol/parg/lexer"
18
+ autoload :Parser, "parsanol/parg/parser"
19
+ autoload :Document, "parsanol/parg/document"
20
+ autoload :Compiler, "parsanol/parg/compiler"
21
+ autoload :Artifact, "parsanol/parg/artifact"
22
+ autoload :Bindings, "parsanol/parg/bindings"
23
+ autoload :Render, "parsanol/parg/render"
24
+ autoload :Derive, "parsanol/parg/derive"
25
+ autoload :SelfHost, "parsanol/parg/selfhost"
26
+ autoload :Frontend, "parsanol/parg/frontend"
27
+ autoload :Lutaml, "parsanol/parg/lutaml"
28
+ autoload :Import, "parsanol/parg/import"
29
+ autoload :CLI, "parsanol/parg/cli"
30
+ autoload :Lsp, "parsanol/parg/lsp"
31
+ autoload :Lints, "parsanol/parg/lints"
32
+ autoload :Preprocess, "parsanol/parg/preprocess"
33
+ autoload :Visitor, "parsanol/parg/visitor"
34
+ autoload :Imports, "parsanol/parg/imports"
35
+ autoload :Suite, "parsanol/parg/authoring"
36
+ autoload :Schema, "parsanol/parg/authoring"
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parsanol
4
- VERSION = "1.3.56"
4
+ VERSION = "1.3.57"
5
5
  end