expexp
Version:
The express model io and express model and data representation.
1 lines • 590 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/tree.js","../src/grammar.js","../src/modelDeserializer.js","../src/model.js","../src/variableScope.js","../src/mniTree.js","../src/evaluator.js","../src/slctgram.js","../src/data.js"],"sourcesContent":["\n// //////////////////////////////////////////////\n// Syntax JSON format and tree traverse concept\n// This is a description of the concepts, ideas and guidelines behind\n// the form and structure of the parsed JSON.\n// The tree traverse function depends on that structure. So they are\n// described both together here.\n//\n// The traverse function keeps track and notifies in its events the\n// variables: ii, path and json\n// - json: Is the current part of the JSON that is in focus at the moment.\n// Initially this is the whole JSON.\n// - path: It is the chain of parent elements down to the root (the whole JSON)\n// When afterFct or beforeFct are called for the current element,\n// the path does not contain json.\n// - ii: Stands for identifier or index. It names the context of\n// the json object: If the parent is semantically an object, the\n// type of the top element at ii is string, providing the name of\n// the key. If the parent is semantically an array, the type of\n// the element is JS number (0 or positive and whole), providing\n// the index position.\n//\n// What does 'is semantically' mean?\n// Even though the JSON contains certainly arrays, they always are\n// represented as JS objects. This is to provide also a name for\n// the type of array. Whether json stands for an array can be checked\n// using the isArrSem(json) function. If so, there is - besides\n// the 't' only one more key 's' of type JS array holding the actual\n// array elements. The point is about having a format for tree unit\n// test data and at the same time human readable path positions in\n// the debug output. See the *.tlog files in the /test/units or\n// test/u* dirs.\n//\n// Remarks:\n// - The length of path and ii is identical.\n// - Neither json nor path do at any time contain a JS array.\n// Their content or elements are JS objects with a granted key 't'\n// of type string.\n// - The value of 't' unambiguously defines what other keys must\n// be present.\n// - Any object with 't':'*_dcl' (but 'sct_dcl') has also a key 'typ':{..} .\n// - The 't':'typ' as well as any aggregation type has a key 'spc' defining\n// the base type (of the elements) or being a reference.\n// - A key 'id' always stands for a JS string but for a JS object\n// in the following cases:\n// For 't':'a_atr_ids':\n// 'id':{t:'atr|qal_atr|qal_atr_rnmd', id:'..', ..} .\n// For 't':'drv|inv':\n// 'id':{t:'atr|qal_atr|qal_atr_rnmd', id:'..', ..} .\n// For 't':'cst_dcl':\n// 'id':{t:'cst', id:'..', ..} .\n// For 't':'a_prm_ids':\n// 'id':{t:'prm', id:'..', ..} .\n// For 't':'a_lcl_ids':\n// 'id':{t:'lcl', id:'..', ..} .\n// - The 'id' key of an operation {'t':'o_*'} is always a string.\n// - A key '*[Rr]ef' always stands for a JS object with {t:'*_ref', id:'..'} .\n// - A key '*[Rr]efs' always stands for a JS array containing JS\n// objects with {t:'*_ref', id:'..'} .\n\nfunction traverseContent(ii, path, json, afterFct, beforeFct, keyOrder) {\n\tif (Array.isArray(json)) {\n\t\t// Simple and plane iteration without any event notification.\n\t\tfor (let i=0; i<json.length; i++) {\n\t\t\tii.push(i)\n\t\t\ttraverseContent(ii, path, json[i], afterFct, beforeFct, keyOrder)\n\t\t\tii.pop() // i\n\t\t}\n\t} else { // json is object: {t:'..', ..}\n\t\tbeforeFct(json, path, ii)\n\t\tpath.push(json)\n\t\t// But we have to check for our special array-objects.\n\t\tif (isArrSem(json) == false) {\n\t\t\t// Establish the defined key order for iterating objects.\n\t\t\tconst keys = Object.keys(json).filter(key => !IGNORE_KEY[key])\n\t\t\tif (1 < keys.length) {\n\t\t\t\t// Initially the order was thought to be most-important-first sorted.\n\t\t\t\t// But to improve performance the whole thing is set up reverted.\n\t\t\t\t// We better sort only this short (even filtered) array instead\n\t\t\t\t// of the lengthy order array later.\n\t\t\t\tkeys.sort() // alphanumerically\n\t\t\t\tif (Array.isArray(keyOrder) && 0 < keyOrder.length) {\n\t\t\t\t\tkeys.reverse()\n\t\t\t\t\t// The reverted sorting causes order.length-i later.\n\t\t\t\t\tconst order = keys.concat(keyOrder)\n\t\t\t\t\t// const order = DEFAULT_OBJECT_KEY_TRAVERSE_ORDER.concat(keys)\n\t\t\t\t\t// order.reverse()\n\t\t\t\t\tconst key2idx = {}\n\t\t\t\t\torder.forEach((elt, i) => { key2idx[elt] = order.length-i }) // Index needs not be exact (missing -1).\n\t\t\t\t\t// A key, that is in the json as well as in the special array,\n\t\t\t\t\t// gets the lower index of the special array.\n\t\t\t\t\tkeys.sort((a, b) => key2idx[a]-key2idx[b])\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of keys) {\n\t\t\t\tconst value = json[key]\n\t\t\t\tif (value !== null && typeof value == 'object' && Array.isArray(value) == false) {\n\t\t\t\t\t// Per design we do not have arrays here.\n\t\t\t\t\tii.push(key)\n\t\t\t\t\ttraverseContent(ii, path, value, afterFct, beforeFct, keyOrder)\n\t\t\t\t\tii.pop() // key\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// The special array-object is the event arg, and\n\t\t\t// already triggered here, while traverseContent(..)\n\t\t\t// only handles the true array (value.s).\n\t\t\ttraverseContent(ii, path, json.s, afterFct, beforeFct, keyOrder)\n\t\t}\n\t\tpath.pop() // json\n\t\tafterFct(json, path, ii)\n\t}\n}\n\nconst II_ROOT = '≡'\nconst IGNORE_KEY = {'p':true, 't':true}\n\nconst DEFAULT_OBJECT_KEY_TRAVERSE_ORDER = [\n\t// For most cases the order is a nice to have, but\n\t// for fct, xpr, itv { < < } and qry( <* | ): order src-var-cnd\n\t// the order fits op stack architecture and is functionally essential.\n\t'arg0',\n\t'qals0',\n\t'arg',\n\t'arg1',\n\t'qals1',\n\t'op',\n\t'id1', // a compare relation op id\n\t'arg2',\n\t'id2', // a compare relation op id\n\t// Unfortunately there are some technical dependencies introduced\n\t// by the fact, that all must fit into one 'flat' order.\n\t// Through cnd(qry) also involved are: ntt and sct_dcl\n\t// Through whrs(ntt) also involved are: typ and rul\n\t// Through csts, lcls, ctts (rul) also: fun and prc\n\t// Through nttRef also involved are: inv, qal_atr, qal_atr_rnmd\n\t// Through ref(qal_atr_rnmd) also: ref_rnmd, enm_xtdd, slc_xtdd\n\t// Through refs(slc_xtdd) also: slc, use, ref, scm\n\t// Through xtd(enm_xtdd, slc_xtdd) also: enm, slc\n // Through vals(enm, enm_xtdd) also: agi, bif, coc\n\t'src', // qry\n\t'var', // qry, als, rpt\n\t'id', // ntt, sct_dcl, .. and really many more, but good, this always comes first.\n\t'spc', // typ, and really many more, but good, this comes after 'id' .\n\t'xtd', // enm, enm_xtdd, slc, slc_xtdd\n\t'nttOnly', // slc, slc_xtdd\n\t'agrTyp', // inv\n\t'agrBds', // inv\n\t'nttRef', // sct_dcl, inv, qal_atr, qal_atr_rnmd\n\t'ref', // qal_atr_rnmd, ref_rnmd, enm_xtdd, slc_xtdd, asg, als\n\t'refs', // slc, slc_xtdd, use, t:ref, scm\n\t'qals', // asg, als\n\t'nttRefs', // rul\n\t'invRef', // inv\n\t'vals', // enm, enm_xtdd, agi, bif, coc\n\t'abs', // ntt, sct_dcl\n\t'ttlNttRefs', // sct_dcl\n\t'cnd', // qry, ntt, sct_dcl, iff\n\t'sprs', // ntt\n\t'atrs', // ntt\n\t'drvs', // ntt\n\t'invs', // ntt\n\t'unqs', // ntt\n\t'itr', // rpt\n\t'whl', // rpt\n\t'utl', // rpt\n\t'prms', // fun, prc\n\t'res', // fun\n\t'ctts', // rul, fun, prc (algorithm_head order)\n\t'csts', // rul, scm, fun, prc (algorithm_head order)\n\t'lcls', // rul, fun, prc (algorithm_head order)\n\t'stms', // fun, prc, rul, cpd, als, rpt, iff\n\t'whrs', // ntt, typ, rul\n\t'elss', // iff\n\t'slr', // cas\n\t'caas', // cas\n\t'oth', // cas\n\t'xprs', // caa\n\t'stm', // caa\n\t'fr', // bds, itr\n\t'to', // bds, itr\n\t'by', // itr\n\t'scts' // scm\n]\n\nconst HUMAN_READ_ORDER = ['t'].concat(DEFAULT_OBJECT_KEY_TRAVERSE_ORDER)\nconst HUMAN_READ_IDX = {}\nHUMAN_READ_ORDER.forEach(key => {\n\tHUMAN_READ_IDX[key] = HUMAN_READ_ORDER.indexOf(key) + 1 // 0 is not good\n})\n\nconst HUMAN_READ_ORDER_FCT = function(a, b) {\n\tconst aIdx = HUMAN_READ_IDX[a] // might be undefined\n\tconst bIdx = HUMAN_READ_IDX[b] // might be undefined\n\tif (aIdx && bIdx) {\n\t\treturn aIdx - bIdx\n\t} else if (!aIdx && !bIdx) {\n\t\treturn a.localeCompare(b) // alphanumerical\n\t} else if (aIdx && !bIdx) {\n\t\treturn -1\n\t} else if (!aIdx && bIdx) {\n\t\treturn 1\n\t}\n}\n\nconst noOp = function(){}\n\nfunction traverseExternal(json, afterFct, beforeFct=noOp, keyOrder=DEFAULT_OBJECT_KEY_TRAVERSE_ORDER, path=[], ii=[II_ROOT]) {\n\tif (!json) return\n\tif (Array.isArray(keyOrder)) {\n\t\tkeyOrder = keyOrder.slice() // copy\n\t\tkeyOrder.reverse()\n\t}\n\ttraverseContent(ii, path, json, afterFct, beforeFct, keyOrder)\n}\n\nfunction isArrSem(json) {\n\treturn json && json.t && json.t.startsWith('a_')\n}\n\nfunction path2str(ii, path, json) {\n\tlet fullPath = path\n\tif (json) {\n\t\tfullPath = path.slice()\n\t\tfullPath.push(json)\n\t}\n\tconst strs = fullPath.map(function(elt, i, arr){\n\t\tlet lbl = ii[i]\n\t\tif (Number.isInteger(lbl)) {\n\t\t\tconst arrObj = arr[i-1]\n\t\t\tconst pArrLenStrLength = ` ${arrObj.s.length}`.length\n\t\t\tlbl = String(lbl).padStart(pArrLenStrLength, ' ')\n\t\t\tlbl = `[${arrObj.t}${lbl}]`\n\t\t} else {\n\t\t\tlbl = '.' + lbl\n\t\t}\n\t\tlet eltStr // undefined\n\t\tif (isArrSem(elt)) {\n\t\t\tif (i < fullPath.length-1) {\n\t\t\t\teltStr = ''\n\t\t\t} else { // At the top.\n\t\t\t\tif (0 < elt.s.length) {\n\t\t\t\t\teltStr = `[${elt.t}:${elt.s.length}]`\n\t\t\t\t} else {\n\t\t\t\t\teltStr = `[]`\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\teltStr = elt.t\n\t\t\tif (elt.id) {\n\t\t\t\teltStr += ' ' + elt.id\n\t\t\t}\n\t\t\teltStr = `{${eltStr}}`\n\t\t}\n\t\treturn lbl + eltStr\n\t})\n\treturn strs.join('').substr(1)\n}\n\nfunction DEFAULT_ORDER() {\n\treturn DEFAULT_OBJECT_KEY_TRAVERSE_ORDER.slice()\n}\n\nfunction ALPHANUM_ORDER() {\n\treturn []\n}\n\nexport {\n\tDEFAULT_ORDER, ALPHANUM_ORDER,\n\tHUMAN_READ_ORDER_FCT,\n\ttraverseExternal as traverse,\n\tisArrSem,\n\tpath2str\n}\n","// Generated automatically by nearley, version 2.20.1\n// http://github.com/Hardmath123/nearley\nfunction id(x) { return x[0]; }\n\n\nimport moo from 'moo'\n\n// \"The order of your rules matters. Earlier ones will take precedence.\" - for an JS object that sounds not very reliable.\n// \"Only rules from the current state can be matched. You need to copy your rule into all the states you want it to be matched in.\"\n// From: https://github.com/no-context/moo#states\n\nconst P_EMBEDDED_REMARK = '\\\\(\\\\*[^]*?\\\\*\\\\)'\nconst P_TAIL_REMARK = '--[^\\\\r\\\\n]*\\\\r?\\\\n'\nconst P_ANY_REMARK_ANYWHERE = '(?:'+P_EMBEDDED_REMARK+'[ \\t\\r\\n]*)?(?:'+P_TAIL_REMARK+'[ \\t\\r\\n]*)?'\nconst rxOptWsAtEnd = new RegExp('\\\\s*'+P_ANY_REMARK_ANYWHERE+'\\$', 'g')\nfunction convStr(str) {\n\treturn str.replace(rxOptWsAtEnd, '').slice(1, -1) // decoding (if needed) is done lazy\n}\n\nconst P_SIMPLE_ID = '[a-zA-Z][a-zA-Z0-9_]*'\n\nconst P_REAL_VALUE = '[+-]?[0-9]+\\\\.[0-9]*(?:[eE][+-]?[0-9]+)?'\nconst P_INT_VALUE = '[+-]?[0-9]+'\n//const P_STR_VALUE = \"'(?:[^']| |'')*'\"\nconst P_STR_VALUE = '\\x27(?:[^\\x27]| |\\x27\\x27)*\\x27'\n// string: {match: /\"(?:\\\\[\"\\\\]|[^\\n\"\\\\])*\"/, value: s => s.slice(1, -1)}\nconst P_ENCSTR_VALUE = '\"(?:[0-9A-F]{8,8})*\"'\n// See: https://github.com/no-context/moo#value-vs-text\nconst P_BIN_VALUE = '\"[0-3][0-9A-F]*\"'\n\nconst sts = {}\nsts['main'] = {}\n\nsts['main']['WS'] = {match: /[ \\t\\r\\n]+/, lineBreaks: true}\nsts['main']['EMBEDDED_REMARK'] = {match: new RegExp(P_EMBEDDED_REMARK), lineBreaks: true}\nsts['main']['TAIL_REMARK'] = {match: new RegExp(P_TAIL_REMARK), lineBreaks: true}\n\nsts['main']['LB'] = '['\nsts['main']['RB'] = ']'\nsts['main']['LP'] = '('\nsts['main']['RP'] = ')'\nsts['main']['LC'] = '{'\nsts['main']['RC'] = '}'\nsts['main']['SNE'] = ':<>:'\nsts['main']['SEQ'] = ':=:'\nsts['main']['ASSIGN'] = ':='\nsts['main']['COLON'] = ':'\nsts['main']['DOT'] = '.'\nsts['main']['SEMI'] = ';'\nsts['main']['COMMA'] = ','\nsts['main']['INDET'] = '?'\nsts['main']['BACKSLASH'] = '\\\\'\nsts['main']['DOUBLE_SOLID'] = '||'\nsts['main']['SOLID'] = '|'\nsts['main']['LESS_ASTERISK'] = '<*'\nsts['main']['DOUBLE_ASTERISTK'] = '**'\nsts['main']['ASTERISK'] = '*'\nsts['main']['DIVIS'] = '/'\nsts['main']['PLUS'] = '+'\nsts['main']['MINUS'] = '-'\nsts['main']['LE'] = '<='\nsts['main']['NE'] = '<>'\nsts['main']['LT'] = '<'\nsts['main']['GE'] = '>='\nsts['main']['GT'] = '>'\nsts['main']['EQ'] = '='\n\nsts['main']['REAL_LIT'] = {match: new RegExp(P_REAL_VALUE)}\nsts['main']['INT'] = {match: new RegExp(P_INT_VALUE)}\nsts['main']['STR'] = {match: new RegExp(P_STR_VALUE)}\nsts['main']['ENCSTR'] = {match: new RegExp(P_ENCSTR_VALUE)}\nsts['main']['BIN'] = {match: new RegExp(P_BIN_VALUE)}\n\nconst kwds = []\nkwds.push('SCHEMA')\nkwds.push('TYPEOF') // before TYPE\nkwds.push('TYPE')\nkwds.push('ENTITY')\nkwds.push('RULE')\nkwds.push('FUNCTION')\nkwds.push('PROCEDURE')\nkwds.push('SUBTYPE_CONSTRAINT') // before SUBTYPE\nkwds.push('SUBTYPE')\nkwds.push('SUPERTYPE')\nkwds.push('GENERIC_ENTITY')\nkwds.push('GENERIC')\nkwds.push('RENAMED')\nkwds.push('LOCAL')\nkwds.push('WHERE')\nkwds.push('DERIVE')\nkwds.push('INVERSE')\nkwds.push('ARRAY')\nkwds.push('BAG')\nkwds.push('LIST')\nkwds.push('SET')\nkwds.push('OPTIONAL')\nkwds.push('UNIQUE')\nkwds.push('AGGREGATE')\nkwds.push('BINARY')\nkwds.push('BOOLEAN')\nkwds.push('INTEGER')\nkwds.push('LOGICAL')\nkwds.push('NUMBER')\nkwds.push('REAL')\nkwds.push('STRING')\nkwds.push('FIXED')\nkwds.push('REFERENCE')\nkwds.push('CONSTANT')\nkwds.push('FROM')\nkwds.push('EXTENSIBLE')\nkwds.push('ANDOR') // before AND\nkwds.push('AND')\nkwds.push('ONEOF')\nkwds.push('END_SCHEMA') // before END\nkwds.push('END_ENTITY') // before END\nkwds.push('END_SUBTYPE_CONSTRAINT') // before END\nkwds.push('END_TYPE') // before END\nkwds.push('END_FUNCTION') // before END\nkwds.push('END_PROCEDURE') // before END\nkwds.push('END_RULE') // before END\nkwds.push('END_LOCAL') // before END\nkwds.push('END_CONSTANT') // before END\nkwds.push('END_IF') // before END\nkwds.push('END_ALIAS') // before END\nkwds.push('END_REPEAT') // before END\nkwds.push('END_CASE') // before END\nkwds.push('END')\nkwds.push('RETURN')\nkwds.push('REMOVE')\nkwds.push('INSERT')\nkwds.push('SKIP')\nkwds.push('ESCAPE')\nkwds.push('CASE')\nkwds.push('BEGIN')\nkwds.push('ALIAS')\nkwds.push('REPEAT')\nkwds.push('IF')\nkwds.push('ELSE')\nkwds.push('ABSTRACT') // before ABS\nkwds.push('ABS')\nkwds.push('CONST_E')\nkwds.push('PI')\nkwds.push('SELF')\nkwds.push('ACOS')\nkwds.push('ASIN')\nkwds.push('ATAN')\nkwds.push('BLENGTH')\nkwds.push('COS')\nkwds.push('EXISTS')\nkwds.push('EXP')\nkwds.push('FORMAT') // before FOR\nkwds.push('FOR')\nkwds.push('HIBOUND')\nkwds.push('HIINDEX')\nkwds.push('LENGTH')\nkwds.push('LOBOUND')\nkwds.push('LOINDEX')\nkwds.push('LOG2') // before LOG\nkwds.push('LOG10') // before LOG\nkwds.push('LOG')\nkwds.push('NVL')\nkwds.push('ODD')\nkwds.push('ROLESOF')\nkwds.push('SIN')\nkwds.push('SIZEOF')\nkwds.push('SQRT')\nkwds.push('TAN')\nkwds.push('USEDIN') // before USE\nkwds.push('USE')\nkwds.push('VALUE_IN') // before VALUE\nkwds.push('VALUE_UNIQUE') // before VALUE\nkwds.push('VALUE')\nkwds.push('QUERY')\nkwds.push('XOR')\nkwds.push('TRUE')\nkwds.push('FALSE')\nkwds.push('UNKNOWN')\nkwds.push('LIKE')\nkwds.push('NOT')\nkwds.push('DIV')\nkwds.push('MOD')\nkwds.push('OTHERWISE')\nkwds.push('WHILE')\nkwds.push('UNTIL')\nkwds.push('THEN')\nkwds.push('SELECT')\nkwds.push('ENUMERATION')\nkwds.push('BASED_ON')\nkwds.push('WITH')\nkwds.push('VAR')\nkwds.push('TOTAL_OVER') // before TO\nkwds.push('TO')\nkwds.push('OR')\nkwds.push('IN')\nkwds.push('AS')\nkwds.push('OF')\nkwds.push('BY')\n\nconst kwm = Object.fromEntries(kwds.map(k => [k, k]))\n\nsts['main']['SIMPLE_ID'] = {\n\tmatch: new RegExp(P_SIMPLE_ID),\n\ttype: moo.keywords(kwm)\n}\n\nconst lexer = moo.states(sts)\n\nfunction pNfo(token) {\n\treturn {\n\t\t//value: token.value,\n\t\tline: token.line,\n\t\tcol: token.col,\n\t\toffset: token.offset,\n\t\tlineBreaks: token.lineBreaks\n\t}\n}\n\nfunction toRlo(dd) {\n\tconst raw = dd.type.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'le': return 'le'\n\t\tcase 'ge': return 'ge'\n\t\tcase 'ne': return 'ne'\n\t\tcase 'eq': return 'eq'\n\t\tcase 'seq': return 'se'\n\t\tcase 'sne': return 'sn'\n\t\tcase 'lt': return 'lt'\n\t\tcase 'gt': return 'gt'\n\t\tcase 'in': return 'in'\n\t\tcase 'like': return 'lik'\n\t}\n\tthrow new Error(`Invalid relational operator \"${raw}\" error.`)\n}\n\nfunction toAdo(d) {\n\tconst raw = d[0][0].type.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'plus': return 'pls'\n\t\tcase 'minus': return 'min'\n\t\tcase 'or': return 'oor'\n\t\tcase 'xor': return 'xor'\n\t}\n\tthrow new Error(`Invalid addition/subtraction (or/xor) operator \"${raw}\" error.`)\n}\n\nfunction toMpo(d) {\n\tconst raw = d[0][0].type.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'asterisk': return 'ast'\n\t\tcase 'divis': return 'dvs'\n\t\tcase 'div': return 'div'\n\t\tcase 'mod': return 'mod'\n\t\tcase 'and': return 'and'\n\t\tcase 'double_solid': return 'll2'\n\t}\n\tthrow new Error(`Invalid multiplication/division (and and double solid) operator \"${raw}\" error.`)\n}\n\nfunction toUno(d) {\n\tconst raw = d[0][0].type.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'plus': return 'psu'\n\t\tcase 'minus': return 'msu'\n\t\tcase 'not': return 'not'\n\t}\n\tthrow new Error(`Invalid unary operator \"${raw}\" error.`)\n}\n\nfunction toBic(d) {\n\tconst raw = d[0][0].value.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'const_e': return 'eul'\n\t\tcase 'pi': return 'pii'\n\t\tcase 'self': return 'slf'\n\t\tcase '?': return 'idt'\n\t\tcase 'true': return 'tru'\n\t\tcase 'false': return 'fls'\n\t\tcase 'unknown': return 'ukn'\n\t}\n\tthrow new Error(`Invalid built in constant \"${raw}\" error.`)\n}\n\nfunction toBif(d) {\n\tconst raw = d[0][0].value.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'abs': return 'abs'\n\t\tcase 'acos': return 'acs'\n\t\tcase 'asin': return 'asn'\n\t\tcase 'atan': return 'atn'\n\t\tcase 'blength': return 'bln'\n\t\tcase 'cos': return 'cos'\n\t\tcase 'exists': return 'xst'\n\t\tcase 'exp': return 'exp'\n\t\tcase 'format': return 'fmt'\n\t\tcase 'hibound': return 'hbd'\n\t\tcase 'hiindex': return 'hdx'\n\t\tcase 'length': return 'len'\n\t\tcase 'lobound': return 'lbd'\n\t\tcase 'loindex': return 'ldx'\n\t\tcase 'log': return 'lgn'\n\t\tcase 'log2': return 'lg2'\n\t\tcase 'log10': return 'lgx'\n\t\tcase 'nvl': return 'nvl'\n\t\tcase 'odd': return 'odd'\n\t\tcase 'rolesof': return 'rlf'\n\t\tcase 'sin': return 'sin'\n\t\tcase 'sizeof': return 'szf'\n\t\tcase 'sqrt': return 'qrt'\n\t\tcase 'tan': return 'tan'\n\t\tcase 'typeof': return 'tpf'\n\t\tcase 'usedin': return 'usd'\n\t\tcase 'value': return 'vlu'\n\t\tcase 'value_in': return 'vln'\n\t\tcase 'value_unique': return 'vlq'\n\t}\n\tthrow new Error(`Invalid built in function \"${raw}\" error.`)\n}\n\nfunction toBip(d) {\n\tconst raw = d[0][0].value.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'insert': return 'ins'\n\t\tcase 'remove': return 'rmv'\n\t}\n\tthrow new Error(`Invalid built in procedure \"${raw}\" error.`)\n}\n\nfunction toSim(d) {\n\tconst raw = d[0][0].value.toLowerCase()\n\tswitch(raw) {\n\t\tcase 'boolean': return 't_bol'\n\t\tcase 'integer': return 't_int'\n\t\tcase 'logical': return 't_lox'\n\t\tcase 'number': return 't_nbr'\n\t}\n\tthrow new Error(`Invalid simple data type \"${raw}\" error.`)\n}\n\nfunction toReal(token) {\n\treturn withWidthSpec(token, 't_rea', true)\n}\n\nfunction toStr(token) {\n\treturn withWidthSpec(token, 't_str')\n}\n\nfunction toBin(token) {\n\treturn withWidthSpec(token, 't_bin')\n}\n\nfunction withWidthSpec(token, typeStr, primIsFrom=false) {\n\tif (token[1]) { // cannot check token.length since token[1] is null\n\t\tlet primFld = 'to'\n\t\tlet scndFld = 'fr'\n\t\tif (primIsFrom) {\n\t\t\tprimFld = 'fr'\n\t\t\tscndFld = 'to'\n\t\t}\n\t\t// See width_spec on how token[1] looks like.\n\t\tif ('width' in token[1]) {\n\t\t\t// console.log(token[1].width)\n\t\t\tif (token[1].width.t == 'width_ref') {\n\t\t\t\ttoken[1].t = 'bds'\n\t\t\t\tconst fixed = token[1].fixed\n\t\t\t\tconst varRef = token[1].width.id\n\t\t\t\ttoken[1][primFld] = {t:'a_sxp_trms', s:[{t:'a_trm_ftrs', s:[{t:'ftr', arg0:{t:'any_ref', id:varRef}, qals0:null, arg1:null, qals1:null, p:pNfo(token[1].p) }]}]}\n\t\t\t\tif (fixed) {\n\t\t\t\t\ttoken[1][scndFld] = token[1][primFld]\n\t\t\t\t} else {\n\t\t\t\t\ttoken[1][scndFld] = null\n\t\t\t\t}\n\t\t\t\tdelete token[1].width\n\t\t\t\tdelete token[1].fixed\n\t\t\t} else {\n\t\t\t\ttoken[1].t = 'bds'\n\t\t\t\tconst fixed = token[1].fixed\n\t\t\t\tconst parsed = parseInt(token[1].width.value)\n\t\t\t\tif (!isNaN(parsed) && 0 < parsed) {\n\t\t\t\t\ttoken[1][primFld] = {t:'a_sxp_trms', s:[{t:'a_trm_ftrs', s:[{t:'ftr', arg0:{t:'int', val:parsed}, qals0:null, arg1:null, qals1:null}]}]}\n\t\t\t\t\tif (fixed) {\n\t\t\t\t\t\ttoken[1][scndFld] = token[1][primFld]\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttoken[1][scndFld] = null\n\t\t\t\t\t}\n\t\t\t\t\tdelete token[1].width\n\t\t\t\t\tdelete token[1].fixed\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// TODO what about p:pNfo?\n\t\treturn {t:typeStr, bds:token[1]}\n\t} else {\n\t\treturn {t:typeStr, bds:null}\n\t}\n}\n\nfunction toArr(token, tName) {\n\tif (token && 0 < token.length) {\n\t\treturn {t:tName, s:token}\n\t} else {\n\t\treturn null\n\t}\n}\n\nfunction toBds(token) { // Also used for t:'itr'.\n\t// Originally this was jsut a undefined check, but then it was not\n\t// achieved by parser rules to get a simple INDET representation\n\t// when the token is just a question_mark. So simplifyBndExpr(..) .\n\tif (token) {\n\t\ttoken.fr = simplifyBndExpr(token.fr)\n\t\ttoken.to = simplifyBndExpr(token.to)\n\t\treturn token\n\t}\n\treturn null\n}\n\nfunction simplifyBndExpr(expr) {\n\tif (expr\n\t\t&& expr.t == 'a_sxp_trms'\n\t\t&& expr.s.length == 1 && expr.s[0]\n\t\t&& expr.s[0].t == 'a_trm_ftrs'\n\t\t&& expr.s[0].s.length == 1 && expr.s[0].s[0]\n\t\t&& expr.s[0].s[0].t == 'ftr'\n\t\t&& expr.s[0].s[0].arg1 == null\n\t\t&& expr.s[0].s[0].arg0.t == 'bic'\n\t\t&& expr.s[0].s[0].arg0.id == 'idt'\n\t) {\n\t\treturn null\n\t}\n\treturn expr\n}\n\nfunction toInverse(d) {\n\tconst res = {\n\t\tt:'inv',\n\t\tid:d[0],\n\t\tagrTyp:null,\n\t\tagrBds:null,\n\t\tnttRef:toNttRef(d[3]),\n\t\tinvRef:{t:'any_ref', id:d[5].value, p:pNfo(d[5])},\n\t\tp:pNfo(d[0])\n\t}\n\tif (d[2]) {\n\t\tres.agrTyp = d[2][0][0].value.toLowerCase()\n\t\tif (d[2][1]) {\n\t\t\tres.agrBds = toBds(d[2][1])\n\t\t} else {\n\t\t\tres.agrBds = {\n\t\t\t\tt:'bds',\n\t\t\t\tfr:{t:'a_sxp_trms', s:[{t:'a_trm_ftrs', s:[{t:'ftr',\n\t\t\t\t\targ0:{t:'int',val:0},\n\t\t\t\t\tqals0:null,\n\t\t\t\t\targ1:null,qals1:null\n\t\t\t\t}]}]},\n\t\t\t\tto:null\n\t\t\t}\n\t\t}\n\t}\n\treturn res\n}\n\nfunction toEotRef(token) { // used for entity_ref | type_ref\n\tif (token.value) {\n\t\treturn {t:'any_ref', id:token.value, p:pNfo(token)}\n\t} else {\n\t\treturn null\n\t}\n}\n\nfunction toNttRef(token) { // used for entity_ref only\n\tif (token && token.value) {\n\t\treturn {t:'ntt_ref', id:token.value, p:pNfo(token)}\n\t} else {\n\t\treturn null\n\t}\n}\n\n// Make remarks (e.g. EMBEDDED_REMARK) not to be passed to the parser.\nlexer.next = (next => () => {\n let tok\n while ((tok = next.call(lexer)) && (\n\t\t\t\t\t\ttok.type === 'WS'\n\t\t\t\t||\ttok.type === 'EMBEDDED_REMARK'\n\t\t\t\t||\ttok.type === 'TAIL_REMARK'\n\t\t\t)) {}\n\t\t//if (tok) { // Out the result from the lexer.\n\t\t//\tconsole.log(tok.type, tok.value, lexer.stack, lexer.state)\n\t\t//}\n\t\tif (tok && tok.type === 'SIMPLE_ID') {\n\t\t\t// Check if it is not a (partially) lower case keyword.\n\t\t\tconst tType = kwm[tok.value.toUpperCase()]\n\t\t\tif (tType) {\n\t\t\t\ttok.type = tType\n\t\t\t}\n\t\t}\n return tok\n})(lexer.next)\nlet Lexer = lexer;\nlet ParserRules = [\n {\"name\": \"main$ebnf$1\", \"symbols\": [(lexer.has(\"WS\") ? {type: \"WS\"} : WS)], \"postprocess\": id},\n {\"name\": \"main$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"main\", \"symbols\": [\"main$ebnf$1\", \"syntax\"], \"postprocess\": d => d[1]},\n {\"name\": \"type_decl$ebnf$1\", \"symbols\": [\"where_clause\"], \"postprocess\": id},\n {\"name\": \"type_decl$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"type_decl\", \"symbols\": [(lexer.has(\"TYPE\") ? {type: \"TYPE\"} : TYPE), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), (lexer.has(\"EQ\") ? {type: \"EQ\"} : EQ), \"underlying_type\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI), \"type_decl$ebnf$1\", (lexer.has(\"END_TYPE\") ? {type: \"END_TYPE\"} : END_TYPE), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'typ', id:d[1].value, spc:d[3], whrs:toArr(d[5],'a_typ_whrs'), p:pNfo(d[0])})},\n {\"name\": \"underlying_type$subexpression$1\", \"symbols\": [\"enumeration_type\"]},\n {\"name\": \"underlying_type$subexpression$1\", \"symbols\": [\"select_type\"]},\n {\"name\": \"underlying_type$subexpression$1\", \"symbols\": [\"general_aggregation_types\"]},\n {\"name\": \"underlying_type$subexpression$1\", \"symbols\": [\"simple_types\"]},\n {\"name\": \"underlying_type$subexpression$1\", \"symbols\": [\"named_types\"]},\n {\"name\": \"underlying_type\", \"symbols\": [\"underlying_type$subexpression$1\"], \"postprocess\": d => d[0][0]},\n {\"name\": \"enumeration_type$ebnf$1\", \"symbols\": [(lexer.has(\"EXTENSIBLE\") ? {type: \"EXTENSIBLE\"} : EXTENSIBLE)], \"postprocess\": id},\n {\"name\": \"enumeration_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"enumeration_type\", \"symbols\": [\"enumeration_type$ebnf$1\", (lexer.has(\"ENUMERATION\") ? {type: \"ENUMERATION\"} : ENUMERATION), (lexer.has(\"OF\") ? {type: \"OF\"} : OF), (lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"enum_id_list\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP)], \"postprocess\": d => ({t:'enm', xtd:(!!d[0]), vals:toArr(d[4],'a_enm_vals'), p:pNfo(d[1]) })},\n {\"name\": \"enumeration_type$ebnf$2\", \"symbols\": [(lexer.has(\"EXTENSIBLE\") ? {type: \"EXTENSIBLE\"} : EXTENSIBLE)], \"postprocess\": id},\n {\"name\": \"enumeration_type$ebnf$2\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"enumeration_type\", \"symbols\": [\"enumeration_type$ebnf$2\", (lexer.has(\"ENUMERATION\") ? {type: \"ENUMERATION\"} : ENUMERATION), (lexer.has(\"BASED_ON\") ? {type: \"BASED_ON\"} : BASED_ON), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), (lexer.has(\"WITH\") ? {type: \"WITH\"} : WITH), (lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"enum_id_list\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP)], \"postprocess\": d => ({t:'enm_xtdd', xtd:(!!d[0]), ref:{t:'typ_ref', id:d[3].value}, vals:toArr(d[6],'a_enm_vals'), p:pNfo(d[1]) })},\n {\"name\": \"enum_id_list$ebnf$1\", \"symbols\": []},\n {\"name\": \"enum_id_list$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"COMMA\") ? {type: \"COMMA\"} : COMMA), \"enum_value\"]},\n {\"name\": \"enum_id_list$ebnf$1\", \"symbols\": [\"enum_id_list$ebnf$1\", \"enum_id_list$ebnf$1$subexpression$1\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"enum_id_list\", \"symbols\": [\"enum_value\", \"enum_id_list$ebnf$1\"], \"postprocess\": d => d[1][0]?[d[0]].concat(d[1].map(e=>e.slice(1)[0]) ):[d[0]]},\n {\"name\": \"enum_value\", \"symbols\": [(lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'evl', id:d[0].value, p:pNfo(d[0])})},\n {\"name\": \"select_type$ebnf$1$subexpression$1$ebnf$1\", \"symbols\": [(lexer.has(\"GENERIC_ENTITY\") ? {type: \"GENERIC_ENTITY\"} : GENERIC_ENTITY)], \"postprocess\": id},\n {\"name\": \"select_type$ebnf$1$subexpression$1$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"select_type$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"EXTENSIBLE\") ? {type: \"EXTENSIBLE\"} : EXTENSIBLE), \"select_type$ebnf$1$subexpression$1$ebnf$1\"]},\n {\"name\": \"select_type$ebnf$1\", \"symbols\": [\"select_type$ebnf$1$subexpression$1\"], \"postprocess\": id},\n {\"name\": \"select_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"select_type\", \"symbols\": [\"select_type$ebnf$1\", (lexer.has(\"SELECT\") ? {type: \"SELECT\"} : SELECT), (lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"select_ref_list\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP)], \"postprocess\": d => ({t:'slc', xtd:!!(d[0]&&!!d[0][0]), refs:toArr(d[3],'a_slc_refs'), nttOnly:!!(d[0]&&!!d[0][1]), p:pNfo(d[1])})},\n {\"name\": \"select_type$ebnf$2$subexpression$1$ebnf$1\", \"symbols\": [(lexer.has(\"GENERIC_ENTITY\") ? {type: \"GENERIC_ENTITY\"} : GENERIC_ENTITY)], \"postprocess\": id},\n {\"name\": \"select_type$ebnf$2$subexpression$1$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"select_type$ebnf$2$subexpression$1\", \"symbols\": [(lexer.has(\"EXTENSIBLE\") ? {type: \"EXTENSIBLE\"} : EXTENSIBLE), \"select_type$ebnf$2$subexpression$1$ebnf$1\"]},\n {\"name\": \"select_type$ebnf$2\", \"symbols\": [\"select_type$ebnf$2$subexpression$1\"], \"postprocess\": id},\n {\"name\": \"select_type$ebnf$2\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"select_type\", \"symbols\": [\"select_type$ebnf$2\", (lexer.has(\"SELECT\") ? {type: \"SELECT\"} : SELECT), (lexer.has(\"BASED_ON\") ? {type: \"BASED_ON\"} : BASED_ON), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), (lexer.has(\"WITH\") ? {type: \"WITH\"} : WITH), (lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"select_ref_list\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP)], \"postprocess\": d => ({t:'slc_xtdd', xtd:!!(d[0]&&!!d[0][0]), ref:{t:'typ_ref', id:d[3].value}, refs:toArr(d[6],'a_slc_refs'), nttOnly:!!(d[0]&&!!d[0][1]), p:pNfo(d[1])})},\n {\"name\": \"select_ref_list$ebnf$1\", \"symbols\": []},\n {\"name\": \"select_ref_list$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"COMMA\") ? {type: \"COMMA\"} : COMMA), \"named_types\"]},\n {\"name\": \"select_ref_list$ebnf$1\", \"symbols\": [\"select_ref_list$ebnf$1\", \"select_ref_list$ebnf$1$subexpression$1\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"select_ref_list\", \"symbols\": [\"named_types\", \"select_ref_list$ebnf$1\"], \"postprocess\": d => d[1][0]?[d[0]].concat(d[1].map(e=>e.slice(1)[0]) ):[d[0]]},\n {\"name\": \"function_decl$ebnf$1\", \"symbols\": [\"formal_params\"], \"postprocess\": id},\n {\"name\": \"function_decl$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"function_decl$ebnf$2\", \"symbols\": []},\n {\"name\": \"function_decl$ebnf$2\", \"symbols\": [\"function_decl$ebnf$2\", \"declaration\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"function_decl$ebnf$3\", \"symbols\": [\"constant_decl\"], \"postprocess\": id},\n {\"name\": \"function_decl$ebnf$3\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"function_decl$ebnf$4\", \"symbols\": [\"local_decl\"], \"postprocess\": id},\n {\"name\": \"function_decl$ebnf$4\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"function_decl$ebnf$5\", \"symbols\": [\"stmt\"]},\n {\"name\": \"function_decl$ebnf$5\", \"symbols\": [\"function_decl$ebnf$5\", \"stmt\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"function_decl\", \"symbols\": [(lexer.has(\"FUNCTION\") ? {type: \"FUNCTION\"} : FUNCTION), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), \"function_decl$ebnf$1\", (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), \"parameter_type\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI), \"function_decl$ebnf$2\", \"function_decl$ebnf$3\", \"function_decl$ebnf$4\", \"function_decl$ebnf$5\", (lexer.has(\"END_FUNCTION\") ? {type: \"END_FUNCTION\"} : END_FUNCTION), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'fun', id:d[1].value,\n \tprms:toArr(d[2],'a_fun_prms'),\n \tres:d[4],\n \tctts:toArr(d[6],'a_fun_ctts'),\n \tcsts:toArr(d[7],'a_fun_csts'),\n \tlcls:toArr(d[8],'a_fun_lcls'),\n \tstms:toArr(d[9],'a_fun_stms'), p:pNfo(d[0])\n }) },\n {\"name\": \"procedure_decl$ebnf$1\", \"symbols\": [\"p_formal_params\"], \"postprocess\": id},\n {\"name\": \"procedure_decl$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"procedure_decl$ebnf$2\", \"symbols\": []},\n {\"name\": \"procedure_decl$ebnf$2\", \"symbols\": [\"procedure_decl$ebnf$2\", \"declaration\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"procedure_decl$ebnf$3\", \"symbols\": [\"constant_decl\"], \"postprocess\": id},\n {\"name\": \"procedure_decl$ebnf$3\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"procedure_decl$ebnf$4\", \"symbols\": [\"local_decl\"], \"postprocess\": id},\n {\"name\": \"procedure_decl$ebnf$4\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"procedure_decl$ebnf$5\", \"symbols\": []},\n {\"name\": \"procedure_decl$ebnf$5\", \"symbols\": [\"procedure_decl$ebnf$5\", \"stmt\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"procedure_decl\", \"symbols\": [(lexer.has(\"PROCEDURE\") ? {type: \"PROCEDURE\"} : PROCEDURE), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), \"procedure_decl$ebnf$1\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI), \"procedure_decl$ebnf$2\", \"procedure_decl$ebnf$3\", \"procedure_decl$ebnf$4\", \"procedure_decl$ebnf$5\", (lexer.has(\"END_PROCEDURE\") ? {type: \"END_PROCEDURE\"} : END_PROCEDURE), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'prc', id:d[1].value,\n \tprms:toArr(d[2],'a_prc_prms'),\n \tctts:toArr(d[4],'a_prc_ctts'),\n \tcsts:toArr(d[5],'a_prc_csts'),\n \tlcls:toArr(d[6],'a_prc_lcls'),\n \tstms:toArr(d[7],'a_prc_stms'), p:pNfo(d[0])\n }) },\n {\"name\": \"rule_decl$ebnf$1\", \"symbols\": []},\n {\"name\": \"rule_decl$ebnf$1\", \"symbols\": [\"rule_decl$ebnf$1\", \"declaration\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"rule_decl$ebnf$2\", \"symbols\": [\"constant_decl\"], \"postprocess\": id},\n {\"name\": \"rule_decl$ebnf$2\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"rule_decl$ebnf$3\", \"symbols\": [\"local_decl\"], \"postprocess\": id},\n {\"name\": \"rule_decl$ebnf$3\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"rule_decl$ebnf$4\", \"symbols\": []},\n {\"name\": \"rule_decl$ebnf$4\", \"symbols\": [\"rule_decl$ebnf$4\", \"stmt\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"rule_decl\", \"symbols\": [(lexer.has(\"RULE\") ? {type: \"RULE\"} : RULE), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), (lexer.has(\"FOR\") ? {type: \"FOR\"} : FOR), (lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"ntt_ref_list\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI), \"rule_decl$ebnf$1\", \"rule_decl$ebnf$2\", \"rule_decl$ebnf$3\", \"rule_decl$ebnf$4\", \"where_clause\", (lexer.has(\"END_RULE\") ? {type: \"END_RULE\"} : END_RULE), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'rul', id:d[1].value,\n \tnttRefs:toArr(d[4],'a_rul_refs'),\n \tctts:toArr(d[7],'a_rul_ctts'),\n \tcsts:toArr(d[8],'a_rul_csts'),\n \tlcls:toArr(d[9],'a_rul_lcls'),\n \tstms:toArr(d[10],'a_rul_stms'),\n \twhrs:toArr(d[11],'a_rul_whrs'), p:pNfo(d[0])\n }) },\n {\"name\": \"ntt_ref_list$ebnf$1\", \"symbols\": []},\n {\"name\": \"ntt_ref_list$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"COMMA\") ? {type: \"COMMA\"} : COMMA), \"ntt_ref\"]},\n {\"name\": \"ntt_ref_list$ebnf$1\", \"symbols\": [\"ntt_ref_list$ebnf$1\", \"ntt_ref_list$ebnf$1$subexpression$1\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"ntt_ref_list\", \"symbols\": [\"ntt_ref\", \"ntt_ref_list$ebnf$1\"], \"postprocess\": d => d[1][0]?[d[0]].concat(d[1].map(e=>e.slice(1)[0]) ):[d[0]]},\n {\"name\": \"ntt_ref\", \"symbols\": [(lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'ntt_ref', id:d[0].value, p:pNfo(d[0])})},\n {\"name\": \"declaration$subexpression$1\", \"symbols\": [\"type_decl\"]},\n {\"name\": \"declaration$subexpression$1\", \"symbols\": [\"entity_decl\"]},\n {\"name\": \"declaration$subexpression$1\", \"symbols\": [\"subtype_constraint_decl\"]},\n {\"name\": \"declaration$subexpression$1\", \"symbols\": [\"function_decl\"]},\n {\"name\": \"declaration$subexpression$1\", \"symbols\": [\"procedure_decl\"]},\n {\"name\": \"declaration\", \"symbols\": [\"declaration$subexpression$1\"], \"postprocess\": d => d[0][0]},\n {\"name\": \"local_decl$ebnf$1\", \"symbols\": [\"local_variables\"]},\n {\"name\": \"local_decl$ebnf$1\", \"symbols\": [\"local_decl$ebnf$1\", \"local_variables\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"local_decl\", \"symbols\": [(lexer.has(\"LOCAL\") ? {type: \"LOCAL\"} : LOCAL), \"local_decl$ebnf$1\", (lexer.has(\"END_LOCAL\") ? {type: \"END_LOCAL\"} : END_LOCAL), (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => d[1]},\n {\"name\": \"local_variables$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"ASSIGN\") ? {type: \"ASSIGN\"} : ASSIGN), \"expression\"]},\n {\"name\": \"local_variables$ebnf$1\", \"symbols\": [\"local_variables$ebnf$1$subexpression$1\"], \"postprocess\": id},\n {\"name\": \"local_variables$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"local_variables\", \"symbols\": [\"variable_id_list\", (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), \"parameter_type\", \"local_variables$ebnf$1\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'lcl_dcl', ids:toArr(d[0],'a_lcl_ids'), typ:d[2], xpr:(d[3]?d[3][1]:null), p:pNfo(d[0])})},\n {\"name\": \"variable_id_list$ebnf$1\", \"symbols\": []},\n {\"name\": \"variable_id_list$ebnf$1$subexpression$1\", \"symbols\": [(lexer.has(\"COMMA\") ? {type: \"COMMA\"} : COMMA), \"variable_id\"]},\n {\"name\": \"variable_id_list$ebnf$1\", \"symbols\": [\"variable_id_list$ebnf$1\", \"variable_id_list$ebnf$1$subexpression$1\"], \"postprocess\": function arrpush(d) {return d[0].concat([d[1]]);}},\n {\"name\": \"variable_id_list\", \"symbols\": [\"variable_id\", \"variable_id_list$ebnf$1\"], \"postprocess\": d => d[1][0]?[d[0]].concat(d[1].map(e=>e.slice(1)[0]) ):[d[0]]},\n {\"name\": \"variable_id\", \"symbols\": [(lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'lcl', id:d[0].value, p:pNfo(d[0])})},\n {\"name\": \"parameter_type$subexpression$1\", \"symbols\": [\"generalized_types\"]},\n {\"name\": \"parameter_type$subexpression$1\", \"symbols\": [\"simple_types\"]},\n {\"name\": \"parameter_type$subexpression$1\", \"symbols\": [\"named_types\"]},\n {\"name\": \"parameter_type\", \"symbols\": [\"parameter_type$subexpression$1\"], \"postprocess\": d => d[0][0]},\n {\"name\": \"generalized_types$subexpression$1\", \"symbols\": [\"aggregate_type\"]},\n {\"name\": \"generalized_types$subexpression$1\", \"symbols\": [\"general_aggregation_types\"]},\n {\"name\": \"generalized_types$subexpression$1\", \"symbols\": [\"generic_entity_type\"]},\n {\"name\": \"generalized_types$subexpression$1\", \"symbols\": [\"generic_type\"]},\n {\"name\": \"generalized_types\", \"symbols\": [\"generalized_types$subexpression$1\"], \"postprocess\": d => d[0][0]},\n {\"name\": \"general_aggregation_types$subexpression$1\", \"symbols\": [\"general_array_type\"]},\n {\"name\": \"general_aggregation_types$subexpression$1\", \"symbols\": [\"general_bag_type\"]},\n {\"name\": \"general_aggregation_types$subexpression$1\", \"symbols\": [\"general_list_type\"]},\n {\"name\": \"general_aggregation_types$subexpression$1\", \"symbols\": [\"general_set_type\"]},\n {\"name\": \"general_aggregation_types\", \"symbols\": [\"general_aggregation_types$subexpression$1\"], \"postprocess\": d => d[0][0]},\n {\"name\": \"general_array_type$ebnf$1\", \"symbols\": [\"bound_spec\"], \"postprocess\": id},\n {\"name\": \"general_array_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_array_type$ebnf$2\", \"symbols\": [(lexer.has(\"OPTIONAL\") ? {type: \"OPTIONAL\"} : OPTIONAL)], \"postprocess\": id},\n {\"name\": \"general_array_type$ebnf$2\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_array_type$ebnf$3\", \"symbols\": [(lexer.has(\"UNIQUE\") ? {type: \"UNIQUE\"} : UNIQUE)], \"postprocess\": id},\n {\"name\": \"general_array_type$ebnf$3\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_array_type\", \"symbols\": [(lexer.has(\"ARRAY\") ? {type: \"ARRAY\"} : ARRAY), \"general_array_type$ebnf$1\", (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"general_array_type$ebnf$2\", \"general_array_type$ebnf$3\", \"parameter_type\"], \"postprocess\": d => ({t:'arr', bds:toBds(d[1]), opt:(!!d[3]), unq:(!!d[4]), spc:d[5], p:pNfo(d[0])})},\n {\"name\": \"general_bag_type$ebnf$1\", \"symbols\": [\"bound_spec\"], \"postprocess\": id},\n {\"name\": \"general_bag_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_bag_type\", \"symbols\": [(lexer.has(\"BAG\") ? {type: \"BAG\"} : BAG), \"general_bag_type$ebnf$1\", (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"parameter_type\"], \"postprocess\": d => ({t:'bag', bds:toBds(d[1]), spc:d[3], p:pNfo(d[0])})},\n {\"name\": \"general_list_type$ebnf$1\", \"symbols\": [\"bound_spec\"], \"postprocess\": id},\n {\"name\": \"general_list_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_list_type$ebnf$2\", \"symbols\": [(lexer.has(\"UNIQUE\") ? {type: \"UNIQUE\"} : UNIQUE)], \"postprocess\": id},\n {\"name\": \"general_list_type$ebnf$2\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_list_type\", \"symbols\": [(lexer.has(\"LIST\") ? {type: \"LIST\"} : LIST), \"general_list_type$ebnf$1\", (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"general_list_type$ebnf$2\", \"parameter_type\"], \"postprocess\": d => ({t:'lst', bds:toBds(d[1]), unq:(!!d[3]), spc:d[4], p:pNfo(d[0])})},\n {\"name\": \"general_set_type$ebnf$1\", \"symbols\": [\"bound_spec\"], \"postprocess\": id},\n {\"name\": \"general_set_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"general_set_type\", \"symbols\": [(lexer.has(\"SET\") ? {type: \"SET\"} : SET), \"general_set_type$ebnf$1\", (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"parameter_type\"], \"postprocess\": d => ({t:'set', bds:toBds(d[1]), spc:d[3], p:pNfo(d[0])})},\n {\"name\": \"bound_spec\", \"symbols\": [(lexer.has(\"LB\") ? {type: \"LB\"} : LB), \"simple_expression\", (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), \"simple_expression\", (lexer.has(\"RB\") ? {type: \"RB\"} : RB)], \"postprocess\": d => ({t:'bds', fr:d[1], to:d[3], p:pNfo(d[0])})},\n {\"name\": \"generic_type\", \"symbols\": [(lexer.has(\"GENERIC\") ? {type: \"GENERIC\"} : GENERIC)], \"postprocess\": d => ({t:'gen', p:pNfo(d[0])})},\n {\"name\": \"generic_type\", \"symbols\": [(lexer.has(\"GENERIC\") ? {type: \"GENERIC\"} : GENERIC), (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'gen_lbld', lbl:d[2].value, p:pNfo(d[0])})},\n {\"name\": \"generic_entity_type\", \"symbols\": [(lexer.has(\"GENERIC_ENTITY\") ? {type: \"GENERIC_ENTITY\"} : GENERIC_ENTITY)], \"postprocess\": d => ({t:'gtt', p:pNfo(d[0])})},\n {\"name\": \"generic_entity_type\", \"symbols\": [(lexer.has(\"GENERIC_ENTITY\") ? {type: \"GENERIC_ENTITY\"} : GENERIC_ENTITY), (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'gtt_lbld', lbl:d[2].value, p:pNfo(d[0])})},\n {\"name\": \"aggregate_type\", \"symbols\": [(lexer.has(\"AGGREGATE\") ? {type: \"AGGREGATE\"} : AGGREGATE), (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"parameter_type\"], \"postprocess\": d => ({t:'agt', spc:d[2], p:pNfo(d[0])})},\n {\"name\": \"aggregate_type\", \"symbols\": [(lexer.has(\"AGGREGATE\") ? {type: \"AGGREGATE\"} : AGGREGATE), (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), (lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID), (lexer.has(\"OF\") ? {type: \"OF\"} : OF), \"parameter_type\"], \"postprocess\": d => ({t:'agt_lbld', lbl:d[2].value, spc:d[4], p:pNfo(d[0])})},\n {\"name\": \"simple_types$subexpression$1\", \"symbols\": [(lexer.has(\"BOOLEAN\") ? {type: \"BOOLEAN\"} : BOOLEAN)]},\n {\"name\": \"simple_types$subexpression$1\", \"symbols\": [(lexer.has(\"INTEGER\") ? {type: \"INTEGER\"} : INTEGER)]},\n {\"name\": \"simple_types$subexpression$1\", \"symbols\": [(lexer.has(\"LOGICAL\") ? {type: \"LOGICAL\"} : LOGICAL)]},\n {\"name\": \"simple_types$subexpression$1\", \"symbols\": [(lexer.has(\"NUMBER\") ? {type: \"NUMBER\"} : NUMBER)]},\n {\"name\": \"simple_types\", \"symbols\": [\"simple_types$subexpression$1\"], \"postprocess\": d => ({t:toSim(d)})},\n {\"name\": \"simple_types\", \"symbols\": [\"real_type\"], \"postprocess\": d => (toReal(d[0]))},\n {\"name\": \"simple_types\", \"symbols\": [\"string_type\"], \"postprocess\": d => (toStr(d[0]))},\n {\"name\": \"simple_types\", \"symbols\": [\"binary_type\"], \"postprocess\": d => (toBin(d[0]))},\n {\"name\": \"named_types\", \"symbols\": [(lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => toEotRef(d[0])},\n {\"name\": \"real_type$ebnf$1\", \"symbols\": [\"precision_spec\"], \"postprocess\": id},\n {\"name\": \"real_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"real_type\", \"symbols\": [(lexer.has(\"REAL\") ? {type: \"REAL\"} : REAL), \"real_type$ebnf$1\"]},\n {\"name\": \"precision_spec\", \"symbols\": [(lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"one_to_bounds_expr\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP)], \"postprocess\": d => ({width:d[1], p:pNfo(d[0])})},\n {\"name\": \"string_type$ebnf$1\", \"symbols\": [\"width_spec\"], \"postprocess\": id},\n {\"name\": \"string_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"string_type\", \"symbols\": [(lexer.has(\"STRING\") ? {type: \"STRING\"} : STRING), \"string_type$ebnf$1\"]},\n {\"name\": \"binary_type$ebnf$1\", \"symbols\": [\"width_spec\"], \"postprocess\": id},\n {\"name\": \"binary_type$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"binary_type\", \"symbols\": [(lexer.has(\"BINARY\") ? {type: \"BINARY\"} : BINARY), \"binary_type$ebnf$1\"]},\n {\"name\": \"width_spec$ebnf$1\", \"symbols\": [(lexer.has(\"FIXED\") ? {type: \"FIXED\"} : FIXED)], \"postprocess\": id},\n {\"name\": \"width_spec$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"width_spec\", \"symbols\": [(lexer.has(\"LP\") ? {type: \"LP\"} : LP), \"one_to_bounds_expr\", (lexer.has(\"RP\") ? {type: \"RP\"} : RP), \"width_spec$ebnf$1\"], \"postprocess\": d => ({width:d[1], fixed:(!!d[3]), p:pNfo(d[0])})},\n {\"name\": \"one_to_bounds_expr\", \"symbols\": [(lexer.has(\"INT\") ? {type: \"INT\"} : INT)], \"postprocess\": d => d[0]},\n {\"name\": \"one_to_bounds_expr\", \"symbols\": [(lexer.has(\"SIMPLE_ID\") ? {type: \"SIMPLE_ID\"} : SIMPLE_ID)], \"postprocess\": d => ({t:'width_ref', id:d[0].value, p:pNfo(d[0])})},\n {\"name\": \"explicit_attr$ebnf$1\", \"symbols\": [(lexer.has(\"OPTIONAL\") ? {type: \"OPTIONAL\"} : OPTIONAL)], \"postprocess\": id},\n {\"name\": \"explicit_attr$ebnf$1\", \"symbols\": [], \"postprocess\": function(d) {return null;}},\n {\"name\": \"explicit_attr\", \"symbols\": [\"attr_list\", (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), \"explicit_attr$ebnf$1\", \"parameter_type\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'atr_dcl', ids:toArr(d[0],'a_atr_ids'), opt:(!!d[2]), typ:d[3], p:pNfo(d[0])})},\n {\"name\": \"derived_attr\", \"symbols\": [\"attr\", (lexer.has(\"COLON\") ? {type: \"COLON\"} : COLON), \"parameter_type\", (lexer.has(\"ASSIGN\") ? {type: \"ASSIGN\"} : ASSIGN), \"expression\", (lexer.has(\"SEMI\") ? {type: \"SEMI\"} : SEMI)], \"postprocess\": d => ({t:'drv', id:d[0], typ:d[2], xpr:d[4], p:pNfo(d[0])})},\n {\"name\": \"inverse_attr$ebnf$1$subexpression$1$subexpression$1\", \"symbols\": [(lexer.has(\"SET\") ? {type: \"SET\"} : SET)]},\n {\"name\": \"inverse_attr$ebnf$1$subexpression$1$subexpression$1\", \"symbols\": [(lexer.has(\"BAG\") ? {type: \"BAG\"} : BAG)]},\n {\"name\": \"inverse_attr$ebnf$1$subexpression$1$ebnf$1\", \"symbols\": [\"bound_spec\"], \"postprocess\": id},\n {\"name\": \"inverse_attr$ebnf$1$subexpression$1$ebnf$1\", \"