@pubid/pubid 0.1.31 → 0.1.33

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 (66) hide show
  1. package/artifact/corpus.json.gz +0 -0
  2. package/dist/conformance/implementation.d.ts +4 -0
  3. package/dist/flavors/iec/index.js +12 -5
  4. package/dist/flavors/ieee/index.js +321 -113
  5. package/dist/flavors/ieee/model.d.ts +18 -0
  6. package/dist/flavors/ieee/model.js +62 -8
  7. package/dist/flavors/ieee/preprocessor.js +3 -0
  8. package/dist/flavors/ieee/update_codes.js +1 -1
  9. package/dist/flavors/iho/index.js +198 -35
  10. package/dist/flavors/jis/index.js +74 -2
  11. package/dist/flavors/nist/grammar.js +44 -16
  12. package/dist/flavors/nist/index.js +17 -2
  13. package/dist/implementations/corpus-mode.d.ts +3 -0
  14. package/dist/implementations/corpus-mode.js +7 -0
  15. package/dist/model/identifier.d.ts +3 -0
  16. package/dist/model/identifier.js +5 -0
  17. package/dist/urn/parsers.js +57 -20
  18. package/package.json +2 -2
  19. package/vendor/parg/adobe.json +1 -1
  20. package/vendor/parg/aiee.json +1 -1
  21. package/vendor/parg/amca.json +1 -1
  22. package/vendor/parg/ansi.json +1 -1
  23. package/vendor/parg/api.json +1 -1
  24. package/vendor/parg/ashrae.json +1 -1
  25. package/vendor/parg/asme.json +1 -1
  26. package/vendor/parg/astm.json +1 -1
  27. package/vendor/parg/bipm.json +1 -1
  28. package/vendor/parg/bsi.json +1 -1
  29. package/vendor/parg/calconnect.json +1 -1
  30. package/vendor/parg/ccsds.json +1 -1
  31. package/vendor/parg/cen_cenelec.json +1 -1
  32. package/vendor/parg/cie.json +1 -1
  33. package/vendor/parg/csa.json +1 -1
  34. package/vendor/parg/doi.json +1 -1
  35. package/vendor/parg/easc.json +1 -1
  36. package/vendor/parg/ecma.json +1 -1
  37. package/vendor/parg/etsi.json +1 -1
  38. package/vendor/parg/evs.json +1 -1
  39. package/vendor/parg/gb.json +1 -1
  40. package/vendor/parg/gost.json +1 -1
  41. package/vendor/parg/iala.json +1 -1
  42. package/vendor/parg/iana.json +1 -1
  43. package/vendor/parg/idf.json +1 -1
  44. package/vendor/parg/iec.json +1 -1
  45. package/vendor/parg/ieee.json +1 -29571
  46. package/vendor/parg/ietf.json +1 -1
  47. package/vendor/parg/iho.json +1 -0
  48. package/vendor/parg/ire.json +1 -1
  49. package/vendor/parg/isbn.json +1 -1
  50. package/vendor/parg/iso.json +1 -8510
  51. package/vendor/parg/itu.json +1 -1
  52. package/vendor/parg/jcgm.json +1 -1
  53. package/vendor/parg/jis.json +1 -1
  54. package/vendor/parg/nesc.json +1 -1
  55. package/vendor/parg/nist.json +1 -9588
  56. package/vendor/parg/oasis.json +1 -1
  57. package/vendor/parg/ogc.json +1 -1
  58. package/vendor/parg/oiml.json +1 -1
  59. package/vendor/parg/omg.json +1 -1
  60. package/vendor/parg/parg.json +1 -1
  61. package/vendor/parg/plateau.json +1 -1
  62. package/vendor/parg/sae.json +1 -1
  63. package/vendor/parg/tgpp.json +1 -1
  64. package/vendor/parg/un.json +1 -1
  65. package/vendor/parg/w3c.json +1 -1
  66. package/vendor/parg/xsf.json +1 -1
@@ -81,46 +81,74 @@ function buildRules() {
81
81
  "hi", "iet", "ort", "r", "p",
82
82
  ]).absent(), digits.maybe())));
83
83
  rule("digits_with_suffix", () => digits.then(ref(rules, "number_suffix").then(digit.absent()).maybe()));
84
+ // The polymorphic number wrapper is split per branch (asme's
85
+ // designator/designator_code pattern): first_number over the bare
86
+ // branches, first_number_composite over the branches carrying inner
87
+ // captures — with the alternation order untouched.
84
88
  rule("first_number", () => ref(rules, "owmwp_date_number")
85
- .or(str("ADHOC"), str("div").then(digits), monthAbbrev().then(dash, monthAbbrev(), digits), digits
89
+ .as("first_number_composite")
90
+ .or(str("ADHOC").as("first_number"), str("div").then(digits).as("first_number"), monthAbbrev().then(dash, monthAbbrev(), digits).as("first_number"), digits
86
91
  .as("number")
87
92
  .then(str("v"), digits.as("volume_suffix"))
88
- .as("number_with_volume"), digits
89
- .then(dash, literalAlternation(["III", "II", "IV", "I", "V", "VI", "VII", "VIII", "IX", "X"]), dash, digits, dot.then(digits).maybe()), digits.then(str("GB"), dash, digits, upperLetter.maybe()), digits.then(upperLetter, dash, digits), str("v")
90
- .then(digits.as("volume_number"), str("n"), digits.as("issue_number")), digits.then(str("supprev")), digits.then(str("e"), digits, str("rev"), digits), digits
93
+ .as("number_with_volume")
94
+ .as("first_number_composite"), digits
95
+ .then(dash, literalAlternation(["III", "II", "IV", "I", "V", "VI", "VII", "VIII", "IX", "X"]), dash, digits, dot.then(digits).maybe())
96
+ .as("first_number"), digits.then(str("GB"), dash, digits, upperLetter.maybe()).as("first_number"), digits.then(upperLetter, dash, digits).as("first_number"), str("v")
97
+ .then(digits.as("volume_number"), str("n"), digits.as("issue_number"))
98
+ .as("first_number_composite"), digits.then(str("supprev")).as("first_number"), digits.then(str("e"), digits, str("rev"), digits).as("first_number"), digits
91
99
  .as("number")
92
100
  .then(str("rv"), digits.as("revision_year"))
93
- .as("number_with_rev_year"), digits.then(str("e"), digits, str("rev"), monthAbbrev(), digits), digits.then(str("e"), digits, str("supp"), digits.maybe()), str("e").then(digits, str("rev"), monthAbbrev(), digits), str("e").then(digits, str("supp"), digits.maybe()), digits.then(str("e"), digits), str("e").then(digits, dash.then(digits).absent()), lowerLetter.then(digits), digits.then(str("supp"), monthAbbrev(), digits), digits.then(str("supp"), digits.maybe()), digits.then(str("sup"), monthAbbrev(), digits), digits.then(str("sup")), digits
101
+ .as("number_with_rev_year")
102
+ .as("first_number_composite"), digits.then(str("e"), digits, str("rev"), monthAbbrev(), digits).as("first_number"), digits.then(str("e"), digits, str("supp"), digits.maybe()).as("first_number"), str("e").then(digits, str("rev"), monthAbbrev(), digits).as("first_number"), str("e").then(digits, str("supp"), digits.maybe()).as("first_number"), digits.then(str("e"), digits).as("first_number"), str("e").then(digits, dash.then(digits).absent()).as("first_number"), lowerLetter.then(digits).as("first_number"), digits.then(str("supp"), monthAbbrev(), digits).as("first_number"), digits.then(str("supp"), digits.maybe()).as("first_number"), digits.then(str("sup"), monthAbbrev(), digits).as("first_number"), digits.then(str("sup")).as("first_number"), digits
94
103
  .as("number")
95
- .then(literalAlternation(["sp", "pt", "es", "SP", "PT", "ES"]).as("language_code"), upperLetter.absent(), digit.absent(), letter.absent(), dash.absent(), dot.absent()), digits
104
+ .then(literalAlternation(["sp", "pt", "es", "SP", "PT", "ES"]).as("language_code"), upperLetter.absent(), digit.absent(), letter.absent(), dash.absent(), dot.absent())
105
+ .as("first_number_composite"), digits
96
106
  .as("number")
97
- .then(str("pt"), digits.as("part_number"), str("e"), digits.as("edition_year")), digits
107
+ .then(str("pt"), digits.as("part_number"), str("e"), digits.as("edition_year"))
108
+ .as("first_number_composite"), digits
98
109
  .as("number")
99
- .then(str("("), literalAlternation(["SP", "PT", "ES"]).as("language_code"), str(")")), digits
110
+ .then(str("("), literalAlternation(["SP", "PT", "ES"]).as("language_code"), str(")"))
111
+ .as("first_number_composite"), digits
100
112
  .as("number")
101
113
  .then(upperLetter.as("letter_suffix"), str("r"), digits.as("revision_id"))
102
- .as("number_with_letter_revision"), rules["digits_with_suffix"])
103
- .as("first_number"));
114
+ .as("number_with_letter_revision")
115
+ .as("first_number_composite"), rules["digits_with_suffix"].as("first_number")));
104
116
  // OWMWP date number: MM-DD-YYYY — must precede the other shapes.
105
117
  rule("owmwp_date_number", () => match("[0-9]")
106
118
  .repeat(2, 2)
107
119
  .as("owmwp_month")
108
120
  .then(dash, match("[0-9]").repeat(2, 2).as("owmwp_day"), dash, match("[0-9]").repeat(4, 4).as("owmwp_year"))
109
121
  .as("owmwp_date_number"));
122
+ // The polymorphic wrapper is split per branch —
123
+ // second_number_composite over the branches carrying inner captures
124
+ // (revision_letter, number_only+edition_id, revision_simple),
125
+ // second_number over the bare ones — with the alternation order and
126
+ // the first branch's month/draft guards untouched.
110
127
  rule("second_number", () => monthAbbrev()
111
128
  .absent()
112
- .then(str("draft").absent(), (digits
129
+ .then(str("draft").absent(), digits
130
+ .as("number_only")
131
+ .then(str("r"), letter.as("letter"))
132
+ .as("revision_letter")
133
+ .as("second_number_composite"))
134
+ .or(digits
113
135
  .then(literalAlternation(["supp", "sup"]), digit.absent(), letter.absent())
114
- .or(digits.then(str("r"), digits, str("U"), lowerLetter), digits.then(str("r"), digits, letter), digits.as("number_only").then(str("r"), digits.then(dot.then(digits).maybe()).as("edition_id")), digits.then(str("_"), digits, dash, digits, upperLetter.maybe()), lowerLetter.then(dash, digits), digits.then(str("pt"), digits, dash.absent()), digits.then(upperLetter), digits
136
+ .as("second_number"), digits.then(str("r"), digits, str("U"), lowerLetter).as("second_number"), digits.then(str("r"), digits, letter).as("second_number"), digits
137
+ .as("number_only")
138
+ .then(str("r"), digits.then(dot.then(digits).maybe()).as("edition_id"))
139
+ .as("second_number_composite"), digits.then(str("_"), digits, dash, digits, upperLetter.maybe()).as("second_number"), lowerLetter.then(dash, digits).as("second_number"), digits.then(str("pt"), digits, dash.absent()).as("second_number"), digits.then(upperLetter).as("second_number"), digits
115
140
  .as("number_only")
116
141
  .then(str("r"), letter.as("letter"))
117
- .as("revision_letter"), str("r").then(letter).as("revision_letter_suffix"), str("r")
142
+ .as("revision_letter")
143
+ .as("second_number_composite"), str("r").then(letter).as("revision_letter_suffix"), str("r")
118
144
  .then(digits.then(dot.then(digits).maybe()).as("edition_id"))
119
- .as("revision_simple"), str("NCNR"), str("PERMIS"), str("BFRL"),
145
+ .as("revision_simple")
146
+ .as("second_number_composite"), str("NCNR").as("second_number"), str("PERMIS").as("second_number"), str("BFRL").as("second_number"),
120
147
  // A trailing lowercase means a capitalized word ("Suppl"),
121
148
  // not a second number.
122
- upperLetter.repeat(1, 3).then(lowerLetter.absent()), rules["digits_with_suffix"]
123
- .then(dash.then(monthAbbrev(), digits, slash).absent()), lowerLetter.then(digit.absent()))).as("second_number")));
149
+ upperLetter.repeat(1, 3).then(lowerLetter.absent()).as("second_number"), rules["digits_with_suffix"]
150
+ .then(dash.then(monthAbbrev(), digits, slash).absent())
151
+ .as("second_number"), lowerLetter.then(digit.absent()).as("second_number")));
124
152
  const dottedDigits = () => digits.then(dot.then(digits).maybe());
125
153
  const editionInner = () => space
126
154
  .maybe()
@@ -189,7 +189,9 @@ function locateIdentifierKlass(h) {
189
189
  series = simple;
190
190
  }
191
191
  if (series === "CS") {
192
- const firstNum = h["first_number"];
192
+ // The composite branch of the split first_number wrapper (the
193
+ // grammar's v#n# branch) arrives under first_number_composite.
194
+ const firstNum = h["first_number"] ?? h["first_number_composite"];
193
195
  if (isObj(firstNum) && firstNum["volume_number"] !== undefined && firstNum["issue_number"] !== undefined) {
194
196
  return classForKind("commercial-standards-monthly");
195
197
  }
@@ -338,9 +340,17 @@ function cast(type, value, h, policy, series = "") {
338
340
  const numberPart = `${s(owmwp["owmwp_month"])}-${s(owmwp["owmwp_day"])}`;
339
341
  return { first_number: numberPart, edition: new NistEdition({ type: "e", id: s(owmwp["owmwp_year"]) }) };
340
342
  }
343
+ // The polymorphic number wrappers split per branch in the grammar
344
+ // (asme's designator/designator_code pattern): first_number /
345
+ // second_number arrive over the bare branches, first_number_composite /
346
+ // second_number_composite (raw) over the branches carrying inner
347
+ // captures. The composite keys map onto the same dispatch.
341
348
  case "first_number":
349
+ case "first_number_composite":
350
+ return castNumber("first_number", value, h, policy);
342
351
  case "second_number":
343
- return castNumber(type, value, h, policy);
352
+ case "second_number_composite":
353
+ return castNumber("second_number", value, h, policy);
344
354
  case "crpl_range": {
345
355
  const strValue = s(value);
346
356
  if (strValue === undefined)
@@ -836,6 +846,11 @@ class NistBuilder {
836
846
  h["supplement_year"] !== undefined ||
837
847
  h["supplement"] !== undefined ||
838
848
  h["supplement_empty"] !== undefined ||
849
+ // The circ_series route marks the bare "NBS.CIRC.sup" head: the
850
+ // edition-2 grammar cannot carry the zero-width supplement_empty
851
+ // marker the Parslet tree used, so the series wrapper IS the
852
+ // supplement signal.
853
+ h["circ_series"] !== undefined ||
839
854
  h["base_portion"] !== undefined) {
840
855
  return this.buildCircularSupplement(h);
841
856
  }
@@ -20,6 +20,9 @@ export declare class CorpusBackedIdentifier implements Identifier {
20
20
  constructor(row: CorpusRow, resolveHash: (hash: Record<string, unknown>) => CorpusRow);
21
21
  toHash(): Record<string, unknown>;
22
22
  toHuman(): string;
23
+ /** The corpus row's canonical human spelling — `toString()` delegates here. */
24
+ render(): string;
25
+ toString(): string;
23
26
  toUrn(): string | undefined;
24
27
  fromHash(hash: Record<string, unknown>): Identifier;
25
28
  }
@@ -61,6 +61,13 @@ export class CorpusBackedIdentifier {
61
61
  toHuman() {
62
62
  return this.row.human;
63
63
  }
64
+ /** The corpus row's canonical human spelling — `toString()` delegates here. */
65
+ render() {
66
+ return this.row.human;
67
+ }
68
+ toString() {
69
+ return this.row.human;
70
+ }
64
71
  toUrn() {
65
72
  return this.row.urn;
66
73
  }
@@ -53,6 +53,9 @@ export declare abstract class BaseIdentifier {
53
53
  constructor(attrs?: Record<string, unknown>);
54
54
  /** The human form (Ruby render(format: :human) → the flavor renderer). */
55
55
  toHuman(): string;
56
+ /** String coercion answers the canonical human spelling — without this
57
+ * override `String(id)` and template literals print "[object Object]". */
58
+ toString(): string;
56
59
  /** Ruby to_urn: the flavor's UrnGenerator, else the base template. */
57
60
  toUrn(): string;
58
61
  fromHash(hash: Record<string, unknown>): BaseIdentifier;
@@ -97,6 +97,11 @@ export class BaseIdentifier {
97
97
  toHuman() {
98
98
  return this.render();
99
99
  }
100
+ /** String coercion answers the canonical human spelling — without this
101
+ * override `String(id)` and template literals print "[object Object]". */
102
+ toString() {
103
+ return this.render();
104
+ }
100
105
  /** Ruby to_urn: the flavor's UrnGenerator, else the base template. */
101
106
  toUrn() {
102
107
  const Generator = this.constructor.urnGenerator ?? BaseUrnGenerator;
@@ -286,35 +286,72 @@ export const URN_PARSERS = {
286
286
  return parse(year ? `GOST ${number}-${year}` : `GOST ${number}`);
287
287
  },
288
288
  },
289
- // lib/pubid/iho/urn_parser.rb — "IHO <TYPE>-<number> [<Part label>
290
- // <value>] [<version>]".
289
+ // lib/pubid/iho/urn_parser.rb (positional segment grammar) —
290
+ // "urn:iho:<type>:<number>[:ed-…][:year-…][:sup-…][:part-…]
291
+ // [:annex-…][:appendix-…][:<sub>][:vol-…][:issue-…]". The number
292
+ // occupies every leading bare digit segment (colon numbers
293
+ // round-trip unescaped); every other component is marker-prefixed.
294
+ // Legacy 2.0.x spellings stay decodable: the bare a.b.c edition,
295
+ // the dotted keys part./ap./annex./suppl./appendix./vol./issue.
296
+ // (whose appendix value may carry the subnumber, "D-2") and the
297
+ // y. year tag whose value decodes into the volume.
291
298
  iho: {
292
299
  prefix: "urn:iho:",
293
300
  reconstruct(body, parse) {
294
- const partLabels = {
295
- part: "Part",
296
- ap: "Ap.",
297
- annex: "Annex",
298
- suppl: "Suppl",
301
+ const NEW_TAG = /^([a-z]+)-(.+)$/;
302
+ const LEGACY_TAG = /^([a-z]+)\.(.*)$/;
303
+ const VERSION_SEGMENT = /^\d+\.\d+\.\d+$/;
304
+ const DIGITS = /^\d+$/;
305
+ const TAG_TEXT = {
306
+ ed: (v) => ` ${v}`,
307
+ year: (v) => ` (${v})`,
308
+ sup: (v) => ` Sup ${v}`,
309
+ part: (v) => ` Part ${v}`,
310
+ annex: (v) => ` Annex ${v}`,
311
+ appendix: (v) => ` Appendix ${v}`,
312
+ vol: (v) => ` Vol. ${v}`,
313
+ issue: (v) => ` (${v})`,
314
+ // Legacy dotted keys: decodable, never emitted. The dotted
315
+ // appendix value carries its subnumber in one string ("D-2").
316
+ ap: (v) => ` Ap. ${v}`,
317
+ suppl: (v) => ` Suppl ${v}`,
318
+ y: (v) => ` ${v}`,
299
319
  };
300
320
  const parts = splitParts(body);
301
321
  const typeToken = (parts[0] ?? "").toUpperCase();
302
- const number = parts[1] ?? "";
322
+ const tagged = (s) => /^[a-z]+[-.]/i.test(s);
323
+ const first = parts[1] ?? "";
303
324
  let idx = 2;
304
- let partLabel;
305
- const kindToken = parts[idx];
306
- if (kindToken !== undefined && /^[a-z]+\./i.test(kindToken)) {
307
- const [kind = "", value = ""] = kindToken.split(".", 2);
308
- const label = partLabels[kind.toLowerCase()] ?? (kind.charAt(0).toUpperCase() + kind.slice(1));
309
- partLabel = `${label} ${value}`;
325
+ while (idx < parts.length && !tagged(parts[idx]) && !VERSION_SEGMENT.test(parts[idx])) {
310
326
  idx += 1;
311
327
  }
312
- const version = parts[idx];
313
- let text = `IHO ${typeToken}-${number}`;
314
- if (partLabel)
315
- text += ` ${partLabel}`;
316
- if (version)
317
- text += ` ${version}`;
328
+ const number = [first, ...parts.slice(2, idx)];
329
+ let text = `IHO ${typeToken}-${number.join(":")}`;
330
+ let appendixSeen = false;
331
+ for (; idx < parts.length; idx += 1) {
332
+ const segment = parts[idx];
333
+ if (VERSION_SEGMENT.test(segment)) {
334
+ text += ` ${segment}`;
335
+ continue;
336
+ }
337
+ if (DIGITS.test(segment)) {
338
+ // The appendix subnumber is the only bare atom past the
339
+ // markers, allowed directly after its appendix segment.
340
+ if (!appendixSeen)
341
+ throw new Error(`unexpected bare segment: ${segment}`);
342
+ text += `-${segment}`;
343
+ continue;
344
+ }
345
+ const match = NEW_TAG.exec(segment) ?? LEGACY_TAG.exec(segment);
346
+ const tag = match?.[1]?.toLowerCase();
347
+ const value = match?.[2] ?? "";
348
+ const fn = tag !== undefined ? TAG_TEXT[tag] : undefined;
349
+ if (fn === undefined)
350
+ throw new Error(`unknown iho urn segment: ${segment}`);
351
+ if (tag === "appendix")
352
+ appendixSeen = true;
353
+ text += fn(value);
354
+ }
318
355
  return parse(text);
319
356
  },
320
357
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pubid/pubid",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "TypeScript PubID identifiers: resolution, normalization and canonical hashes for every identifier in the pubid-testsuite corpus (41 standards bodies), with a conformance runner mirroring the Ruby reference",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "doc:api": "node scripts/api-reference.mjs"
19
19
  },
20
20
  "dependencies": {
21
- "parsanol": "^0.10.4",
21
+ "parsanol": "0.10.37",
22
22
  "yaml": "^2.5.0"
23
23
  },
24
24
  "devDependencies": {
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidAdobe","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":48}},{"Entity":{"atom":30}},{"Entity":{"atom":9}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":" "}},{"Str":{"pattern":"TN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":7,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[3,4,6,8]}},{"Entity":{"atom":24}},{"Str":{"pattern":"Adobe"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Technical"}},{"Entity":{"atom":5}},{"Str":{"pattern":"Note"}},{"Entity":{"atom":5}},{"Repetition":{"atom":16,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"#"}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":5}},{"Repetition":{"atom":20,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[17,19,21]}},{"Repetition":{"atom":22,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[11,12,13,14,15,23]}},{"Entity":{"atom":29}},{"Str":{"pattern":"ATN"}},{"Entity":{"atom":5}},{"Repetition":{"atom":27,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[26,28]}},{"Alternative":{"atoms":[2,10,25]}},{"Entity":{"atom":32}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":31,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":33}},{"Entity":{"atom":36}},{"Str":{"pattern":"."}},{"Entity":{"atom":42}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[_]"}},{"Alternative":{"atoms":[38,39,40,41]}},{"Repetition":{"atom":37,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"slug","atom":43}},{"Sequence":{"atoms":[35,44]}},{"Repetition":{"atom":45,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,34,46]}},{"Named":{"name":"tech_note","atom":47}},{"Entity":{"atom":53}},{"Entity":{"atom":32}},{"Repetition":{"atom":50,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":51}},{"Named":{"name":"tech_note_bare","atom":52}},{"Entity":{"atom":87}},{"Str":{"pattern":"Adobe Publication "}},{"Repetition":{"atom":55,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":86}},{"Entity":{"atom":82}},{"Entity":{"atom":75}},{"Entity":{"atom":69}},{"Entity":{"atom":62}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":61,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":67}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[65,66]}},{"Repetition":{"atom":64,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[63,68]}},{"Entity":{"atom":71}},{"Str":{"pattern":"-"}},{"Entity":{"atom":69}},{"Sequence":{"atoms":[70,72]}},{"Repetition":{"atom":73,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[60,74]}},{"Named":{"name":"slug","atom":59}},{"Entity":{"atom":71}},{"Entity":{"atom":32}},{"Repetition":{"atom":78,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"version","atom":79}},{"Sequence":{"atoms":[76,77,80]}},{"Named":{"name":"publication_version","atom":81}},{"Entity":{"atom":85}},{"Entity":{"atom":75}},{"Named":{"name":"slug","atom":84}},{"Alternative":{"atoms":[58,83]}},{"Sequence":{"atoms":[56,57]}},{"Alternative":{"atoms":[0,49,54]}}],"root":88},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule tech_note_prefix: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule tech_note_prefix: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule publication_slug_or_version: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"Adobe TN 15","expect":{}},{"entry":"identifier","kind":"accept","input":"ATN 30","expect":{}},{"entry":"identifier","kind":"accept","input":"Adobe Technical Note #12","expect":{}},{"entry":"identifier","kind":"reject","input":"###","expect":{}}],"docs":{},"source":"# Port of lib/pubid/adobe/parser.rb: tech notes (Adobe TN 5014, legacy\n# \"Adobe Technical Note #5014\", ATN5014, bare 5014) and publications\n# (adobe-glyph-list, adobe-japan1-7 with the version split tried first).\n\ngrammar PubidAdobe version \"0.1.0\" {\n tech_note_tn_prefix = \"Adobe\" space \"TN\" [space]\n tech_note_long_prefix = \"Adobe\" space \"Technical\" space \"Note\" [[space] [\"#\"] [space]]\n tech_note_atn_prefix = \"ATN\" [space]\n tech_note_prefix = tech_note_tn_prefix / tech_note_long_prefix / tech_note_atn_prefix\n # Capture precedence: (*rep) as name wraps the whole repetition, so a\n # digit run joins to one string instead of re-keying every character;\n # slug is captured exactly once (the bare form) or as a sibling of\n # version inside the publication_version capture.\n tech_note = (tech_note_prefix (1*digit) as number [(dot (1*slug_char) as slug)]) as tech_note\n bare_number = ((1*digit) as number) as tech_note_bare\n slug_segment = 1*lower1 *lowerd\n slug_text = slug_segment *(dash slug_segment)\n slug_inner = (slug_text) as slug\n publication_with_version = ((slug_text) as slug dash (1*digit) as version) as publication_version\n publication_slug_or_version = publication_with_version / slug_inner\n publication = [\"Adobe Publication \"] publication_slug_or_version\n identifier = tech_note / bare_number / publication\n slug_char = %x41-5A / %x61-7A / %x30-39 / %x5F\n lower1 = %x61-7A\n lowerd = %x61-7A / %x30-39\n digit = %x30-39\n space = \" \"\n dot = \".\"\n dash = \"-\"\n entry identifier: identifier\n\n test {\n accept \"Adobe TN 15\"\n accept \"ATN 30\"\n accept \"Adobe Technical Note #12\"\n reject \"###\"\n }\n}\n","source_hash":"bba8ad76fa85bcbf6363b8bfa1502a76a050fa4ca87bcf5a8bfd14a19cab9f5e","compiler_version":"1.3.93","checksum":"sha256:cef9c127759ddb05f7bd725d9bc923b6207c099dbd8a8e73ec4ae84101040361"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidAdobe","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":40}},{"Str":{"pattern":"Adobe"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"TN"}},{"Str":{"pattern":" "}},{"Repetition":{"atom":4,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[1,2,3,5]}},{"Str":{"pattern":"Adobe"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Technical"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Note"}},{"Str":{"pattern":" "}},{"Repetition":{"atom":12,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"#"}},{"Repetition":{"atom":14,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Repetition":{"atom":16,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[13,15,17]}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[7,8,9,10,11,19]}},{"Str":{"pattern":"ATN"}},{"Str":{"pattern":" "}},{"Repetition":{"atom":22,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[21,23]}},{"Alternative":{"atoms":[6,20,24]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":26,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"number","atom":27}},{"Str":{"pattern":"."}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Re":{"pattern":"[_]"}},{"Alternative":{"atoms":[30,31,32,33]}},{"Repetition":{"atom":34,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"slug","atom":35}},{"Sequence":{"atoms":[29,36]}},{"Repetition":{"atom":37,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[25,28,38]}},{"Named":{"name":"tech_note","atom":39}},{"Entity":{"atom":44}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":42,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"tech_note_bare","atom":43}},{"Entity":{"atom":92}},{"Str":{"pattern":"Adobe Publication "}},{"Repetition":{"atom":46,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":91}},{"Entity":{"atom":72}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":50,"min":1,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[52,53]}},{"Repetition":{"atom":54,"min":0,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":57,"min":1,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[59,60]}},{"Repetition":{"atom":61,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[56,58,62]}},{"Repetition":{"atom":63,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[51,55,64]}},{"Named":{"name":"slug","atom":65}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":68,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"version","atom":69}},{"Sequence":{"atoms":[66,67,70]}},{"Named":{"name":"publication_version","atom":71}},{"Entity":{"atom":90}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":74,"min":1,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[76,77]}},{"Repetition":{"atom":78,"min":0,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Repetition":{"atom":81,"min":1,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Alternative":{"atoms":[83,84]}},{"Repetition":{"atom":85,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[80,82,86]}},{"Repetition":{"atom":87,"min":0,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[75,79,88]}},{"Named":{"name":"slug","atom":89}},{"Alternative":{"atoms":[49,73]}},{"Sequence":{"atoms":[47,48]}},{"Alternative":{"atoms":[0,41,45]}}],"root":93},"bindings":[{"capture":"tech_note","path":"tech_note","type":"raw","card":null,"preprocess":null},{"capture":"tech_note_bare","path":"tech_note_bare","type":"string","card":null,"preprocess":null},{"capture":"publication_version","path":"publication_version","type":"raw","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"slug","path":"slug","type":"string","card":null,"preprocess":null},{"capture":"version","path":"version","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule publication_slug_or_version: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"Adobe TN 15","expect":{}},{"entry":"identifier","kind":"accept","input":"ATN 30","expect":{}},{"entry":"identifier","kind":"accept","input":"Adobe Technical Note #12","expect":{}},{"entry":"identifier","kind":"reject","input":"###","expect":{}}],"docs":{},"source":"# Port of lib/pubid/adobe/parser.rb: tech notes (Adobe TN 5014, legacy\n# \"Adobe Technical Note #5014\", ATN5014, bare 5014) and publications\n# (adobe-glyph-list, adobe-japan1-7 with the version split tried first).\n#\n# Edition 2: every reference inside a captured body is inlined to raw\n# terms (a rule reference materializes as a named node in the edition-2\n# tree, so only a raw capture binds a scalar span). The prefix spellings\n# and slug shapes live inline below; the wrapper captures (tech_note,\n# tech_note_bare, publication_version) keep the v1 tree shape and the\n# bindings name their scalar leaves.\n\ngrammar PubidAdobe version \"0.1.0\" edition 2 {\n\n # Capture precedence: (*rep) as name wraps the whole repetition, so a\n # digit run joins to one string instead of re-keying every character;\n # slug is captured exactly once (the bare form) or as a sibling of\n # version inside the publication_version capture. The three prefix\n # spellings are inlined longest-first (ordered choice is decisive).\n tech_note = {\n (\n ( \"Adobe\" \" \" \"TN\" [\" \"]\n / \"Adobe\" \" \" \"Technical\" \" \" \"Note\" [[\" \"] [\"#\"] [\" \"]]\n / \"ATN\" [\" \"] )\n (1*%x30-39) as number\n [(\".\" (1*(%x41-5A / %x61-7A / %x30-39 / %x5F)) as slug)]\n ) as tech_note\n }\n # The bare form captures the digit run as one span: the builder\n # stringifies the :tech_note_bare value AS the number (no nested read),\n # so an inner capture here would render the hash, not the digits.\n bare_number = (1*%x30-39) as tech_note_bare\n # Slug text: a lower-case lead segment, then dash-joined segments.\n publication_with_version = {\n (\n ( 1*%x61-7A *(%x61-7A / %x30-39)\n *(\"-\" 1*%x61-7A *(%x61-7A / %x30-39)) ) as slug\n \"-\"\n (1*%x30-39) as version\n ) as publication_version\n }\n slug_inner = {\n ( 1*%x61-7A *(%x61-7A / %x30-39)\n *(\"-\" 1*%x61-7A *(%x61-7A / %x30-39)) ) as slug\n }\n publication_slug_or_version = publication_with_version / slug_inner\n publication = [\"Adobe Publication \"] publication_slug_or_version\n identifier = tech_note / bare_number / publication\n\n entry identifier: identifier\n\n test {\n accept \"Adobe TN 15\"\n accept \"ATN 30\"\n accept \"Adobe Technical Note #12\"\n reject \"###\"\n }\n\n bindings identifier {\n # The builder dispatches on the wrapper keys and reads the leaves from\n # inside them (adobe/builder.rb build_tech_note / build_publication_version),\n # so the wrappers bind uncast — the nested hash the builder expects. The\n # scalar bindings carry the same leaves flat for typed consumers.\n tech_note -> tech_note (raw)\n tech_note_bare -> tech_note_bare (string)\n publication_version -> publication_version (raw)\n number -> number (string)\n slug -> slug (string)\n version -> version (string)\n }\n}\n","source_hash":"ebe64b2104b3e1494b9c5ba304e3b7e62f95b3430851db7f5c09549e03fcefb9","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.121","edition":2,"semantics_hash":"sha256:a56693eaf290b40d9d94ed91611d4aa108e9827d578071062b17ca072658cc25","checksum":"sha256:c60b5d20d036c1fe12c259948141288a671bac74772e754f3afff4bc60cc00c8"}
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidAiee","shape":"parsanol-tree/v2","binding_version":1,"entries":{"aiee_identifier":{"root":"aiee_identifier","grammar":{"atoms":[{"Entity":{"atom":6}},{"Str":{"pattern":"IEEE-AIEE"}},{"Str":{"pattern":"A.I.E.E."}},{"Str":{"pattern":"A. I. E. E."}},{"Str":{"pattern":"AIEE"}},{"Alternative":{"atoms":[1,2,3,4]}},{"Named":{"name":"publisher","atom":5}},{"Entity":{"atom":8}},{"Str":{"pattern":" "}},{"Entity":{"atom":22}},{"Str":{"pattern":"Standard No."}},{"Str":{"pattern":"Standard No"}},{"Str":{"pattern":"Std No."}},{"Str":{"pattern":"Std No"}},{"Str":{"pattern":"Std"}},{"Str":{"pattern":"Nos"}},{"Str":{"pattern":"No."}},{"Str":{"pattern":"No"}},{"Str":{"pattern":"no"}},{"Str":{"pattern":"Standard"}},{"Str":{"pattern":"Trans."}},{"Alternative":{"atoms":[10,11,12,13,14,15,16,17,18,19,20]}},{"Named":{"name":"type","atom":21}},{"Entity":{"atom":8}},{"Sequence":{"atoms":[9,23]}},{"Repetition":{"atom":24,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":68}},{"Entity":{"atom":28}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Repetition":{"atom":27,"min":2,"max":3,"tag":"Repetition"}},{"Entity":{"atom":31}},{"Str":{"pattern":"-"}},{"Entity":{"atom":35}},{"Entity":{"atom":34}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":33,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[29,30,32]}},{"Entity":{"atom":35}},{"Entity":{"atom":28}},{"Entity":{"atom":8}},{"Str":{"pattern":"and"}},{"Sequence":{"atoms":[39,40]}},{"Lookahead":{"atom":41,"positive":false}},{"Sequence":{"atoms":[37,38,42]}},{"Entity":{"atom":35}},{"Entity":{"atom":46}},{"Str":{"pattern":"."}},{"Entity":{"atom":35}},{"Sequence":{"atoms":[44,45,47]}},{"Entity":{"atom":35}},{"Named":{"name":"main_number","atom":49}},{"Entity":{"atom":8}},{"Str":{"pattern":"("}},{"Entity":{"atom":35}},{"Named":{"name":"alt_number","atom":53}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[52,54,55]}},{"Named":{"name":"parenthetical","atom":56}},{"Sequence":{"atoms":[50,51,57]}},{"Entity":{"atom":35}},{"Entity":{"atom":8}},{"Str":{"pattern":"and"}},{"Entity":{"atom":8}},{"Entity":{"atom":35}},{"Sequence":{"atoms":[60,61,62,63]}},{"Lookahead":{"atom":64,"positive":false}},{"Sequence":{"atoms":[59,65]}},{"Alternative":{"atoms":[36,43,48,58,66]}},{"Named":{"name":"number","atom":67}},{"Entity":{"atom":155}},{"Entity":{"atom":94}},{"Entity":{"atom":8}},{"Repetition":{"atom":71,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":31}},{"Entity":{"atom":92}},{"Str":{"pattern":"18"}},{"Entity":{"atom":34}},{"Repetition":{"atom":76,"min":2,"max":2,"tag":"Repetition"}},{"Sequence":{"atoms":[75,77]}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"0"}},{"Str":{"pattern":"1"}},{"Str":{"pattern":"2"}},{"Str":{"pattern":"3"}},{"Str":{"pattern":"4"}},{"Str":{"pattern":"5"}},{"Alternative":{"atoms":[80,81,82,83,84,85]}},{"Entity":{"atom":34}},{"Sequence":{"atoms":[79,86,87]}},{"Str":{"pattern":"196"}},{"Re":{"pattern":"[\\x30-\\x33]"}},{"Sequence":{"atoms":[89,90]}},{"Alternative":{"atoms":[78,88,91]}},{"Named":{"name":"year","atom":74}},{"Sequence":{"atoms":[72,73,93]}},{"Entity":{"atom":153}},{"Entity":{"atom":8}},{"Repetition":{"atom":96,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":","}},{"Entity":{"atom":46}},{"Alternative":{"atoms":[98,99]}},{"Named":{"name":"separator","atom":100}},{"Entity":{"atom":8}},{"Repetition":{"atom":102,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":129}},{"Str":{"pattern":"September"}},{"Str":{"pattern":"November"}},{"Str":{"pattern":"December"}},{"Str":{"pattern":"February"}},{"Str":{"pattern":"August"}},{"Str":{"pattern":"June"}},{"Str":{"pattern":"January"}},{"Str":{"pattern":"March"}},{"Str":{"pattern":"April"}},{"Str":{"pattern":"October"}},{"Str":{"pattern":"July"}},{"Str":{"pattern":"May"}},{"Str":{"pattern":"Sept"}},{"Str":{"pattern":"Jan"}},{"Str":{"pattern":"Feb"}},{"Str":{"pattern":"Mar"}},{"Str":{"pattern":"Apr"}},{"Str":{"pattern":"Jun"}},{"Str":{"pattern":"Jul"}},{"Str":{"pattern":"Aug"}},{"Str":{"pattern":"Sep"}},{"Str":{"pattern":"Oct"}},{"Str":{"pattern":"Nov"}},{"Str":{"pattern":"Dec"}},{"Alternative":{"atoms":[105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128]}},{"Named":{"name":"month","atom":104}},{"Entity":{"atom":8}},{"Sequence":{"atoms":[130,131]}},{"Repetition":{"atom":132,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":92}},{"Named":{"name":"year","atom":134}},{"Sequence":{"atoms":[101,103,133,135]}},{"Sequence":{"atoms":[97,136]}},{"Entity":{"atom":8}},{"Entity":{"atom":31}},{"Sequence":{"atoms":[138,139]}},{"Named":{"name":"separator","atom":140}},{"Entity":{"atom":8}},{"Repetition":{"atom":142,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":92}},{"Named":{"name":"year","atom":144}},{"Sequence":{"atoms":[141,143,145]}},{"Entity":{"atom":129}},{"Named":{"name":"month","atom":147}},{"Entity":{"atom":31}},{"Entity":{"atom":92}},{"Named":{"name":"year","atom":150}},{"Sequence":{"atoms":[148,149,151]}},{"Alternative":{"atoms":[137,146,152]}},{"Alternative":{"atoms":[70,95]}},{"Repetition":{"atom":154,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[0,7,25,26,69]}}],"root":156},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule year: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule year: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule year: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 1 and 13 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 1 and 21 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 2 and 23 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 3 and 24 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 4 and 15 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 9 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 17 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 7 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 11 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 11 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 8 and 12 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 8 and 16 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 9 and 17 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 9 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 10 and 22 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 12 and 16 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 13 and 21 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 14 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 14 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 17 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 18 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule date_long: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"aiee_identifier","render":{},"derive":{},"tests":[{"entry":"aiee_identifier","kind":"accept","input":"AIEE No. 56","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"AIEE Std 800","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"IEEE-AIEE No 18-1938","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"AIEE Standard 19","expect":{}},{"entry":"aiee_identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/ieee/aiee/parser.rb — AIEE (pre-IEEE) designations:\n# prefixes (IEEE-AIEE transitional, A.I.E.E. variants, AIEE), types\n# (Standard No./Std No./Nos/No/Trans.), numbers (letters-dash, dotted,\n# parenthetical alternates) and long/short dates. Consumed by the ieee\n# grammar via `use aiee`. Deviation: source \"Sep\"/\"Sept\" order is\n# lint-forced to longest-first.\n\ngrammar PubidAiee version \"0.1.0\" {\n digit = %x30-39\n upper = %x41-5A\n lower = %x61-7A\n digits = 1*digit\n space = \" \"\n dash = \"-\"\n dot = \".\"\n\n year = ((\"18\" 2digit)) / ((\"19\" (\"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\") digit)) / ((\"196\" %x30-33))\n month_name = \"September\" / \"November\" / \"December\" / \"February\" / \"August\" / \"June\" / \"January\" / \"March\" / \"April\" / \"October\" / \"July\" / \"May\" / \"Sept\" / \"Jan\" / \"Feb\" / \"Mar\" / \"Apr\" / \"Jun\" / \"Jul\" / \"Aug\" / \"Sep\" / \"Oct\" / \"Nov\" / \"Dec\"\n aiee_prefix = (\"IEEE-AIEE\" / \"A.I.E.E.\" / \"A. I. E. E.\" / \"AIEE\") as publisher\n aiee_type = (\"Standard No.\" / \"Standard No\" / \"Std No.\" / \"Std No\" / \"Std\" / \"Nos\" / \"No.\" / \"No\" / \"no\" / \"Standard\" / \"Trans.\") as type\n number = (((2*3upper dash digits)) / ((digits upper !((space \"and\")))) / ((digits dot digits)) / (((digits) as main_number space ((( \"(\" (digits) as alt_number \")\"))) as parenthetical)) / ((digits !((space \"and\" space digits))))) as number\n date_long = ([space] ((((\",\" / dot) as separator) [space] [((month_name) as month space)] (year) as year)) / (((space dash) as separator) [space] (year) as year) / (((month_name) as month dash (year) as year)))\n date_short = ([space] dash (year) as year)\n date = [(date_short / date_long)]\n\n aiee_identifier = aiee_prefix space [(aiee_type space)] number date\n\n entry aiee_identifier: aiee_identifier\n\n test {\n accept \"AIEE No. 56\"\n accept \"AIEE Std 800\"\n accept \"IEEE-AIEE No 18-1938\"\n accept \"AIEE Standard 19\"\n reject \"nonsense\"\n }\n}\n","source_hash":"4d858b677a096e55be57fc24b443cf2bef9b27648d8b4433523115189affca50","compiler_version":"1.3.93","checksum":"sha256:3214fb753c1e1fead5e52d03778b4718384039995d5841d3c11b2d84489a594b"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidAiee","shape":"parsanol-tree/v2","binding_version":1,"entries":{"aiee_identifier":{"root":"aiee_identifier","grammar":{"atoms":[{"Entity":{"atom":6}},{"Str":{"pattern":"IEEE-AIEE"}},{"Str":{"pattern":"A.I.E.E."}},{"Str":{"pattern":"A. I. E. E."}},{"Str":{"pattern":"AIEE"}},{"Alternative":{"atoms":[1,2,3,4]}},{"Named":{"name":"publisher","atom":5}},{"Str":{"pattern":" "}},{"Entity":{"atom":21}},{"Str":{"pattern":"Standard No."}},{"Str":{"pattern":"Standard No"}},{"Str":{"pattern":"Std No."}},{"Str":{"pattern":"Std No"}},{"Str":{"pattern":"Std"}},{"Str":{"pattern":"Nos"}},{"Str":{"pattern":"No."}},{"Str":{"pattern":"No"}},{"Str":{"pattern":"no"}},{"Str":{"pattern":"Standard"}},{"Str":{"pattern":"Trans."}},{"Alternative":{"atoms":[9,10,11,12,13,14,15,16,17,18,19]}},{"Named":{"name":"type","atom":20}},{"Str":{"pattern":" "}},{"Sequence":{"atoms":[8,22]}},{"Repetition":{"atom":23,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":61}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Repetition":{"atom":26,"min":2,"max":3,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":29,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[27,28,30]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":32,"min":1,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Str":{"pattern":" and"}},{"Lookahead":{"atom":35,"positive":false}},{"Sequence":{"atoms":[33,34,36]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":38,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":41}},{"Str":{"pattern":"."}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":42,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[39,40,43]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":45,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":" ("}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":48,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[46,47,49,50]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":52,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":" and "}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":55,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[54,56]}},{"Lookahead":{"atom":57,"positive":false}},{"Sequence":{"atoms":[53,58]}},{"Alternative":{"atoms":[31,37,44,51,59]}},{"Named":{"name":"number","atom":60}},{"Entity":{"atom":175}},{"Entity":{"atom":86}},{"Str":{"pattern":" "}},{"Repetition":{"atom":64,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"18"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":68,"min":2,"max":2,"tag":"Repetition"}},{"Sequence":{"atoms":[67,69]}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"0"}},{"Str":{"pattern":"1"}},{"Str":{"pattern":"2"}},{"Str":{"pattern":"3"}},{"Str":{"pattern":"4"}},{"Str":{"pattern":"5"}},{"Alternative":{"atoms":[72,73,74,75,76,77]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Sequence":{"atoms":[71,78,79]}},{"Str":{"pattern":"196"}},{"Re":{"pattern":"[\\x30-\\x33]"}},{"Sequence":{"atoms":[81,82]}},{"Alternative":{"atoms":[70,80,83]}},{"Named":{"name":"year","atom":84}},{"Sequence":{"atoms":[65,66,85]}},{"Entity":{"atom":173}},{"Str":{"pattern":" "}},{"Repetition":{"atom":88,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":","}},{"Str":{"pattern":"."}},{"Alternative":{"atoms":[90,91]}},{"Named":{"name":"separator","atom":92}},{"Str":{"pattern":" "}},{"Repetition":{"atom":94,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":121}},{"Str":{"pattern":"September"}},{"Str":{"pattern":"November"}},{"Str":{"pattern":"December"}},{"Str":{"pattern":"February"}},{"Str":{"pattern":"August"}},{"Str":{"pattern":"June"}},{"Str":{"pattern":"January"}},{"Str":{"pattern":"March"}},{"Str":{"pattern":"April"}},{"Str":{"pattern":"October"}},{"Str":{"pattern":"July"}},{"Str":{"pattern":"May"}},{"Str":{"pattern":"Sept"}},{"Str":{"pattern":"Jan"}},{"Str":{"pattern":"Feb"}},{"Str":{"pattern":"Mar"}},{"Str":{"pattern":"Apr"}},{"Str":{"pattern":"Jun"}},{"Str":{"pattern":"Jul"}},{"Str":{"pattern":"Aug"}},{"Str":{"pattern":"Sep"}},{"Str":{"pattern":"Oct"}},{"Str":{"pattern":"Nov"}},{"Str":{"pattern":"Dec"}},{"Alternative":{"atoms":[97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120]}},{"Named":{"name":"month","atom":96}},{"Str":{"pattern":" "}},{"Sequence":{"atoms":[122,123]}},{"Repetition":{"atom":124,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"18"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":127,"min":2,"max":2,"tag":"Repetition"}},{"Sequence":{"atoms":[126,128]}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"0"}},{"Str":{"pattern":"1"}},{"Str":{"pattern":"2"}},{"Str":{"pattern":"3"}},{"Str":{"pattern":"4"}},{"Str":{"pattern":"5"}},{"Alternative":{"atoms":[131,132,133,134,135,136]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Sequence":{"atoms":[130,137,138]}},{"Str":{"pattern":"196"}},{"Re":{"pattern":"[\\x30-\\x33]"}},{"Sequence":{"atoms":[140,141]}},{"Alternative":{"atoms":[129,139,142]}},{"Named":{"name":"year","atom":143}},{"Sequence":{"atoms":[93,95,125,144]}},{"Sequence":{"atoms":[89,145]}},{"Str":{"pattern":" "}},{"Repetition":{"atom":147,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" -"}},{"Named":{"name":"separator","atom":149}},{"Str":{"pattern":" "}},{"Repetition":{"atom":151,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"18"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":154,"min":2,"max":2,"tag":"Repetition"}},{"Sequence":{"atoms":[153,155]}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"0"}},{"Str":{"pattern":"1"}},{"Str":{"pattern":"2"}},{"Str":{"pattern":"3"}},{"Str":{"pattern":"4"}},{"Str":{"pattern":"5"}},{"Alternative":{"atoms":[158,159,160,161,162,163]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Sequence":{"atoms":[157,164,165]}},{"Str":{"pattern":"196"}},{"Re":{"pattern":"[\\x30-\\x33]"}},{"Sequence":{"atoms":[167,168]}},{"Alternative":{"atoms":[156,166,169]}},{"Named":{"name":"year","atom":170}},{"Sequence":{"atoms":[148,150,152,171]}},{"Alternative":{"atoms":[146,172]}},{"Alternative":{"atoms":[63,87]}},{"Repetition":{"atom":174,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[0,7,24,25,62]}}],"root":176},"bindings":[{"capture":"publisher","path":"publisher","type":"string","card":null,"preprocess":null},{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"number","path":"number","type":"string","card":null,"preprocess":null},{"capture":"separator","path":"separator","type":"string","card":null,"preprocess":null},{"capture":"month","path":"month","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule year: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule year: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule year: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 1 and 13 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 1 and 21 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 2 and 23 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 3 and 24 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 4 and 15 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 9 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 17 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 5 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 7 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 11 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 6 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 11 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 7 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 8 and 12 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 8 and 16 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 9 and 17 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 9 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 10 and 22 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 14 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 11 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 12 and 16 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 13 and 21 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 14 and 18 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 14 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 17 and 20 are order-dependent (shared first bytes; ordered choice is decisive)","rule month_name: branches 18 and 19 are order-dependent (shared first bytes; ordered choice is decisive)","rule date_long: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"aiee_identifier","render":{},"derive":{},"tests":[{"entry":"aiee_identifier","kind":"accept","input":"AIEE No. 56","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"AIEE Std 800","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"IEEE-AIEE No 18-1938","expect":{}},{"entry":"aiee_identifier","kind":"accept","input":"AIEE Standard 19","expect":{}},{"entry":"aiee_identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/ieee/aiee/parser.rb — AIEE (pre-IEEE) designations:\n# prefixes (IEEE-AIEE transitional, A.I.E.E. variants, AIEE), types\n# (Standard No./Std No./Nos/No/Trans.), numbers (letters-dash, dotted,\n# parenthetical alternates) and long/short dates. Consumed by the ieee\n# grammar via `use aiee`. Deviation: source \"Sep\"/\"Sept\" order is\n# lint-forced to longest-first.\n#\n# Edition-2 notes: the number capture inlines all five alternatives to\n# raw terms, including the parenthetical-alternate branch — its\n# main_number/alt_number/parenthetical sub-captures drop (a wrapper over\n# them expands to element hashes, which cannot bind scalar; the old\n# pipeline already flattened the subtree to the \"431 (105)\" span the\n# capture now binds directly). The year body inlines at every capture\n# site for the same reason; the digits rule inlines to 1*%x30-39 (a ref\n# whose body is a repetition expands to node lists inside a capture).\n\ngrammar PubidAiee version \"0.1.0\" edition 2 {\n digit = %x30-39\n upper = %x41-5A\n lower = %x61-7A\n digits = 1*%x30-39\n space = \" \"\n dash = \"-\"\n dot = \".\"\n\n year = ((\"18\" 2%x30-39)) / ((\"19\" (\"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\") %x30-39)) / ((\"196\" %x30-33))\n month_name = {\n \"September\"\n / \"November\"\n / \"December\"\n / \"February\"\n / \"August\"\n / \"June\"\n / \"January\"\n / \"March\"\n / \"April\"\n / \"October\"\n / \"July\"\n / \"May\"\n / \"Sept\"\n / \"Jan\"\n / \"Feb\"\n / \"Mar\"\n / \"Apr\"\n / \"Jun\"\n / \"Jul\"\n / \"Aug\"\n / \"Sep\"\n / \"Oct\"\n / \"Nov\"\n / \"Dec\"\n }\n aiee_prefix = (\"IEEE-AIEE\" / \"A.I.E.E.\" / \"A. I. E. E.\" / \"AIEE\") as publisher\n aiee_type = {\n (\n \"Standard No.\"\n / \"Standard No\"\n / \"Std No.\"\n / \"Std No\"\n / \"Std\"\n / \"Nos\"\n / \"No.\"\n / \"No\"\n / \"no\"\n / \"Standard\"\n / \"Trans.\"\n ) as type\n }\n number = {\n (\n ( 2*3%x41-5A \"-\" 1*%x30-39 )\n / ( 1*%x30-39 %x41-5A !( \" and\" ) )\n / ( 1*%x30-39 dot 1*%x30-39 )\n / ( 1*%x30-39 \" (\" 1*%x30-39 \")\" )\n / ( 1*%x30-39 !( \" and \" 1*%x30-39 ) )\n ) as number\n }\n # The source's third date_long alternative (month dash year, no\n # separator) is dropped deliberately: under the edition-1 branch-commit\n # semantics the leading [space] commits before the alternation, so the\n # month-first form never matches (\"AIEE No 15May-1928\" and\n # \"AIEE No 15 May-1928\" both reject on the edition-1 artifact). Keeping\n # it would widen the accept set; month forms ride the separator\n # alternative, as on edition 1.\n #\n # The year body inlines at every capture site (a capture wrapping the\n # year rule ref expands to element hashes; the inline alternation binds\n # as one scalar string).\n date_long = {\n (\n ( [\" \"] ( ( ( \",\" / \".\" ) as separator ) [\" \"] [ ( month_name ) as month \" \" ]\n ( (\"18\" 2%x30-39)\n / (\"19\" (\"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\") %x30-39)\n / (\"196\" %x30-33) ) as year ) )\n / ( [\" \"] ( \" -\" ) as separator [\" \"]\n ( (\"18\" 2%x30-39)\n / (\"19\" (\"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\") %x30-39)\n / (\"196\" %x30-33) ) as year )\n )\n }\n date_short = {\n [\" \"] \"-\"\n ( (\"18\" 2%x30-39) / (\"19\" (\"0\" / \"1\" / \"2\" / \"3\" / \"4\" / \"5\") %x30-39) / (\"196\" %x30-33) ) as year\n }\n date = [(date_short / date_long)]\n\n aiee_identifier = aiee_prefix \" \" [aiee_type \" \"] number date\n\n entry aiee_identifier: aiee_identifier\n\n bindings aiee_identifier {\n publisher -> publisher (string)\n type -> type (string)\n number -> number (string)\n separator -> separator (string)\n month -> month (string)\n year -> year (string)\n }\n\n test {\n accept \"AIEE No. 56\"\n accept \"AIEE Std 800\"\n accept \"IEEE-AIEE No 18-1938\"\n accept \"AIEE Standard 19\"\n reject \"nonsense\"\n }\n}\n","source_hash":"41c7feee510cd38fb391ef4bd8e581dfc8edd5126d9660a8c7fbde8ac79bfe44","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.121","edition":2,"semantics_hash":"sha256:95a3985f74d0a5f73f942239f9da951858d702b6748eea894738e52b65f76cd3","checksum":"sha256:a1adfdeb96fa6d52ef431f39a82d973f6e6b5cbcdd70a32c9a28f1f87dc391ce"}
@@ -1 +1 @@
1
- {"bindings":null,"version":"0.1.0","grammar":"PubidAmca","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":65}},{"Entity":{"atom":9}},{"Str":{"pattern":"ANSI"}},{"Entity":{"atom":4}},{"Str":{"pattern":"/"}},{"Str":{"pattern":"AMCA"}},{"Sequence":{"atoms":[2,3,5]}},{"Str":{"pattern":"AMCA"}},{"Alternative":{"atoms":[6,7]}},{"Named":{"name":"copublisher","atom":8}},{"Repetition":{"atom":1,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Str":{"pattern":" "}},{"Entity":{"atom":32}},{"Entity":{"atom":15}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":14,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":18}},{"Str":{"pattern":"-"}},{"Entity":{"atom":22}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[20,21]}},{"Sequence":{"atoms":[17,19]}},{"Repetition":{"atom":23,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":26}},{"Str":{"pattern":"."}},{"Entity":{"atom":15}},{"Repetition":{"atom":27,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[25,28]}},{"Repetition":{"atom":29,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[16,24,30]}},{"Named":{"name":"code","atom":31}},{"Entity":{"atom":12}},{"Entity":{"atom":40}},{"Entity":{"atom":22}},{"Repetition":{"atom":35,"min":2,"max":null,"tag":"Repetition"}},{"Entity":{"atom":15}},{"Repetition":{"atom":37,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[36,38]}},{"Named":{"name":"interpretation_code","atom":39}},{"Entity":{"atom":44}},{"Entity":{"atom":12}},{"Str":{"pattern":"Interp"}},{"Sequence":{"atoms":[42,43]}},{"Sequence":{"atoms":[34,41]}},{"Str":{"pattern":"–"}},{"Entity":{"atom":18}},{"Alternative":{"atoms":[46,47]}},{"Entity":{"atom":15}},{"Repetition":{"atom":49,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"interpretation_year","atom":50}},{"Entity":{"atom":44}},{"Repetition":{"atom":52,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[48,51,53]}},{"Alternative":{"atoms":[45,54]}},{"Sequence":{"atoms":[10,11,13,33,55]}},{"Named":{"name":"interpretation","atom":56}},{"Entity":{"atom":9}},{"Repetition":{"atom":58,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":32}},{"Entity":{"atom":44}},{"Sequence":{"atoms":[59,60,61,62]}},{"Named":{"name":"interpretation","atom":63}},{"Alternative":{"atoms":[57,64]}},{"Entity":{"atom":118}},{"Entity":{"atom":9}},{"Repetition":{"atom":67,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Str":{"pattern":"Publication"}},{"Named":{"name":"publication_keyword","atom":70}},{"Entity":{"atom":12}},{"Entity":{"atom":32}},{"Entity":{"atom":18}},{"Entity":{"atom":84}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[76,77]}},{"Entity":{"atom":15}},{"Repetition":{"atom":79,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[78,80]}},{"Entity":{"atom":15}},{"Repetition":{"atom":82,"min":2,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[81,83]}},{"Named":{"name":"year","atom":75}},{"Sequence":{"atoms":[74,85]}},{"Repetition":{"atom":86,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":103}},{"Str":{"pattern":"("}},{"Str":{"pattern":"Rev"}},{"Entity":{"atom":26}},{"Repetition":{"atom":92,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":15}},{"Repetition":{"atom":95,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":18}},{"Entity":{"atom":15}},{"Repetition":{"atom":98,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[96,97,99]}},{"Named":{"name":"revision","atom":100}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[90,91,93,94,101,102]}},{"Sequence":{"atoms":[88,89]}},{"Repetition":{"atom":104,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":114}},{"Str":{"pattern":"("}},{"Str":{"pattern":"R"}},{"Entity":{"atom":15}},{"Repetition":{"atom":110,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"reaffirmed","atom":111}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[108,109,112,113]}},{"Sequence":{"atoms":[106,107]}},{"Repetition":{"atom":115,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[68,69,71,72,73,87,105,116]}},{"Named":{"name":"publication","atom":117}},{"Entity":{"atom":163}},{"Entity":{"atom":9}},{"Repetition":{"atom":120,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":126}},{"Str":{"pattern":"Standard"}},{"Str":{"pattern":"Publication"}},{"Alternative":{"atoms":[124,125]}},{"Named":{"name":"type","atom":123}},{"Repetition":{"atom":127,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Repetition":{"atom":129,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":32}},{"Entity":{"atom":18}},{"Entity":{"atom":84}},{"Named":{"name":"year","atom":133}},{"Sequence":{"atoms":[132,134]}},{"Repetition":{"atom":135,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":150}},{"Entity":{"atom":4}},{"Entity":{"atom":22}},{"Repetition":{"atom":140,"min":2,"max":10,"tag":"Repetition"}},{"Entity":{"atom":12}},{"Entity":{"atom":15}},{"Repetition":{"atom":143,"min":1,"max":null,"tag":"Repetition"}},{"Entity":{"atom":18}},{"Entity":{"atom":15}},{"Repetition":{"atom":146,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[145,147]}},{"Repetition":{"atom":148,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[139,141,142,144,149]}},{"Sequence":{"atoms":[137,138]}},{"Repetition":{"atom":151,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":156}},{"Str":{"pattern":"R"}},{"Str":{"pattern":"P"}},{"Alternative":{"atoms":[154,155]}},{"Repetition":{"atom":153,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":12}},{"Entity":{"atom":114}},{"Sequence":{"atoms":[158,159]}},{"Repetition":{"atom":160,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[121,122,128,130,131,136,152,157,161]}},{"Named":{"name":"standard","atom":162}},{"Alternative":{"atoms":[0,66,119]}}],"root":164},"bindings":[]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule interpretation_identifier: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule year_digits: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"AMCA 500-D","expect":{}},{"entry":"identifier","kind":"accept","input":"AMCA Standard 210","expect":{}},{"entry":"identifier","kind":"accept","input":"ANSI/AMCA 210","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/amca/parser.rb. Pre-parse whitespace collapsing,\n# en-dash normalization and trailing punctuation stripping stay\n# binder-side.\n\ngrammar PubidAmca version \"0.1.0\" {\n copublisher = ((\"ANSI\" slash \"AMCA\") / \"AMCA\") as copublisher\n additional_copublisher = slash 2*10letter space 1*digit [(dash 1*digit)]\n code = (1*digit [(dash letter)] [(dot 1*digit)]) as code\n type = \"Standard\" / \"Publication\"\n reaffirmation = \"(\" \"R\" (1*digit) as reaffirmed \")\"\n suffix = \"R\" / \"P\"\n revision = \"(\" \"Rev\" [dot] space (1*digit dash 1*digit) as revision \")\"\n interpretation_code = (2*letter / 1*digit) as interpretation_code\n interp_keyword = space \"Interp\"\n interpretation_identifier = (([copublisher] space code space ((interpretation_code interp_keyword) / ((\"–\" / dash) 1*digit as interpretation_year [interp_keyword]))) as interpretation) / (([copublisher] space code interp_keyword) as interpretation)\n publication_identifier = (([copublisher] space \"Publication\" as publication_keyword space code [(dash year_digits as year)] [(space revision)] [(space reaffirmation)]) as publication)\n standard_identifier = (([copublisher] space [type as type] [space] code [(dash year_digits as year)] [(space additional_copublisher)] [suffix] [(space reaffirmation)]) as standard)\n identifier = interpretation_identifier / publication_identifier / standard_identifier\n year_digits = ((\"19\" / \"20\") 2*digit / 2*digit)\n letter = %x41-5A / %x61-7A\n digit = %x30-39\n dash = \"-\"\n dot = \".\"\n slash = \"/\"\n space = \" \"\n entry identifier: identifier\n\n test {\n accept \"AMCA 500-D\"\n accept \"AMCA Standard 210\"\n accept \"ANSI/AMCA 210\"\n reject \"nonsense\"\n }\n}\n","source_hash":"ac95e8697ba2f8fd5e272a80b7fa3705cfac6e9efac3bd4e7fc9630cb3ebb30a","compiler_version":"1.3.93","checksum":"sha256:9774e9505d23cef48fe63e1caeea198ca729e4f200f1a95ff0607d04036b4c42"}
1
+ {"bindings":null,"version":"0.1.0","grammar":"PubidAmca","shape":"parsanol-tree/v2","binding_version":1,"entries":{"identifier":{"root":"identifier","grammar":{"atoms":[{"Entity":{"atom":62}},{"Entity":{"atom":8}},{"Str":{"pattern":"ANSI"}},{"Str":{"pattern":"/"}},{"Str":{"pattern":"AMCA"}},{"Sequence":{"atoms":[2,3,4]}},{"Str":{"pattern":"AMCA"}},{"Alternative":{"atoms":[5,6]}},{"Named":{"name":"copublisher","atom":7}},{"Repetition":{"atom":1,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":26}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":12,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[15,16]}},{"Sequence":{"atoms":[14,17]}},{"Repetition":{"atom":18,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"."}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":21,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[20,22]}},{"Repetition":{"atom":23,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[13,19,24]}},{"Named":{"name":"code","atom":25}},{"Str":{"pattern":" "}},{"Entity":{"atom":36}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[29,30]}},{"Repetition":{"atom":31,"min":2,"max":null,"tag":"Repetition"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":33,"min":1,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[32,34]}},{"Named":{"name":"interpretation_code","atom":35}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Interp"}},{"Sequence":{"atoms":[28,37,38]}},{"Str":{"pattern":"–"}},{"Str":{"pattern":"-"}},{"Alternative":{"atoms":[40,41]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":43,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"interpretation_year","atom":44}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Interp"}},{"Sequence":{"atoms":[46,47]}},{"Repetition":{"atom":48,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[42,45,49]}},{"Alternative":{"atoms":[39,50]}},{"Sequence":{"atoms":[9,10,11,27,51]}},{"Named":{"name":"interpretation","atom":52}},{"Entity":{"atom":8}},{"Repetition":{"atom":54,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":26}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Interp"}},{"Sequence":{"atoms":[55,56,57,58,59]}},{"Named":{"name":"interpretation","atom":60}},{"Alternative":{"atoms":[53,61]}},{"Entity":{"atom":114}},{"Entity":{"atom":8}},{"Repetition":{"atom":64,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Publication"}},{"Named":{"name":"publication_keyword","atom":67}},{"Str":{"pattern":" "}},{"Entity":{"atom":26}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[72,73]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":75,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[74,76]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":78,"min":2,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[77,79]}},{"Named":{"name":"year","atom":80}},{"Sequence":{"atoms":[71,81]}},{"Repetition":{"atom":82,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":99}},{"Str":{"pattern":"("}},{"Str":{"pattern":"Rev"}},{"Str":{"pattern":"."}},{"Repetition":{"atom":88,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":91,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":94,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[92,93,95]}},{"Named":{"name":"revision","atom":96}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[86,87,89,90,97,98]}},{"Sequence":{"atoms":[84,85]}},{"Repetition":{"atom":100,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":110}},{"Str":{"pattern":"("}},{"Str":{"pattern":"R"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":106,"min":1,"max":null,"tag":"Repetition"}},{"Named":{"name":"reaffirmed","atom":107}},{"Str":{"pattern":")"}},{"Sequence":{"atoms":[104,105,108,109]}},{"Sequence":{"atoms":[102,103]}},{"Repetition":{"atom":111,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[65,66,68,69,70,83,101,112]}},{"Named":{"name":"publication","atom":113}},{"Entity":{"atom":165}},{"Entity":{"atom":8}},{"Repetition":{"atom":116,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"Standard"}},{"Str":{"pattern":"Publication"}},{"Alternative":{"atoms":[119,120]}},{"Named":{"name":"type","atom":121}},{"Repetition":{"atom":122,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Repetition":{"atom":124,"min":0,"max":1,"tag":"Maybe"}},{"Entity":{"atom":26}},{"Str":{"pattern":"-"}},{"Str":{"pattern":"19"}},{"Str":{"pattern":"20"}},{"Alternative":{"atoms":[128,129]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":131,"min":2,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[130,132]}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":134,"min":2,"max":null,"tag":"Repetition"}},{"Alternative":{"atoms":[133,135]}},{"Named":{"name":"year","atom":136}},{"Sequence":{"atoms":[127,137]}},{"Repetition":{"atom":138,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Str":{"pattern":"/"}},{"Re":{"pattern":"[\\x41-\\x5a]"}},{"Re":{"pattern":"[\\x61-\\x7a]"}},{"Alternative":{"atoms":[142,143]}},{"Repetition":{"atom":144,"min":2,"max":10,"tag":"Repetition"}},{"Str":{"pattern":" "}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":147,"min":1,"max":null,"tag":"Repetition"}},{"Str":{"pattern":"-"}},{"Re":{"pattern":"[\\x30-\\x39]"}},{"Repetition":{"atom":150,"min":1,"max":null,"tag":"Repetition"}},{"Sequence":{"atoms":[149,151]}},{"Repetition":{"atom":152,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[140,141,145,146,148,153]}},{"Repetition":{"atom":154,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":"R"}},{"Str":{"pattern":"P"}},{"Alternative":{"atoms":[156,157]}},{"Repetition":{"atom":158,"min":0,"max":1,"tag":"Maybe"}},{"Str":{"pattern":" "}},{"Entity":{"atom":110}},{"Sequence":{"atoms":[160,161]}},{"Repetition":{"atom":162,"min":0,"max":1,"tag":"Maybe"}},{"Sequence":{"atoms":[117,118,123,125,126,139,155,159,163]}},{"Named":{"name":"standard","atom":164}},{"Alternative":{"atoms":[0,63,115]}}],"root":166},"bindings":[{"capture":"interpretation","path":"interpretation","type":"raw","card":null,"preprocess":null},{"capture":"copublisher","path":"copublisher","type":"string","card":null,"preprocess":null},{"capture":"code","path":"code","type":"string","card":null,"preprocess":null},{"capture":"type","path":"type","type":"string","card":null,"preprocess":null},{"capture":"reaffirmed","path":"reaffirmed","type":"string","card":null,"preprocess":null},{"capture":"revision","path":"revision","type":"string","card":null,"preprocess":null},{"capture":"interpretation_code","path":"interpretation_code","type":"string","card":null,"preprocess":null},{"capture":"interpretation_year","path":"interpretation_year","type":"string","card":null,"preprocess":null},{"capture":"publication_keyword","path":"publication_keyword","type":"string","card":null,"preprocess":null},{"capture":"year","path":"year","type":"string","card":null,"preprocess":null}]}},"preprocess":{},"tables":{},"lint":{"order_warnings":["rule interpretation_identifier: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 2 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 1 and 3 are order-dependent (shared first bytes; ordered choice is decisive)","rule identifier: branches 2 and 3 are order-dependent (shared first bytes; ordered choice is decisive)"]},"default_entry":"identifier","render":{},"derive":{},"tests":[{"entry":"identifier","kind":"accept","input":"AMCA 500-D","expect":{}},{"entry":"identifier","kind":"accept","input":"AMCA Standard 210","expect":{}},{"entry":"identifier","kind":"accept","input":"ANSI/AMCA 210","expect":{}},{"entry":"identifier","kind":"reject","input":"nonsense","expect":{}}],"docs":{},"source":"# Port of lib/pubid/amca/parser.rb. Pre-parse whitespace collapsing,\n# en-dash normalization and trailing punctuation stripping stay\n# binder-side.\n#\n# Edition 2: every reference inside a captured body is inlined to raw\n# terms (a rule reference materializes as a named node in the edition-2\n# tree, so only a raw capture binds a scalar span); references to rules\n# that themselves capture (copublisher, code, reaffirmation) float their\n# captures unchanged. The type wrappers (interpretation, publication,\n# standard) keep the v1 tree shape and the bindings name the scalar\n# leaves.\n\ngrammar PubidAmca version \"0.1.0\" edition 2 {\n copublisher = ((\"ANSI\" \"/\" \"AMCA\") / \"AMCA\") as copublisher\n code = {\n ( 1*%x30-39\n [(\"-\" (%x41-5A / %x61-7A))]\n [(\".\" 1*%x30-39)] ) as code\n }\n reaffirmation = \"(\" \"R\" (1*%x30-39) as reaffirmed \")\"\n revision = \"(\" \"Rev\" [\".\"] \" \" (1*%x30-39 \"-\" 1*%x30-39) as revision \")\"\n interpretation_code = (2*(%x41-5A / %x61-7A) / 1*%x30-39) as interpretation_code\n\n interpretation_identifier = {\n (\n ( [copublisher] \" \" code \" \"\n ( (interpretation_code \" \" \"Interp\")\n / ((\"–\" / \"-\") (1*%x30-39) as interpretation_year [\" \" \"Interp\"]) )\n ) as interpretation\n )\n /\n (\n ( [copublisher] \" \" code \" \" \"Interp\" ) as interpretation\n )\n }\n publication_identifier = {\n (\n ( [copublisher] \" \" \"Publication\" as publication_keyword \" \" code\n [(\"-\" (((\"19\" / \"20\") 2*%x30-39) / (2*%x30-39)) as year)]\n [(\" \" revision)]\n [(\" \" reaffirmation)] ) as publication\n )\n }\n standard_identifier = {\n (\n ( [copublisher] \" \" [(\"Standard\" / \"Publication\") as type] [\" \"] code\n [(\"-\" (((\"19\" / \"20\") 2*%x30-39) / (2*%x30-39)) as year)]\n [(\" \" \"/\" 2*10(%x41-5A / %x61-7A) \" \" 1*%x30-39 [(\"-\" 1*%x30-39)])]\n [(\"R\" / \"P\")]\n [(\" \" reaffirmation)] ) as standard\n )\n }\n identifier = interpretation_identifier / publication_identifier / standard_identifier\n\n entry identifier: identifier\n\n test {\n accept \"AMCA 500-D\"\n accept \"AMCA Standard 210\"\n accept \"ANSI/AMCA 210\"\n reject \"nonsense\"\n }\n\n bindings identifier {\n # The builder dispatches interpretation on the :interpretation wrapper\n # when the code/keyword leaves are absent (branch 2 spellings), so the\n # wrapper binds raw — the nested hash build_interpretation walks.\n interpretation -> interpretation (raw)\n copublisher -> copublisher (string)\n code -> code (string)\n type -> type (string)\n reaffirmed -> reaffirmed (string)\n revision -> revision (string)\n interpretation_code -> interpretation_code (string)\n interpretation_year -> interpretation_year (string)\n publication_keyword -> publication_keyword (string)\n year -> year (string)\n }\n}\n","source_hash":"bceecc759a9fa419b558c9df856323bc3c9ca9d0e3ebccde9ed6a37695794a9c","unicode_tables":"onigmo (Ruby 3.4.8)","compiler_version":"1.3.121","edition":2,"semantics_hash":"sha256:15bec081203edf351402d06b6e26bf8ba5a4dcfee87e6142636b1b2a9754d194","checksum":"sha256:5f45ba71d8f371f5f1438cceb06924d1ac9e634c57684055a7900a1bec303798"}