1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | const RHS_1 = require("./RHS");
|
13 | const GrammarAnnotation_1 = require("./GrammarAnnotation");
|
14 | const Terminal_1 = require("./Terminal");
|
15 | const Builder_1 = require("./Builder");
|
16 | const utils = require("./utils");
|
17 |
|
18 | class Production extends Builder_1.default {
|
19 | constructor(spec, node, namespace) {
|
20 | super(spec, node);
|
21 | this.type = node.getAttribute('type');
|
22 | this.name = node.getAttribute('name');
|
23 | this.params = node.getAttribute('params');
|
24 | this.optional = node.hasAttribute('optional');
|
25 | this.oneOf = node.hasAttribute('oneof');
|
26 | this.rhses = [];
|
27 | this.rhsesById = {};
|
28 | this.namespace = namespace;
|
29 | const rhses = this.node.querySelectorAll('emu-rhs');
|
30 | for (let i = 0; i < rhses.length; i++) {
|
31 | const rhs = new RHS_1.default(this.spec, this, rhses[i]);
|
32 | this.rhses.push(rhs);
|
33 | if (rhs.alternativeId) {
|
34 | this.rhsesById[rhs.alternativeId] = rhs;
|
35 | }
|
36 | }
|
37 | const id = this._id();
|
38 | const entry = this.spec.biblio.byProductionName(this.name, this.namespace);
|
39 | let primary = false;
|
40 | if (node.hasAttribute('primary')) {
|
41 | primary = true;
|
42 | }
|
43 | else {
|
44 | let parent = node.parentElement;
|
45 | if (parent != null) {
|
46 |
|
47 | while (parent.tagName === 'INS' || parent.tagName === 'MARK') {
|
48 | parent = parent.parentElement;
|
49 | if (parent == null) {
|
50 | break;
|
51 | }
|
52 | }
|
53 | if (parent != null && parent.tagName === 'EMU-GRAMMAR') {
|
54 | primary = parent.hasAttribute('primary') || parent.getAttribute('type') === 'definition';
|
55 | }
|
56 | }
|
57 | }
|
58 | this.primary = primary;
|
59 | if (this.primary) {
|
60 | this.id = id;
|
61 | if (entry && entry.namespace === this.namespace && entry._instance) {
|
62 | entry._instance.primary = false;
|
63 | entry._instance.node.removeAttribute('id');
|
64 | }
|
65 | const newEntry = {
|
66 | type: 'production',
|
67 | id,
|
68 | name: this.name,
|
69 | };
|
70 |
|
71 | Object.defineProperty(newEntry, '_instance', { value: this });
|
72 | this.spec.biblio.add(newEntry, this.namespace);
|
73 | }
|
74 | }
|
75 | _id() {
|
76 | if (this.namespace && this.namespace !== this.spec.namespace) {
|
77 | return `prod-${this.namespace}-${this.name}`;
|
78 | }
|
79 | else {
|
80 | return `prod-${this.name}`;
|
81 | }
|
82 | }
|
83 | static enter({ spec, node, clauseStack }) {
|
84 | return __awaiter(this, void 0, void 0, function* () {
|
85 | const ntNode = spec.doc.createElement('emu-nt');
|
86 | const clause = clauseStack[clauseStack.length - 1];
|
87 | const prod = new Production(spec, node, clause ? clause.namespace : spec.namespace);
|
88 | ntNode.innerHTML = '<a href="#prod-' + prod.name + '">' + prod.name + '</a>';
|
89 | if (prod.params)
|
90 | ntNode.setAttribute('params', prod.params);
|
91 | if (prod.optional)
|
92 | ntNode.setAttribute('optional', '');
|
93 | node.insertBefore(ntNode, node.children[0]);
|
94 | const geq = spec.doc.createElement('emu-geq');
|
95 | if (prod.type === 'lexical') {
|
96 | geq.textContent = '::';
|
97 | }
|
98 | else if (prod.type === 'regexp') {
|
99 | geq.textContent = ':::';
|
100 | }
|
101 | else {
|
102 | geq.textContent = ':';
|
103 | }
|
104 | node.insertBefore(spec.doc.createTextNode(' '), ntNode.nextSibling);
|
105 | node.insertBefore(geq, ntNode.nextSibling);
|
106 | node.insertBefore(spec.doc.createTextNode(' '), ntNode.nextSibling);
|
107 | if (prod.oneOf) {
|
108 | const elem = spec.doc.createElement('emu-oneof');
|
109 | elem.textContent = 'one of';
|
110 | node.insertBefore(elem, geq.nextSibling);
|
111 | node.insertBefore(spec.doc.createTextNode(' '), elem);
|
112 | }
|
113 | prod.rhses.forEach(rhs => rhs.build());
|
114 | const ganns = node.querySelectorAll('emu-gann');
|
115 | for (let i = 0; i < ganns.length; i++) {
|
116 | new GrammarAnnotation_1.default(spec, prod, ganns[i]).build();
|
117 | }
|
118 | const ts = node.querySelectorAll('emu-t');
|
119 | for (let i = 0; i < ts.length; i++) {
|
120 | new Terminal_1.default(spec, prod, ts[i]).build();
|
121 | }
|
122 | if (prod.primary) {
|
123 | node.setAttribute('id', prod.id);
|
124 | }
|
125 | if (utils.shouldInline(node)) {
|
126 | const cls = node.getAttribute('class') || '';
|
127 | if (cls.indexOf('inline') === -1) {
|
128 | node.setAttribute('class', cls + ' inline');
|
129 | }
|
130 | }
|
131 | });
|
132 | }
|
133 | }
|
134 | exports.default = Production;
|
135 | Production.byName = {};
|
136 | Production.elements = ['EMU-PRODUCTION'];
|