UNPKG

@foxglove/omgidl-parser

Version:

Parse OMG IDL to flattened definitions for serialization

1,232 lines (1,112 loc) 105 kB
/******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 694: /***/ (function(module, exports) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(root, factory) { if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) /* global define */ } else {} }(this, function() { 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty var toString = Object.prototype.toString var hasSticky = typeof new RegExp().sticky === 'boolean' /***************************************************************************/ function isRegExp(o) { return o && toString.call(o) === '[object RegExp]' } function isObject(o) { return o && typeof o === 'object' && !isRegExp(o) && !Array.isArray(o) } function reEscape(s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') } function reGroups(s) { var re = new RegExp('|' + s) return re.exec('').length - 1 } function reCapture(s) { return '(' + s + ')' } function reUnion(regexps) { if (!regexps.length) return '(?!)' var source = regexps.map(function(s) { return "(?:" + s + ")" }).join('|') return "(?:" + source + ")" } function regexpOrLiteral(obj) { if (typeof obj === 'string') { return '(?:' + reEscape(obj) + ')' } else if (isRegExp(obj)) { // TODO: consider /u support if (obj.ignoreCase) throw new Error('RegExp /i flag not allowed') if (obj.global) throw new Error('RegExp /g flag is implied') if (obj.sticky) throw new Error('RegExp /y flag is implied') if (obj.multiline) throw new Error('RegExp /m flag is implied') return obj.source } else { throw new Error('Not a pattern: ' + obj) } } function pad(s, length) { if (s.length > length) { return s } return Array(length - s.length + 1).join(" ") + s } function lastNLines(string, numLines) { var position = string.length var lineBreaks = 0; while (true) { var idx = string.lastIndexOf("\n", position - 1) if (idx === -1) { break; } else { lineBreaks++ } position = idx if (lineBreaks === numLines) { break; } if (position === 0) { break; } } var startPosition = lineBreaks < numLines ? 0 : position + 1 return string.substring(startPosition).split("\n") } function objectToRules(object) { var keys = Object.getOwnPropertyNames(object) var result = [] for (var i = 0; i < keys.length; i++) { var key = keys[i] var thing = object[key] var rules = [].concat(thing) if (key === 'include') { for (var j = 0; j < rules.length; j++) { result.push({include: rules[j]}) } continue } var match = [] rules.forEach(function(rule) { if (isObject(rule)) { if (match.length) result.push(ruleOptions(key, match)) result.push(ruleOptions(key, rule)) match = [] } else { match.push(rule) } }) if (match.length) result.push(ruleOptions(key, match)) } return result } function arrayToRules(array) { var result = [] for (var i = 0; i < array.length; i++) { var obj = array[i] if (obj.include) { var include = [].concat(obj.include) for (var j = 0; j < include.length; j++) { result.push({include: include[j]}) } continue } if (!obj.type) { throw new Error('Rule has no type: ' + JSON.stringify(obj)) } result.push(ruleOptions(obj.type, obj)) } return result } function ruleOptions(type, obj) { if (!isObject(obj)) { obj = { match: obj } } if (obj.include) { throw new Error('Matching rules cannot also include states') } // nb. error and fallback imply lineBreaks var options = { defaultType: type, lineBreaks: !!obj.error || !!obj.fallback, pop: false, next: null, push: null, error: false, fallback: false, value: null, type: null, shouldThrow: false, } // Avoid Object.assign(), so we support IE9+ for (var key in obj) { if (hasOwnProperty.call(obj, key)) { options[key] = obj[key] } } // type transform cannot be a string if (typeof options.type === 'string' && type !== options.type) { throw new Error("Type transform cannot be a string (type '" + options.type + "' for token '" + type + "')") } // convert to array var match = options.match options.match = Array.isArray(match) ? match : match ? [match] : [] options.match.sort(function(a, b) { return isRegExp(a) && isRegExp(b) ? 0 : isRegExp(b) ? -1 : isRegExp(a) ? +1 : b.length - a.length }) return options } function toRules(spec) { return Array.isArray(spec) ? arrayToRules(spec) : objectToRules(spec) } var defaultErrorRule = ruleOptions('error', {lineBreaks: true, shouldThrow: true}) function compileRules(rules, hasStates) { var errorRule = null var fast = Object.create(null) var fastAllowed = true var unicodeFlag = null var groups = [] var parts = [] // If there is a fallback rule, then disable fast matching for (var i = 0; i < rules.length; i++) { if (rules[i].fallback) { fastAllowed = false } } for (var i = 0; i < rules.length; i++) { var options = rules[i] if (options.include) { // all valid inclusions are removed by states() preprocessor throw new Error('Inheritance is not allowed in stateless lexers') } if (options.error || options.fallback) { // errorRule can only be set once if (errorRule) { if (!options.fallback === !errorRule.fallback) { throw new Error("Multiple " + (options.fallback ? "fallback" : "error") + " rules not allowed (for token '" + options.defaultType + "')") } else { throw new Error("fallback and error are mutually exclusive (for token '" + options.defaultType + "')") } } errorRule = options } var match = options.match.slice() if (fastAllowed) { while (match.length && typeof match[0] === 'string' && match[0].length === 1) { var word = match.shift() fast[word.charCodeAt(0)] = options } } // Warn about inappropriate state-switching options if (options.pop || options.push || options.next) { if (!hasStates) { throw new Error("State-switching options are not allowed in stateless lexers (for token '" + options.defaultType + "')") } if (options.fallback) { throw new Error("State-switching options are not allowed on fallback tokens (for token '" + options.defaultType + "')") } } // Only rules with a .match are included in the RegExp if (match.length === 0) { continue } fastAllowed = false groups.push(options) // Check unicode flag is used everywhere or nowhere for (var j = 0; j < match.length; j++) { var obj = match[j] if (!isRegExp(obj)) { continue } if (unicodeFlag === null) { unicodeFlag = obj.unicode } else if (unicodeFlag !== obj.unicode && options.fallback === false) { throw new Error('If one rule is /u then all must be') } } // convert to RegExp var pat = reUnion(match.map(regexpOrLiteral)) // validate var regexp = new RegExp(pat) if (regexp.test("")) { throw new Error("RegExp matches empty string: " + regexp) } var groupCount = reGroups(pat) if (groupCount > 0) { throw new Error("RegExp has capture groups: " + regexp + "\nUse (?: … ) instead") } // try and detect rules matching newlines if (!options.lineBreaks && regexp.test('\n')) { throw new Error('Rule should declare lineBreaks: ' + regexp) } // store regex parts.push(reCapture(pat)) } // If there's no fallback rule, use the sticky flag so we only look for // matches at the current index. // // If we don't support the sticky flag, then fake it using an irrefutable // match (i.e. an empty pattern). var fallbackRule = errorRule && errorRule.fallback var flags = hasSticky && !fallbackRule ? 'ym' : 'gm' var suffix = hasSticky || fallbackRule ? '' : '|' if (unicodeFlag === true) flags += "u" var combined = new RegExp(reUnion(parts) + suffix, flags) return {regexp: combined, groups: groups, fast: fast, error: errorRule || defaultErrorRule} } function compile(rules) { var result = compileRules(toRules(rules)) return new Lexer({start: result}, 'start') } function checkStateGroup(g, name, map) { var state = g && (g.push || g.next) if (state && !map[state]) { throw new Error("Missing state '" + state + "' (in token '" + g.defaultType + "' of state '" + name + "')") } if (g && g.pop && +g.pop !== 1) { throw new Error("pop must be 1 (in token '" + g.defaultType + "' of state '" + name + "')") } } function compileStates(states, start) { var all = states.$all ? toRules(states.$all) : [] delete states.$all var keys = Object.getOwnPropertyNames(states) if (!start) start = keys[0] var ruleMap = Object.create(null) for (var i = 0; i < keys.length; i++) { var key = keys[i] ruleMap[key] = toRules(states[key]).concat(all) } for (var i = 0; i < keys.length; i++) { var key = keys[i] var rules = ruleMap[key] var included = Object.create(null) for (var j = 0; j < rules.length; j++) { var rule = rules[j] if (!rule.include) continue var splice = [j, 1] if (rule.include !== key && !included[rule.include]) { included[rule.include] = true var newRules = ruleMap[rule.include] if (!newRules) { throw new Error("Cannot include nonexistent state '" + rule.include + "' (in state '" + key + "')") } for (var k = 0; k < newRules.length; k++) { var newRule = newRules[k] if (rules.indexOf(newRule) !== -1) continue splice.push(newRule) } } rules.splice.apply(rules, splice) j-- } } var map = Object.create(null) for (var i = 0; i < keys.length; i++) { var key = keys[i] map[key] = compileRules(ruleMap[key], true) } for (var i = 0; i < keys.length; i++) { var name = keys[i] var state = map[name] var groups = state.groups for (var j = 0; j < groups.length; j++) { checkStateGroup(groups[j], name, map) } var fastKeys = Object.getOwnPropertyNames(state.fast) for (var j = 0; j < fastKeys.length; j++) { checkStateGroup(state.fast[fastKeys[j]], name, map) } } return new Lexer(map, start) } function keywordTransform(map) { // Use a JavaScript Map to map keywords to their corresponding token type // unless Map is unsupported, then fall back to using an Object: var isMap = typeof Map !== 'undefined' var reverseMap = isMap ? new Map : Object.create(null) var types = Object.getOwnPropertyNames(map) for (var i = 0; i < types.length; i++) { var tokenType = types[i] var item = map[tokenType] var keywordList = Array.isArray(item) ? item : [item] keywordList.forEach(function(keyword) { if (typeof keyword !== 'string') { throw new Error("keyword must be string (in keyword '" + tokenType + "')") } if (isMap) { reverseMap.set(keyword, tokenType) } else { reverseMap[keyword] = tokenType } }) } return function(k) { return isMap ? reverseMap.get(k) : reverseMap[k] } } /***************************************************************************/ var Lexer = function(states, state) { this.startState = state this.states = states this.buffer = '' this.stack = [] this.reset() } Lexer.prototype.reset = function(data, info) { this.buffer = data || '' this.index = 0 this.line = info ? info.line : 1 this.col = info ? info.col : 1 this.queuedToken = info ? info.queuedToken : null this.queuedText = info ? info.queuedText: ""; this.queuedThrow = info ? info.queuedThrow : null this.setState(info ? info.state : this.startState) this.stack = info && info.stack ? info.stack.slice() : [] return this } Lexer.prototype.save = function() { return { line: this.line, col: this.col, state: this.state, stack: this.stack.slice(), queuedToken: this.queuedToken, queuedText: this.queuedText, queuedThrow: this.queuedThrow, } } Lexer.prototype.setState = function(state) { if (!state || this.state === state) return this.state = state var info = this.states[state] this.groups = info.groups this.error = info.error this.re = info.regexp this.fast = info.fast } Lexer.prototype.popState = function() { this.setState(this.stack.pop()) } Lexer.prototype.pushState = function(state) { this.stack.push(this.state) this.setState(state) } var eat = hasSticky ? function(re, buffer) { // assume re is /y return re.exec(buffer) } : function(re, buffer) { // assume re is /g var match = re.exec(buffer) // will always match, since we used the |(?:) trick if (match[0].length === 0) { return null } return match } Lexer.prototype._getGroup = function(match) { var groupCount = this.groups.length for (var i = 0; i < groupCount; i++) { if (match[i + 1] !== undefined) { return this.groups[i] } } throw new Error('Cannot find token type for matched text') } function tokenToString() { return this.value } Lexer.prototype.next = function() { var index = this.index // If a fallback token matched, we don't need to re-run the RegExp if (this.queuedGroup) { var token = this._token(this.queuedGroup, this.queuedText, index) this.queuedGroup = null this.queuedText = "" return token } var buffer = this.buffer if (index === buffer.length) { return // EOF } // Fast matching for single characters var group = this.fast[buffer.charCodeAt(index)] if (group) { return this._token(group, buffer.charAt(index), index) } // Execute RegExp var re = this.re re.lastIndex = index var match = eat(re, buffer) // Error tokens match the remaining buffer var error = this.error if (match == null) { return this._token(error, buffer.slice(index, buffer.length), index) } var group = this._getGroup(match) var text = match[0] if (error.fallback && match.index !== index) { this.queuedGroup = group this.queuedText = text // Fallback tokens contain the unmatched portion of the buffer return this._token(error, buffer.slice(index, match.index), index) } return this._token(group, text, index) } Lexer.prototype._token = function(group, text, offset) { // count line breaks var lineBreaks = 0 if (group.lineBreaks) { var matchNL = /\n/g var nl = 1 if (text === '\n') { lineBreaks = 1 } else { while (matchNL.exec(text)) { lineBreaks++; nl = matchNL.lastIndex } } } var token = { type: (typeof group.type === 'function' && group.type(text)) || group.defaultType, value: typeof group.value === 'function' ? group.value(text) : text, text: text, toString: tokenToString, offset: offset, lineBreaks: lineBreaks, line: this.line, col: this.col, } // nb. adding more props to token object will make V8 sad! var size = text.length this.index += size this.line += lineBreaks if (lineBreaks !== 0) { this.col = size - nl + 1 } else { this.col += size } // throw, if no rule with {error: true} if (group.shouldThrow) { var err = new Error(this.formatError(token, "invalid syntax")) throw err; } if (group.pop) this.popState() else if (group.push) this.pushState(group.push) else if (group.next) this.setState(group.next) return token } if (typeof Symbol !== 'undefined' && Symbol.iterator) { var LexerIterator = function(lexer) { this.lexer = lexer } LexerIterator.prototype.next = function() { var token = this.lexer.next() return {value: token, done: !token} } LexerIterator.prototype[Symbol.iterator] = function() { return this } Lexer.prototype[Symbol.iterator] = function() { return new LexerIterator(this) } } Lexer.prototype.formatError = function(token, message) { if (token == null) { // An undefined token indicates EOF var text = this.buffer.slice(this.index) var token = { text: text, offset: this.index, lineBreaks: text.indexOf('\n') === -1 ? 0 : 1, line: this.line, col: this.col, } } var numLinesAround = 2 var firstDisplayedLine = Math.max(token.line - numLinesAround, 1) var lastDisplayedLine = token.line + numLinesAround var lastLineDigits = String(lastDisplayedLine).length var displayedLines = lastNLines( this.buffer, (this.line - token.line) + numLinesAround + 1 ) .slice(0, 5) var errorLines = [] errorLines.push(message + " at line " + token.line + " col " + token.col + ":") errorLines.push("") for (var i = 0; i < displayedLines.length; i++) { var line = displayedLines[i] var lineNo = firstDisplayedLine + i errorLines.push(pad(String(lineNo), lastLineDigits) + " " + line); if (lineNo === token.line) { errorLines.push(pad("", lastLineDigits + token.col + 1) + "^") } } return errorLines.join("\n") } Lexer.prototype.clone = function() { return new Lexer(this.states, this.state) } Lexer.prototype.has = function(tokenType) { return true } return { compile: compile, states: compileStates, error: Object.freeze({error: true}), fallback: Object.freeze({fallback: true}), keywords: keywordTransform, } })); /***/ }), /***/ 506: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { // Generated automatically by nearley, version unknown // http://github.com/Hardmath123/nearley (function () { function id(x) { return x[0]; } // necessary to use keywords to avoid using the `reject` postprocessor which can cause poor perf // having these as keywords removes ambiguity with `customType` rule const keywords = [ , "struct" , "module" , "enum" , "const" , "typedef" , "union" , "switch" , "case" //types , "boolean" , "wstring" , "string" , "sequence" // Boolean types , "TRUE" , "FALSE" // numeric types , "byte" , "octet" , "wchar" , "char" , "double" , "float" , "int8" , "uint8" , "int16" , "uint16" , "int32" , "uint32" , "int64" , "uint64" , "unsigned" , "short" , "long" ]; const kwObject = keywords.reduce((obj, w) => { obj[w] = w; return obj; }, {}); const moo = __webpack_require__(694); // Terminal tokens are in all caps const lexer = moo.compile({ SPACE: {match: /\s+/, lineBreaks: true}, DECIMALEXP: /(?:(?:\d+\.\d*)|(?:\d*\.\d+)|(?:[0-9]+))[eE](?:[+|-])?[0-9]+/, DECIMAL: /(?:(?:\d+\.\d*)|(?:\d*\.\d+))/, INTEGER: /0[xX][0-9a-fA-F]+|\d+/, COMMENT: /(?:\/\/[^\n]*)|(?:\/\*(?:.|\n)+?\*\/)/, STRING: {match: /"(?:\\["\\rnu]|[^"\\])*"/, value: x => x.slice(1, -1)}, // remove outside quotes LCBR: '{', RCBR: '}', LBR: '[', RBR: ']', LT: '<', GT: '>', LPAR: '(', RPAR: ')', ':': ':', ';': ';', ',': ',', AT: '@', PND: '#', PT: ".", '/': "/", SIGN: /[+-]/, EQ: /=[^\n]*?/, NAME: {match: /[a-zA-Z_][a-zA-Z0-9_]*(?:\:\:[a-zA-Z][a-zA-Z0-9_]*)*/, type: moo.keywords(kwObject)}, }); // Ignore whitespace and comment tokens const tokensToIgnore = ['SPACE', 'COMMENT']; // requires us to override the lexer's next function lexer.next = (next => () => { let token; while ((token = next.call(lexer)) && tokensToIgnore.includes(token.type)) {} return token; })(lexer.next); /*** Utility functions ******/ // also used to parse tokens to strings since they start as an object function join(d){ return d.join(""); } // used for combining AST components function extend(objs) { return objs.filter(Boolean).reduce((r, p) => ({ ...r, ...p }), {}); } function noop() { return null; } function getIntOrConstantValue(d) { const int = parseInt(d); if(!isNaN(int)) { return int; } // handle %NAME token return d?.value ? {usesConstant: true, name: d.value} : undefined; } var grammar = { Lexer: lexer, ParserRules: [ {"name": "main$ebnf$1$subexpression$1$ebnf$1", "symbols": []}, {"name": "main$ebnf$1$subexpression$1$ebnf$1", "symbols": ["main$ebnf$1$subexpression$1$ebnf$1", "importDcl"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "main$ebnf$1$subexpression$1", "symbols": ["main$ebnf$1$subexpression$1$ebnf$1", "definition"]}, {"name": "main$ebnf$1", "symbols": ["main$ebnf$1$subexpression$1"]}, {"name": "main$ebnf$1$subexpression$2$ebnf$1", "symbols": []}, {"name": "main$ebnf$1$subexpression$2$ebnf$1", "symbols": ["main$ebnf$1$subexpression$2$ebnf$1", "importDcl"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "main$ebnf$1$subexpression$2", "symbols": ["main$ebnf$1$subexpression$2$ebnf$1", "definition"]}, {"name": "main$ebnf$1", "symbols": ["main$ebnf$1", "main$ebnf$1$subexpression$2"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "main", "symbols": ["main$ebnf$1"], "postprocess": d => { return d[0].flatMap(inner => inner[1]); } }, {"name": "importDcl$subexpression$1", "symbols": [(lexer.has("STRING") ? {type: "STRING"} : STRING)]}, {"name": "importDcl$subexpression$1$ebnf$1", "symbols": []}, {"name": "importDcl$subexpression$1$ebnf$1$subexpression$1", "symbols": [{"literal":"/"}, (lexer.has("NAME") ? {type: "NAME"} : NAME)]}, {"name": "importDcl$subexpression$1$ebnf$1", "symbols": ["importDcl$subexpression$1$ebnf$1", "importDcl$subexpression$1$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "importDcl$subexpression$1", "symbols": [{"literal":"<"}, (lexer.has("NAME") ? {type: "NAME"} : NAME), "importDcl$subexpression$1$ebnf$1", {"literal":"."}, {"literal":"idl"}, {"literal":">"}]}, {"name": "importDcl", "symbols": [{"literal":"#"}, {"literal":"include"}, "importDcl$subexpression$1"], "postprocess": noop}, {"name": "moduleDcl$ebnf$1$subexpression$1", "symbols": ["definition"]}, {"name": "moduleDcl$ebnf$1", "symbols": ["moduleDcl$ebnf$1$subexpression$1"]}, {"name": "moduleDcl$ebnf$1$subexpression$2", "symbols": ["definition"]}, {"name": "moduleDcl$ebnf$1", "symbols": ["moduleDcl$ebnf$1", "moduleDcl$ebnf$1$subexpression$2"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "moduleDcl", "symbols": [{"literal":"module"}, "fieldName", {"literal":"{"}, "moduleDcl$ebnf$1", {"literal":"}"}], "postprocess": function processModule(d) { const moduleName = d[1].name; const defs = d[3]; // need to return array here to keep same signature as processComplexModule return { declarator: "module", name: moduleName, definitions: defs.flat(1), }; } }, {"name": "definition$subexpression$1", "symbols": ["typeDcl"]}, {"name": "definition$subexpression$1", "symbols": ["constantDcl"]}, {"name": "definition$subexpression$1", "symbols": ["moduleDcl"]}, {"name": "definition$subexpression$1", "symbols": ["union"]}, {"name": "definition", "symbols": ["multiAnnotations", "definition$subexpression$1", "semi"], "postprocess": d => { const annotations = d[0]; const declaration = d[1][0]; return extend([annotations, declaration]); }}, {"name": "typeDcl$subexpression$1", "symbols": ["struct"]}, {"name": "typeDcl$subexpression$1", "symbols": ["typedef"]}, {"name": "typeDcl$subexpression$1", "symbols": ["enum"]}, {"name": "typeDcl", "symbols": ["typeDcl$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "union", "symbols": [{"literal":"union"}, "fieldName", {"literal":"switch"}, {"literal":"("}, "switchTypedef", {"literal":")"}, {"literal":"{"}, "switchBody", {"literal":"}"}], "postprocess": (d) => { const name = d[1].name const switchType = d[4].type; const switchBody = d[7]; const allCases = switchBody; const defaultCase = allCases.find(c => "default" in c); const cases = allCases.filter(c => ("predicates" in c)); const unionNode = { declarator: "union", name, switchType, cases, }; if(defaultCase) { unionNode.defaultCase = defaultCase.default; } return unionNode; } }, {"name": "switchTypedef$subexpression$1", "symbols": ["customType"]}, {"name": "switchTypedef$subexpression$1", "symbols": ["numericType"]}, {"name": "switchTypedef$subexpression$1", "symbols": ["booleanType"]}, {"name": "switchTypedef", "symbols": ["switchTypedef$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "switchBody$ebnf$1", "symbols": ["case"]}, {"name": "switchBody$ebnf$1", "symbols": ["switchBody$ebnf$1", "case"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "switchBody", "symbols": ["switchBody$ebnf$1"], "postprocess": d => d.flat(2)}, {"name": "case$ebnf$1", "symbols": ["caseLabel"]}, {"name": "case$ebnf$1", "symbols": ["case$ebnf$1", "caseLabel"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "case", "symbols": ["case$ebnf$1", "elementSpec", {"literal":";"}], "postprocess": d => { const cases = d[0]; const type = d[1] const nonDefaultCases = cases.filter(casePredicate => casePredicate !== "default"); const isDefault = cases.length !== nonDefaultCases.length; const caseArray = [] if(isDefault) { caseArray.push({default: type}); } if(nonDefaultCases.length > 0) { caseArray.push({ predicates: nonDefaultCases, type, }); } return caseArray; }}, {"name": "caseLabel$subexpression$1", "symbols": [{"literal":"case"}, "constExpression", {"literal":":"}]}, {"name": "caseLabel", "symbols": ["caseLabel$subexpression$1"], "postprocess": (d) => d[0][1]}, {"name": "caseLabel$subexpression$2", "symbols": [{"literal":"default"}, {"literal":":"}]}, {"name": "caseLabel", "symbols": ["caseLabel$subexpression$2"], "postprocess": () => "default"}, {"name": "elementSpec", "symbols": ["typeDeclaratorWithAnnotations"], "postprocess": d => d[0]}, {"name": "enum$ebnf$1", "symbols": []}, {"name": "enum$ebnf$1$subexpression$1", "symbols": [{"literal":","}, "enumFieldName"]}, {"name": "enum$ebnf$1", "symbols": ["enum$ebnf$1", "enum$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "enum", "symbols": [{"literal":"enum"}, "fieldName", {"literal":"{"}, "enumFieldName", "enum$ebnf$1", {"literal":"}"}], "postprocess": d => { const name = d[1].name; const firstMember = d[3]; const members = d[4] .flat(2) // need to filter out commas .filter(item => Boolean(item) && item.type !== ","); return { declarator: 'enum', name, enumerators: [firstMember, ...members], }; } }, {"name": "enumFieldName", "symbols": ["multiAnnotations", "fieldName"], "postprocess": d => { const annotations = d[0]; const name = d[1]; return extend([annotations, name]); } }, {"name": "struct$ebnf$1", "symbols": []}, {"name": "struct$ebnf$1$subexpression$1", "symbols": ["member"]}, {"name": "struct$ebnf$1", "symbols": ["struct$ebnf$1", "struct$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "struct", "symbols": [{"literal":"struct"}, "fieldName", {"literal":"{"}, "struct$ebnf$1", {"literal":"}"}], "postprocess": d => { const name = d[1].name; const definitions = d[3].flat(2).filter(def => def !== null); return { declarator: 'struct', name, definitions, }; } }, {"name": "typedef", "symbols": [{"literal":"typedef"}, "typeDeclarator"], "postprocess": ([_, definition]) => ( { declarator: "typedef", ...definition } )}, {"name": "typeDeclaratorWithAnnotations", "symbols": ["multiAnnotations", "typeDeclarator"], "postprocess": d => { const annotations = d[0]; const definition = d[1]; return extend([annotations, definition]); } }, {"name": "typeDeclarator$subexpression$1", "symbols": ["allTypes", "fieldName", "arrayLengths"]}, {"name": "typeDeclarator$subexpression$1", "symbols": ["allTypes", "fieldName"]}, {"name": "typeDeclarator$subexpression$1", "symbols": ["sequenceType", "fieldName"]}, {"name": "typeDeclarator", "symbols": ["typeDeclarator$subexpression$1"], "postprocess": d => extend(d[0])}, {"name": "constantDcl", "symbols": ["constType"], "postprocess": d => d[0]}, {"name": "member", "symbols": ["fieldWithAnnotation", "semi"], "postprocess": d => d[0]}, {"name": "fieldWithAnnotation", "symbols": ["multiAnnotations", "fieldDcl"], "postprocess": d=> { const annotations = d[0] const fields = d[1]; const finalDefs = fields.map((def) => extend([annotations, def]) ); return finalDefs; } }, {"name": "fieldDcl$subexpression$1", "symbols": ["allTypes", "multiFieldNames", "arrayLengths"]}, {"name": "fieldDcl$subexpression$1", "symbols": ["allTypes", "multiFieldNames"]}, {"name": "fieldDcl$subexpression$1", "symbols": ["sequenceType", "multiFieldNames"]}, {"name": "fieldDcl", "symbols": ["fieldDcl$subexpression$1"], "postprocess": (d) => { const names = d[0].splice(1, 1)[0]; // create a definition for each name const defs = names.map((nameObj) => ({ ...extend([...d[0], nameObj]), declarator: "struct-member" })); return defs; } }, {"name": "multiFieldNames$ebnf$1", "symbols": []}, {"name": "multiFieldNames$ebnf$1$subexpression$1", "symbols": [{"literal":","}, "fieldName"]}, {"name": "multiFieldNames$ebnf$1", "symbols": ["multiFieldNames$ebnf$1", "multiFieldNames$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "multiFieldNames", "symbols": ["fieldName", "multiFieldNames$ebnf$1"], "postprocess": d => { const fieldNames = d.flat(2).filter( d => d !== null && d.name); return fieldNames; } }, {"name": "multiAnnotations$ebnf$1", "symbols": []}, {"name": "multiAnnotations$ebnf$1", "symbols": ["multiAnnotations$ebnf$1", "annotation"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "multiAnnotations", "symbols": ["multiAnnotations$ebnf$1"], "postprocess": d => { return d[0].length > 0 ? {annotations: d[0].reduce((record, annotation) => { record[annotation.name] = annotation; return record; }, {}) } : null; } }, {"name": "annotation$ebnf$1$subexpression$1", "symbols": [{"literal":"("}, "annotationParams", {"literal":")"}]}, {"name": "annotation$ebnf$1", "symbols": ["annotation$ebnf$1$subexpression$1"], "postprocess": id}, {"name": "annotation$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}}, {"name": "annotation", "symbols": ["at", (lexer.has("NAME") ? {type: "NAME"} : NAME), "annotation$ebnf$1"], "postprocess": d => { const annotationName = d[1].value; const params = d[2] ? d[2][1] : undefined; if(params == undefined) { return { type: 'no-params', name: annotationName }; } // named params in the form of [{<name>: <value>}, ...] if(Array.isArray(params)) { const namedParamsRecord = extend(params); return { type: 'named-params', name: annotationName, namedParams: namedParamsRecord }; } // can only be constant param return { type: "const-param", value: params, name: annotationName }; } }, {"name": "annotationParams$subexpression$1", "symbols": ["multipleNamedAnnotationParams"]}, {"name": "annotationParams$subexpression$1", "symbols": ["constExpression"]}, {"name": "annotationParams", "symbols": ["annotationParams$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "multipleNamedAnnotationParams$ebnf$1", "symbols": []}, {"name": "multipleNamedAnnotationParams$ebnf$1$subexpression$1", "symbols": [{"literal":","}, "namedAnnotationParam"]}, {"name": "multipleNamedAnnotationParams$ebnf$1", "symbols": ["multipleNamedAnnotationParams$ebnf$1", "multipleNamedAnnotationParams$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "multipleNamedAnnotationParams", "symbols": ["namedAnnotationParam", "multipleNamedAnnotationParams$ebnf$1"], "postprocess": d => ([d[0], ...d[1].flatMap(([, param]) => param)]) // returns array }, {"name": "constExpression", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)], "postprocess": d => // should match `variableAssignment` constant usage structure for consistency // between named and const annotation types ({usesConstant: true, name: d[0].value}) }, {"name": "constExpression", "symbols": ["literal"], "postprocess": d => d[0].value}, {"name": "namedAnnotationParam$subexpression$1", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME), "assignment"]}, {"name": "namedAnnotationParam", "symbols": ["namedAnnotationParam$subexpression$1"], "postprocess": d => ({[d[0][0].value]: d[0][1].value})}, {"name": "at", "symbols": [{"literal":"@"}], "postprocess": noop}, {"name": "constType$subexpression$1", "symbols": ["constKeyword", "numericType", "fieldName", "floatAssignment", "simple"]}, {"name": "constType$subexpression$1", "symbols": ["constKeyword", "numericType", "fieldName", "intAssignment", "simple"]}, {"name": "constType$subexpression$1", "symbols": ["constKeyword", "stringType", "fieldName", "stringAssignment", "simple"]}, {"name": "constType$subexpression$1", "symbols": ["constKeyword", "booleanType", "fieldName", "booleanAssignment", "simple"]}, {"name": "constType$subexpression$1", "symbols": ["constKeyword", "customType", "fieldName", "variableAssignment", "simple"]}, {"name": "constType", "symbols": ["constType$subexpression$1"], "postprocess": d => { return extend(d[0]); } }, {"name": "constKeyword", "symbols": [{"literal":"const"}], "postprocess": d => ({isConstant: true, declarator: "const"})}, {"name": "fieldName", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)], "postprocess": d => ({name: d[0].value})}, {"name": "sequenceType$ebnf$1$subexpression$1$subexpression$1", "symbols": ["INT"]}, {"name": "sequenceType$ebnf$1$subexpression$1$subexpression$1", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)]}, {"name": "sequenceType$ebnf$1$subexpression$1", "symbols": [{"literal":","}, "sequenceType$ebnf$1$subexpression$1$subexpression$1"]}, {"name": "sequenceType$ebnf$1", "symbols": ["sequenceType$ebnf$1$subexpression$1"], "postprocess": id}, {"name": "sequenceType$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}}, {"name": "sequenceType", "symbols": [{"literal":"sequence"}, {"literal":"<"}, "allTypes", "sequenceType$ebnf$1", {"literal":">"}], "postprocess": d => { const arrayUpperBound = d[3] !== null ? getIntOrConstantValue(d[3][1][0]) : undefined; const typeObj = d[2]; return { ...typeObj, isArray: true, arrayUpperBound, }; }}, {"name": "arrayLengths$ebnf$1", "symbols": ["arrayLength"]}, {"name": "arrayLengths$ebnf$1", "symbols": ["arrayLengths$ebnf$1", "arrayLength"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "arrayLengths", "symbols": ["arrayLengths$ebnf$1"], "postprocess": (d) => { const arrInfo = {isArray: true}; const arrLengthList = d.flat(2).filter((num) => num != undefined); arrInfo.arrayLengths = arrLengthList; return arrInfo; } }, {"name": "arrayLength$subexpression$1", "symbols": ["INT"]}, {"name": "arrayLength$subexpression$1", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)]}, {"name": "arrayLength", "symbols": [{"literal":"["}, "arrayLength$subexpression$1", {"literal":"]"}], "postprocess": ([, intOrName]) => (getIntOrConstantValue(intOrName ? intOrName[0] : undefined)) }, {"name": "assignment$subexpression$1", "symbols": ["floatAssignment"]}, {"name": "assignment$subexpression$1", "symbols": ["intAssignment"]}, {"name": "assignment$subexpression$1", "symbols": ["stringAssignment"]}, {"name": "assignment$subexpression$1", "symbols": ["booleanAssignment"]}, {"name": "assignment$subexpression$1", "symbols": ["variableAssignment"]}, {"name": "assignment", "symbols": ["assignment$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "floatAssignment$subexpression$1", "symbols": ["SIGNED_FLOAT"]}, {"name": "floatAssignment$subexpression$1", "symbols": ["FLOAT"]}, {"name": "floatAssignment", "symbols": [(lexer.has("EQ") ? {type: "EQ"} : EQ), "floatAssignment$subexpression$1"], "postprocess": ([, num]) => ({valueText: num[0], value: parseFloat(num[0])})}, {"name": "intAssignment$subexpression$1", "symbols": ["SIGNED_INT"]}, {"name": "intAssignment$subexpression$1", "symbols": ["INT"]}, {"name": "intAssignment", "symbols": [(lexer.has("EQ") ? {type: "EQ"} : EQ), "intAssignment$subexpression$1"], "postprocess": ([, num]) => ({valueText: num[0], value: parseInt(num[0])})}, {"name": "stringAssignment", "symbols": [(lexer.has("EQ") ? {type: "EQ"} : EQ), "STR"], "postprocess": ([, str]) => ({valueText: str, value: str})}, {"name": "booleanAssignment", "symbols": [(lexer.has("EQ") ? {type: "EQ"} : EQ), "BOOLEAN"], "postprocess": ([, bool]) => ({valueText: bool, value: bool === "TRUE"})}, {"name": "variableAssignment", "symbols": [(lexer.has("EQ") ? {type: "EQ"} : EQ), (lexer.has("NAME") ? {type: "NAME"} : NAME)], "postprocess": ([, name]) => ({ valueText: name.value, value: { usesConstant: true, name: name.value } }) }, {"name": "allTypes$subexpression$1", "symbols": ["primitiveTypes"]}, {"name": "allTypes$subexpression$1", "symbols": ["customType"]}, {"name": "allTypes", "symbols": ["allTypes$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "primitiveTypes$subexpression$1", "symbols": ["stringType"]}, {"name": "primitiveTypes$subexpression$1", "symbols": ["numericType"]}, {"name": "primitiveTypes$subexpression$1", "symbols": ["booleanType"]}, {"name": "primitiveTypes", "symbols": ["primitiveTypes$subexpression$1"], "postprocess": d => ({...d[0][0], isComplex: false})}, {"name": "customType", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)], "postprocess": d => { const typeName = d[0].value; // post process will go through and replace typedefs with their actual type return {type: typeName }; }}, {"name": "stringType$subexpression$1", "symbols": [{"literal":"string"}]}, {"name": "stringType$subexpression$1", "symbols": [{"literal":"wstring"}]}, {"name": "stringType$ebnf$1$subexpression$1$subexpression$1", "symbols": ["INT"]}, {"name": "stringType$ebnf$1$subexpression$1$subexpression$1", "symbols": [(lexer.has("NAME") ? {type: "NAME"} : NAME)]}, {"name": "stringType$ebnf$1$subexpression$1", "symbols": [{"literal":"<"}, "stringType$ebnf$1$subexpression$1$subexpression$1", {"literal":">"}]}, {"name": "stringType$ebnf$1", "symbols": ["stringType$ebnf$1$subexpression$1"], "postprocess": id}, {"name": "stringType$ebnf$1", "symbols": [], "postprocess": function(d) {return null;}}, {"name": "stringType", "symbols": ["stringType$subexpression$1", "stringType$ebnf$1"], "postprocess": d => { const stringKind = d[0][0].value; let strLength = undefined; if(d[1] !== null) { strLength = getIntOrConstantValue(d[1][1] ? d[1][1][0] : undefined); } return {type: stringKind, upperBound: strLength}; } }, {"name": "booleanType", "symbols": [{"literal":"boolean"}], "postprocess": d => ({type: "bool"})}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"byte"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"octet"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"wchar"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"char"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"long"}, {"literal":"double"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"double"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"float"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"int8"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"uint8"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"int16"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"uint16"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"int32"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"uint32"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"int64"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"uint64"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"unsigned"}, {"literal":"short"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"short"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"unsigned"}, {"literal":"long"}, {"literal":"long"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"long"}, {"literal":"long"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"unsigned"}, {"literal":"long"}]}, {"name": "numericType$subexpression$1", "symbols": [{"literal":"long"}]}, {"name": "numericType", "symbols": ["numericType$subexpression$1"], "postprocess": (d) => { const typeString = d[0].map((t) => t?.value).filter(t => !!t).join(" "); return { type: typeString }; } }, {"name": "literal$subexpression$1", "symbols": ["booleanLiteral"]}, {"name": "literal$subexpression$1", "symbols": ["strLiteral"]}, {"name": "literal$subexpression$1", "symbols": ["floatLiteral"]}, {"name": "literal$subexpression$1", "symbols": ["intLiteral"]}, {"name": "literal", "symbols": ["literal$subexpression$1"], "postprocess": d => d[0][0]}, {"name": "booleanLiteral", "symbols": ["BOOLEAN"], "postprocess": d => ({value: d[0] === "TRUE"})}, {"name": "strLiteral", "symbols": ["STR"], "postprocess": d => ({value: d[0]})}, {"name": "floatLiteral$subexpression$1", "symbols": ["SIGNED_FLOAT"]}, {"name": "floatLiteral$subexpression$1", "symbols": ["FLOAT"]}, {"name": "floatLiteral", "symbols": ["floatLiteral$subexpression$1"], "postprocess": d => ({value: parseFloat(d[0][0])})}, {"name": "intLiteral$subexpression$1", "symbols": ["SIGNED_INT"]}, {"name": "intLiteral$subexpression$1", "symbols": ["INT"]}, {"name": "intLiteral", "symbols": ["intLiteral$subexpression$1"], "postprocess": d => ({value: parseInt(d[0][0])})}, {"name": "BOOLEAN$subexpression$1", "symbols": [{"literal":"TRUE"}]}, {"name": "BOOLEAN$subexpression$1", "symbols": [{"literal":"FALSE"}]}, {"name": "BOOLEAN", "symbols": ["BOOLEAN$subexpression$1"], "postprocess": join}, {"name": "STR$ebnf$1", "symbols": [(lexer.has("STRING") ? {type: "STRING"} : STRING)]}, {"name": "STR$ebnf$1", "symbols": ["STR$ebnf$1", (lexer.has("STRING") ? {type: "STRING"} : STRING)], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, {"name": "STR", "symbols": ["STR$ebnf$1"], "postprocess": d => { return join(d.flat(1).filter(d => d !== null)); }}, {"name": "SIGNED_FLOAT$subexpression$1", "symbols": [{"literal":"+"}]}, {"name": "SIGNED_FLOAT$subexpression$1", "symbols": [{"literal":"-"}]}, {"name": "SIGNED_FLOAT", "symbols": ["SIGNED_FLOAT$subexpression$1", "FLOAT"], "postprocess": join}, {"name": "FLOAT$subexpression$1", "symbols": [(lexer.has("DECIMAL") ? {type: "DECIMAL"} : DECIMAL)]}, {"name": "FLOAT$subexpression$1", "symbols": [(lexer.has("DECIMALEXP") ? {type: "DECIMALEXP"} : DECIMALEXP)]}, {"name": "FLOAT", "symbols": ["FLOAT$subexpression$1"], "postprocess": join}, {"name": "FLOAT$subexpression$2", "symbols": [(lexer.has("DECIMAL") ? {type: "DECIMAL"} : DECIMAL), {"literal":"d"}]}, {"name": "FLOAT", "symbols": ["FLOAT$subexpression$2"], "postprocess": d => d[0][0].value}, {"name": "FLOAT$subexpression$3", "symbols": ["INT", {"literal":"d"}]}, {"name": "FLOAT", "symbols": ["FLOAT$subexpression$3"], "postprocess": d => d[0][0]}, {"name": "SIGNED_INT$subexpression$1", "symbols": [{"literal":"+"}]}, {"name": "SIGNED_INT$subexpression$1", "symbols": [{"literal":"-"}]}, {"name": "SIGNED_INT", "symbols": ["SIGNED_INT$subexpression$1", "INT"], "postprocess": join}, {"name": "INT", "symbols": [(lexer.has("INTEGER") ? {type: "INTEGER"} : INTEGER)], "postprocess": join}, {"name": "semi", "symbols": [{"literal":";"}], "postprocess": noop}, {"name": "simple", "symbols": [], "postprocess": () => ({isComplex: false})} ] , ParserStart: "main" } if ( true&& typeof module.exports !== 'undefined') { module.exports = grammar; } else { window.grammar = grammar; } })(); /***/ }), /***/ 662: /***/ (function(module) { (function(root, factory) { if ( true && module.exports) { module.exports = factory(); } else { root.nearley = factory(); } }(this, function() { function Rule(name, symbols, postprocess) { this.id = ++Rule.highestId; this.name = name; this.symbols = symbols; // a list of literal | regex class | nonterminal this.postprocess = postprocess; return this; } Rule.highestId = 0; Rule.prototype.toString = function(withCursorAt) { var symbolSequence = (typeof withCursorAt === "undefined") ? this.symbols.map(getSymbolShortDisplay).join(' ') : ( this.symbols.slice(0, withCursorAt).map(getSymbolShortDisplay).join(' ') + " ● " + this.symbols.slice(withCursorAt).map(getSymbolShortDisplay).join(' ') ); return this.name + " → " + symbolSequence; } // a State is a rule at a position from a given starting point in the input stream (reference) function State(rule, dot, reference, wantedBy) { this.rule = rule; this.dot = dot; this.reference = reference; this.data = []; this.wantedBy = wantedBy; this.isComplete = this.dot === rule.symbols.length; } State.prototype.toString = function() { return "{" + this.rule.toString(this.dot) + "}, from: " + (this.reference || 0); }; State.prototype.nextState = function(child) { var state = new State(this.rule, this.dot + 1, this.reference, this.wantedBy); state.left = this; state.right = child; if (state.isComplete) { state.data = state.build(); // Having right set here will prevent the right state and its children // form being garbage collected state.right = undefined; } return state; }; State.prototype.build = function() { var children = []; var node = this; do { children.push(node.right.data); node = node.left; } while (node.left);