parsanol 1.3.60 → 1.3.62
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/Cargo.lock +4 -4
- data/ext/parsanol_native/Cargo.toml +1 -1
- data/lib/parsanol/native.rb +18 -9
- data/lib/parsanol/parg/artifact.rb +2 -2
- data/lib/parsanol/parg/authoring.rb +1 -1
- data/lib/parsanol/parg/cli.rb +5 -4
- data/lib/parsanol/parg/compiler.rb +1 -1
- data/lib/parsanol/parg/imports.rb +1 -1
- data/lib/parsanol/parg/selfhost.rb +1 -1
- data/lib/parsanol/parg.rb +7 -0
- data/lib/parsanol/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc7df8984ab8f887379dc43d351e628656048cf4fd2a4bdd359b0b8b45341ce0
|
|
4
|
+
data.tar.gz: 38f9a43f7d4bf61621ef843d672f66883d5eee7abbe9af596b065499f89dcb12
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60c1f94221c0f97ebd61f27f6e409667630b0fd013aeabebab44cbb4918a8f22e951878ffce3f9d40b8a48d7a7bf4f4fb99c160efe11fdefe682beac63c48dca
|
|
7
|
+
data.tar.gz: b3fa201e5e2290698c3532eee6ba251a88547c4627348c791c08406b849ad651136ab65281ffa2f72b9629999b4af261679379f8f5e3d014ad82670ba0360349
|
data/Cargo.lock
CHANGED
|
@@ -307,9 +307,9 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
|
307
307
|
|
|
308
308
|
[[package]]
|
|
309
309
|
name = "parsanol"
|
|
310
|
-
version = "0.10.
|
|
310
|
+
version = "0.10.2"
|
|
311
311
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
312
|
-
checksum = "
|
|
312
|
+
checksum = "dd43c104276def3f79a54ce6e8d26642ea330c13f97d66380bd94fc057f0a849"
|
|
313
313
|
dependencies = [
|
|
314
314
|
"ahash",
|
|
315
315
|
"getrandom 0.3.4",
|
|
@@ -326,9 +326,9 @@ dependencies = [
|
|
|
326
326
|
|
|
327
327
|
[[package]]
|
|
328
328
|
name = "parsanol-derive"
|
|
329
|
-
version = "0.10.
|
|
329
|
+
version = "0.10.2"
|
|
330
330
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
331
|
-
checksum = "
|
|
331
|
+
checksum = "eca430ba21d7cc2d674080d40dd37a5567e1a0acdc37faef9a9b3738b8651dd6"
|
|
332
332
|
dependencies = [
|
|
333
333
|
"proc-macro2",
|
|
334
334
|
"quote",
|
|
@@ -28,7 +28,7 @@ rb-sys = { version = "0.9.124", features = ["global-allocator"] }
|
|
|
28
28
|
magnus = { version = "0.9" }
|
|
29
29
|
|
|
30
30
|
# parsanol parser library (crates.io; 0.10 carries the class fast-path fix)
|
|
31
|
-
parsanol = { version = "0.10", features = ["ruby"] }
|
|
31
|
+
parsanol = { version = "0.10.2", features = ["ruby"] }
|
|
32
32
|
|
|
33
33
|
# Logging
|
|
34
34
|
log = "0.4"
|
data/lib/parsanol/native.rb
CHANGED
|
@@ -220,15 +220,21 @@ module Parsanol
|
|
|
220
220
|
# to recover inputs from grammars native cannot express.
|
|
221
221
|
parsanol_grammar =
|
|
222
222
|
grammar.is_a?(Parsanol::Atoms::Base) || grammar.is_a?(Parsanol::Parser)
|
|
223
|
-
|
|
223
|
+
# The position capture is extracted as a plain String: a MatchData
|
|
224
|
+
# would pin its subject — the full multi-KB failure message — for
|
|
225
|
+
# as long as anything downstream retains it, and callers that
|
|
226
|
+
# rescue-and-collect (pubid's flavor dispatcher) retain millions
|
|
227
|
+
# across long parses (#123).
|
|
228
|
+
message = error.message
|
|
229
|
+
if parsanol_grammar && (pos_str = message[NATIVE_POS_MARKER, 1])
|
|
224
230
|
source = Parsanol::Source.new(input)
|
|
225
231
|
success, value = grammar.run_with_context(source, nil, true)
|
|
226
232
|
return grammar.finalize_result(value) if success
|
|
227
233
|
|
|
228
|
-
pos =
|
|
229
|
-
msg =
|
|
234
|
+
pos = pos_str.to_i
|
|
235
|
+
msg = message.sub(NATIVE_POS_MARKER, "")
|
|
230
236
|
cause = Parsanol::Cause.new(msg, source, pos)
|
|
231
|
-
raise Parsanol::ParseFailed.new(cause.to_s, cause)
|
|
237
|
+
raise Parsanol::ParseFailed.new(cause.to_s, cause), cause: nil
|
|
232
238
|
end
|
|
233
239
|
|
|
234
240
|
if parsanol_grammar
|
|
@@ -243,17 +249,20 @@ module Parsanol
|
|
|
243
249
|
value.raise
|
|
244
250
|
end
|
|
245
251
|
|
|
246
|
-
|
|
252
|
+
# Same capture-string extraction as above; `cause: nil` keeps the
|
|
253
|
+
# retained ParseFailed from pinning the original RuntimeError and
|
|
254
|
+
# its message through the exception-cause chain (#123).
|
|
255
|
+
if (pos_str = message[NATIVE_POS_MARKER, 1])
|
|
247
256
|
source = Parsanol::Source.new(input)
|
|
248
257
|
cause = Parsanol::Cause.new(
|
|
249
|
-
|
|
258
|
+
message.sub(NATIVE_POS_MARKER, ""), source, pos_str.to_i
|
|
250
259
|
)
|
|
251
|
-
raise Parsanol::ParseFailed.new(cause.to_s, cause)
|
|
260
|
+
raise Parsanol::ParseFailed.new(cause.to_s, cause), cause: nil
|
|
252
261
|
end
|
|
253
262
|
|
|
254
263
|
source = Parsanol::Source.new(input)
|
|
255
|
-
cause = Parsanol::Cause.new(
|
|
256
|
-
raise Parsanol::ParseFailed.new(cause.to_s, cause)
|
|
264
|
+
cause = Parsanol::Cause.new(message, source, source.bytepos)
|
|
265
|
+
raise Parsanol::ParseFailed.new(cause.to_s, cause), cause: nil
|
|
257
266
|
end
|
|
258
267
|
|
|
259
268
|
# Pre-serialized JSON grammar path (library authors with cached JSON).
|
|
@@ -14,7 +14,7 @@ module Parsanol
|
|
|
14
14
|
attr_reader :envelope, :path, :tables_dir
|
|
15
15
|
|
|
16
16
|
def self.load(path, tables_dir: nil)
|
|
17
|
-
envelope = JSON.parse(
|
|
17
|
+
envelope = JSON.parse(PARG.read_utf8(path))
|
|
18
18
|
new(envelope, path, tables_dir || File.dirname(path))
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -169,7 +169,7 @@ module Parsanol
|
|
|
169
169
|
|
|
170
170
|
file = declared
|
|
171
171
|
path = File.join(@tables_dir.to_s, file)
|
|
172
|
-
raw = path.end_with?(".json") ? JSON.parse(
|
|
172
|
+
raw = path.end_with?(".json") ? JSON.parse(PARG.read_utf8(path)) : YAML.safe_load_file(path, aliases: true)
|
|
173
173
|
rows = case raw
|
|
174
174
|
when Hash
|
|
175
175
|
raw.map { |key, value| { "name" => key.to_s }.merge(value.to_h.transform_keys(&:to_s)) }
|
|
@@ -25,7 +25,7 @@ module Parsanol
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def read_file(file)
|
|
28
|
-
content =
|
|
28
|
+
content = PARG.read_utf8(file).gsub(/^#[^\n]*\n/, "")
|
|
29
29
|
header = content.match(/suite\s+\w+(?:\s+for\s+entry\s+(?<entry>\w+))?\s*\{/)
|
|
30
30
|
unless header
|
|
31
31
|
raise ParseError,
|
data/lib/parsanol/parg/cli.rb
CHANGED
|
@@ -36,7 +36,8 @@ module Parsanol
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def initialize(argv)
|
|
39
|
-
|
|
39
|
+
# Under a non-UTF-8 locale ARGV arrives as BINARY; inputs are UTF-8.
|
|
40
|
+
@argv = argv.map { |arg| arg.dup.force_encoding(Encoding::UTF_8) }
|
|
40
41
|
@tables_dir = nil
|
|
41
42
|
end
|
|
42
43
|
|
|
@@ -82,7 +83,7 @@ module Parsanol
|
|
|
82
83
|
source = @argv.shift
|
|
83
84
|
out = flag_value("-o") || default_artifact_name(source)
|
|
84
85
|
envelope = compile_source(source).envelope
|
|
85
|
-
File.write(out, "#{JSON.generate(envelope)}\n")
|
|
86
|
+
File.write(out, "#{JSON.generate(envelope)}\n", encoding: Encoding::UTF_8)
|
|
86
87
|
puts "#{out} #{envelope['checksum']} warnings=#{envelope['lint']['order_warnings'].size}"
|
|
87
88
|
0
|
|
88
89
|
end
|
|
@@ -161,7 +162,7 @@ module Parsanol
|
|
|
161
162
|
puts "parsanol parg repl — #{file} entry #{entry_name.inspect}; blank line quits"
|
|
162
163
|
loop do
|
|
163
164
|
print "> "
|
|
164
|
-
input = $stdin.gets
|
|
165
|
+
input = $stdin.gets&.force_encoding(Encoding::UTF_8)
|
|
165
166
|
break if input.nil? || input.strip.empty?
|
|
166
167
|
|
|
167
168
|
begin
|
|
@@ -209,7 +210,7 @@ module Parsanol
|
|
|
209
210
|
|
|
210
211
|
def compile_source(file)
|
|
211
212
|
tables = @tables_dir || default_tables_dir(file)
|
|
212
|
-
document = Parsanol::PARG::Parser.new(
|
|
213
|
+
document = Parsanol::PARG::Parser.new(PARG.read_utf8(file)).parse
|
|
213
214
|
Parsanol::PARG::Imports.merge!(document, [File.dirname(file)])
|
|
214
215
|
Parsanol::PARG::Compiler.compile(document, tables_dir: tables)
|
|
215
216
|
end
|
|
@@ -19,7 +19,7 @@ module Parsanol
|
|
|
19
19
|
raise CompileError, "import cycle: #{(merging + [name]).join(' -> ')}" if merging.include?(name)
|
|
20
20
|
|
|
21
21
|
source = find_file(name, import_dirs)
|
|
22
|
-
used = Parser.new(
|
|
22
|
+
used = Parser.new(PARG.read_utf8(source)).parse
|
|
23
23
|
merge!(used, import_dirs, merging + [name])
|
|
24
24
|
merge_used(document, used, "#{name}.")
|
|
25
25
|
end
|
|
@@ -32,7 +32,7 @@ module Parsanol
|
|
|
32
32
|
def validate(source)
|
|
33
33
|
raise ArtifactError, "parg artifact not found (set PG_ARTIFACT)" unless available?
|
|
34
34
|
|
|
35
|
-
envelope = JSON.parse(
|
|
35
|
+
envelope = JSON.parse(PARG.read_utf8(artifact_path))
|
|
36
36
|
artifact = Artifact.new(envelope, nil, nil)
|
|
37
37
|
artifact.parse("file", source)
|
|
38
38
|
end
|
data/lib/parsanol/parg.rb
CHANGED
|
@@ -38,5 +38,12 @@ module Parsanol
|
|
|
38
38
|
autoload :Imports, "parsanol/parg/imports"
|
|
39
39
|
autoload :Suite, "parsanol/parg/authoring"
|
|
40
40
|
autoload :Schema, "parsanol/parg/authoring"
|
|
41
|
+
|
|
42
|
+
# PARG sources and JSON artifacts are UTF-8 by definition: read them as
|
|
43
|
+
# UTF-8 whatever the locale's default external encoding, and skip a
|
|
44
|
+
# byte-order mark the way YAML.safe_load_file does (GH-121).
|
|
45
|
+
def self.read_utf8(path)
|
|
46
|
+
File.read(path, mode: "r:bom|utf-8")
|
|
47
|
+
end
|
|
41
48
|
end
|
|
42
49
|
end
|
data/lib/parsanol/version.rb
CHANGED