diff --git a/package.json b/package.json index 315734c..cd6fd52 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "author": "David Morrison ", "license": "MIT", "scripts": { + "build": "cd src; jison language.json", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage" @@ -18,6 +19,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "jest": "27", + "jison": "^0.4.18", "prettier": "^2.6.2", "source-map-support": "^0.5.21", "ts-jest": "^27.1.4", diff --git a/src/index.ts b/src/index.ts index c392ae2..d34035d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,4 +3,4 @@ export * from "./transform_fwd"; export * from "./transform_rev"; export * from "./analysis"; export * from "./names"; -export * from "./language"; \ No newline at end of file +export * from "./parser"; \ No newline at end of file diff --git a/src/language.js b/src/language.js new file mode 100644 index 0000000..7b42559 --- /dev/null +++ b/src/language.js @@ -0,0 +1,775 @@ +/* parser generated by jison 0.4.18 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var language = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,7],$V1=[1,9],$V2=[1,10],$V3=[1,11],$V4=[1,8],$V5=[1,6],$V6=[1,15],$V7=[1,16],$V8=[1,17],$V9=[1,18],$Va=[1,19],$Vb=[1,20],$Vc=[1,21],$Vd=[1,22],$Ve=[1,23],$Vf=[1,24],$Vg=[1,25],$Vh=[1,26],$Vi=[1,32],$Vj=[1,6,24,25,26,27,28,29,30,31,32,34,36,38],$Vk=[2,12],$Vl=[1,6,22,24,25,26,27,28,29,30,31,32,34,36,38],$Vm=[1,37],$Vn=[1,6,22,24,25,26,27,28,29,30,31,32,34,36],$Vo=[1,58],$Vp=[2,15]; +var parser = {trace: function trace () { }, +yy: {}, +symbols_: {"error":2,"Document":3,"StatementSequence":4,"Statement":5,".":6,"ColorSequence":7,"Color":8,"Assignment":9,"testcase":10,"Number":11,"Identifier":12,"is":13,"digits":14,"ColorHex":15,"hmj":16,"(":17,")":18,"Adjustment":19,"AdjSequence":20,"rainbow":21,"in":22,"steps":23,"lighter":24,"darker":25,"shaded":26,"contrast":27,"stronger":28,"weaker":29,"warmer":30,"cooler":31,"1st":32,"triadic":33,"2nd":34,"tetradic":35,"3rd":36,"by":37,"to":38,"$accept":0,"$end":1}, +terminals_: {2:"error",6:".",10:"testcase",12:"Identifier",13:"is",14:"digits",15:"ColorHex",16:"hmj",17:"(",18:")",21:"rainbow",22:"in",23:"steps",24:"lighter",25:"darker",26:"shaded",27:"contrast",28:"stronger",29:"weaker",30:"warmer",31:"cooler",32:"1st",33:"triadic",34:"2nd",35:"tetradic",36:"3rd",37:"by",38:"to"}, +productions_: [0,[3,1],[4,1],[4,3],[5,1],[5,1],[5,1],[5,2],[5,2],[5,2],[9,3],[11,1],[8,1],[8,1],[8,6],[8,2],[7,2],[7,2],[7,4],[20,4],[19,1],[19,1],[19,1],[19,1],[19,1],[19,1],[19,1],[19,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,3],[19,2]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */, cam16) { +/* this == yyval */ + +var $0 = $$.length - 1; +switch (yystate) { +case 1: +return $$[$0] +break; +case 2: case 4: case 7: case 8: +this.$ = $$[$0] +break; +case 3: +this.$ = [...$$[$0-2], ...$$[$0]] +break; +case 5: +this.$ = [$$[$0]] +break; +case 6: +this.$ = [] +break; +case 9: +this.$ = identifiers +break; +case 10: +identifiers[$$[$0-2]] = $$[$0]; this.$ = $$[$0] +break; +case 11: +this.$ = Number($$[$0]) +break; +case 12: +this.$ = identifiers[$$[$0]] +break; +case 13: +this.$ = cam16.hex_to_cam16_ucs_ingamut($$[$0]); +break; +case 14: +this.$ = cam16.cam16_ucs_to_hex_ingamut({ Hu: $$[$0-3], Mu: $$[$0-2], Ju: $$[$0-1] }) +break; +case 15: +this.$ = cam16.cam16_ucs_adjust($$[$0], $$[$0-1])[0]; +break; +case 16: +this.$ = cam16.cam16_ucs_adjust($$[$0], $$[$0-1]); +break; +case 17: +this.$ = cam16.cam16_ucs_adjust($$[$0], ...$$[$0-1]); +break; +case 18: +this.$ = cam16.cam16_ucs_rainbow({ steps: $$[$0-1] }); +break; +case 19: +this.$ = {...$$[$0-3], steps: $$[$0-1] } +break; +case 20: +this.$ = { Jub: +5 } +break; +case 21: +this.$ = { Jub: -5 } +break; +case 22: +this.$ = { Jua: 0.95, Mua: 0.95 } +break; +case 23: +this.$ = { Jub: +75, contrast: true } +break; +case 24: +this.$ = { Mub: +5 } +break; +case 25: +this.$ = { Mub: -5 } +break; +case 26: +this.$ = { Hub: +5 } +break; +case 27: +this.$ = { Hub: -5 } +break; +case 28: +this.$ = { Hub: +120 } +break; +case 29: +this.$ = { Hub: +240 } +break; +case 30: +this.$ = { Hub: +90 } +break; +case 31: +this.$ = { Hub: +180 } +break; +case 32: +this.$ = { Hub: +270 } +break; +case 33: +this.$ = { Jub: +$$[$0] } +break; +case 34: +this.$ = { Jub: -$$[$0] } +break; +case 35: +this.$ = { Jua: 1-$$[$0]/100, Mua: 1-$$[$0]/100 } +break; +case 36: +this.$ = { Jub: +$$[$0], contrast: true } +break; +case 37: +this.$ = { Mub: +$$[$0] } +break; +case 38: +this.$ = { Mub: -$$[$0] } +break; +case 39: +this.$ = { Hub: +$$[$0] } +break; +case 40: +this.$ = { Hub: -$$[$0] } +break; +case 41: case 42: +this.$ = { Jua: 0, Jub: +$$[$0] } +break; +case 43: case 44: +this.$ = { Mua: 0, Mub: +$$[$0] } +break; +case 45: case 46: +this.$ = { Hua: 0, Hub: +$$[$0] } +break; +case 47: +this.$ = { Jua: 0, Jub: +$$[$0].Ju, Mua: 0, Mub: +$$[$0].Mu, Hua: 0, Hub: +$$[$0].Hu } +break; +} +}, +table: [{3:1,4:2,5:3,7:4,8:5,9:6,10:$V0,12:$V1,15:$V2,16:$V3,21:$V4},{1:[3]},{1:[2,1],6:[1,12]},o($V5,[2,2]),o($V5,[2,4],{20:13,19:14,24:$V6,25:$V7,26:$V8,27:$V9,28:$Va,29:$Vb,30:$Vc,31:$Vd,32:$Ve,34:$Vf,36:$Vg,38:$Vh}),o($V5,[2,5],{20:27,19:28,24:$V6,25:$V7,26:$V8,27:$V9,28:$Va,29:$Vb,30:$Vc,31:$Vd,32:$Ve,34:$Vf,36:$Vg,38:$Vh}),o($V5,[2,6]),{8:30,9:31,11:29,12:$V1,14:$Vi,15:$V2,16:$V3},{22:[1,33]},o($Vj,$Vk,{13:[1,34]}),o($Vl,[2,13]),{17:[1,35]},{5:36,7:4,8:5,9:6,10:$V0,12:$V1,15:$V2,16:$V3,21:$V4},o($Vj,[2,17]),{22:$Vm},o($Vn,[2,20],{37:[1,38],38:[1,39]}),o($Vn,[2,21],{37:[1,40],38:[1,41]}),o($Vl,[2,22],{37:[1,42]}),o($Vl,[2,23],{37:[1,43]}),o($Vn,[2,24],{37:[1,44],38:[1,45]}),o($Vn,[2,25],{37:[1,46],38:[1,47]}),o($Vn,[2,26],{37:[1,48],38:[1,49]}),o($Vn,[2,27],{37:[1,50],38:[1,51]}),{33:[1,52],35:[1,53]},{33:[1,54],35:[1,55]},{35:[1,56]},{8:57,12:$Vo,15:$V2,16:$V3},o($Vj,[2,16]),o($Vj,$Vp,{22:$Vm}),o($V5,[2,7]),o($V5,[2,8],{19:59,24:$V6,25:$V7,26:$V8,27:$V9,28:$Va,29:$Vb,30:$Vc,31:$Vd,32:$Ve,34:$Vf,36:$Vg,38:$Vh}),o($V5,[2,9]),o([1,6,14,18,22,23,24,25,26,27,28,29,30,31,32,34,36,38],[2,11]),{11:60,14:$Vi},{8:61,12:$Vo,15:$V2,16:$V3},{11:62,14:$Vi},o($V5,[2,3]),{11:63,14:$Vi},{11:64,14:$Vi},{11:65,14:$Vi},{11:66,14:$Vi},{11:67,14:$Vi},{11:68,14:$Vi},{11:69,14:$Vi},{11:70,14:$Vi},{11:71,14:$Vi},{11:72,14:$Vi},{11:73,14:$Vi},{11:74,14:$Vi},{11:75,14:$Vi},{11:76,14:$Vi},{11:77,14:$Vi},o($Vl,[2,28]),o($Vl,[2,30]),o($Vl,[2,29]),o($Vl,[2,31]),o($Vl,[2,32]),o([1,6,22],[2,47],{19:59,24:$V6,25:$V7,26:$V8,27:$V9,28:$Va,29:$Vb,30:$Vc,31:$Vd,32:$Ve,34:$Vf,36:$Vg,38:$Vh}),o($Vl,$Vk),o($Vl,$Vp),{23:[1,78]},o($V5,[2,10],{19:59,24:$V6,25:$V7,26:$V8,27:$V9,28:$Va,29:$Vb,30:$Vc,31:$Vd,32:$Ve,34:$Vf,36:$Vg,38:$Vh}),{11:79,14:$Vi},{23:[1,80]},o($Vl,[2,33]),o($Vl,[2,41]),o($Vl,[2,34]),o($Vl,[2,42]),o($Vl,[2,35]),o($Vl,[2,36]),o($Vl,[2,37]),o($Vl,[2,43]),o($Vl,[2,38]),o($Vl,[2,44]),o($Vl,[2,39]),o($Vl,[2,45]),o($Vl,[2,40]),o($Vl,[2,46]),o($Vj,[2,18]),{11:81,14:$Vi},o($Vj,[2,19]),{18:[1,82]},o($Vl,[2,14])], +defaultActions: {}, +parseError: function parseError (str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } +}, +parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + _token_stack: + var lex = function () { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + return token; + }; + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; +}}; +let identifiers={};/* generated by jison-lex 0.3.4 */ +var lexer = (function(){ +var lexer = ({ + +EOF:1, + +parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + +// resets the lexer, sets new input +setInput:function (input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0,0]; + } + this.offset = 0; + return this; + }, + +// consumes and returns one char from the input +input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + + this._input = this._input.slice(1); + return ch; + }, + +// unshifts one char (or a string) into the input +unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; + + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + +// When called from action, caches matched text and appends it on next action +more:function () { + this._more = true; + return this; + }, + +// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. +reject:function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + + } + return this; + }, + +// retain first n characters of the match +less:function (n) { + this.unput(this.match.slice(n)); + }, + +// displays already matched input, i.e. for error messages +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, + +// displays upcoming input, i.e. for error messages +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + +// displays the character position where the lexing error occurred, i.e. for error messages +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + +// test the lexed token: return FALSE when not a match, otherwise return token +test_match:function(match, indexed_rule) { + var token, + lines, + backup; + + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? + lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, + +// return next match in input +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + + var token, + match, + tempMatch, + index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + +// return next match that has a token +lex:function lex () { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + +// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) +begin:function begin (condition) { + this.conditionStack.push(condition); + }, + +// pop the previously active lexer condition state off the condition stack +popState:function popState () { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + +// produce the lexer rule set which is active for the currently active lexer condition state +_currentRules:function _currentRules () { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + +// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available +topState:function topState (n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + +// alias for begin(condition) +pushState:function pushState (condition) { + this.begin(condition); + }, + +// return the number of states currently on the stack +stateStackSize:function stateStackSize() { + return this.conditionStack.length; + }, +options: {}, +performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { +var YYSTATE=YY_START; +switch($avoiding_name_collisions) { +case 0:/* skip whitespace */ +break; +case 1:/* skip comma */ +break; +case 2:return 10; +break; +case 3:return 24; +break; +case 4:return 25; +break; +case 5:return 26; +break; +case 6:return 27; +break; +case 7:return 28; +break; +case 8:return 29; +break; +case 9:return 30; +break; +case 10:return 31; +break; +case 11:return 'complimented'; +break; +case 12:return 33; +break; +case 13:return 35; +break; +case 14:return 21; +break; +case 15:return 32; +break; +case 16:return 34; +break; +case 17:return 36; +break; +case 18:return 16; +break; +case 19:return 37; +break; +case 20:return 38; +break; +case 21:return 13; +break; +case 22:return 'and'; +break; +case 23:return 22; +break; +case 24:return 23; +break; +case 25:return 17; +break; +case 26:return 18; +break; +case 27:return 6; +break; +case 28:return ','; +break; +case 29:return 14; +break; +case 30:return 15; +break; +case 31:return 12; +break; +} +}, +rules: [/^(?:\s+)/,/^(?:,)/,/^(?:testcase)/,/^(?:lighter)/,/^(?:darker)/,/^(?:shaded)/,/^(?:contrast)/,/^(?:stronger)/,/^(?:weaker)/,/^(?:warmer)/,/^(?:cooler)/,/^(?:complimented)/,/^(?:triadic)/,/^(?:tetradic)/,/^(?:rainbow)/,/^(?:1st)/,/^(?:2nd)/,/^(?:3rd)/,/^(?:hmj)/,/^(?:by)/,/^(?:to)/,/^(?:is)/,/^(?:and)/,/^(?:in)/,/^(?:steps?)/,/^(?:\()/,/^(?:\))/,/^(?:\.)/,/^(?:,)/,/^(?:[+-]?[0-9]+(\.[0-9]+)?)/,/^(?:#[0-9a-fA-F]{6})/,/^(?:[a-zA-Z][[a-zA-Z0-9]*)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31],"inclusive":true}} +}); +return lexer; +})(); +parser.lexer = lexer; +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})(); + + +if (typeof require !== 'undefined' && typeof exports !== 'undefined') { +exports.parser = language; +exports.Parser = language.Parser; +exports.parse = function () { return language.parse.apply(language, arguments); }; +exports.main = true; +if (typeof module !== 'undefined' && require.main === module) { + exports.main(process.argv.slice(1)); +} +} \ No newline at end of file diff --git a/src/language.json b/src/language.json new file mode 100644 index 0000000..52e4dd5 --- /dev/null +++ b/src/language.json @@ -0,0 +1,114 @@ +{ + "options": { + "moduleType": "default", + "moduleMain": true + }, + "moduleInclude": "let identifiers={};", + "parseParams": ["cam16"], + "lex": { + "rules": [ + ["\\s+", "/* skip whitespace */"], + [",", "/* skip comma */"], + ["testcase", "return 'testcase';"], + ["lighter", "return 'lighter';"], + ["darker", "return 'darker';"], + ["shaded", "return 'shaded';"], + ["contrast", "return 'contrast';"], + ["stronger", "return 'stronger';"], + ["weaker", "return 'weaker';"], + ["warmer", "return 'warmer';"], + ["cooler", "return 'cooler';"], + ["complimented", "return 'complimented';"], + ["triadic", "return 'triadic';"], + ["tetradic", "return 'tetradic';"], + ["rainbow", "return 'rainbow';"], + ["1st", "return '1st';"], + ["2nd", "return '2nd';"], + ["3rd", "return '3rd';"], + ["hmj", "return 'hmj';"], + ["by", "return 'by';"], + ["to", "return 'to';"], + ["is", "return 'is';"], + ["and", "return 'and';"], + ["in", "return 'in';"], + ["steps?", "return 'steps';"], + ["\\(", "return '(';"], + ["\\)", "return ')';"], + ["\\.", "return '.';"], + [",", "return ',';"], + ["[+-]?[0-9]+(\\.[0-9]+)?", "return 'digits';"], + ["#[0-9a-fA-F]{6}", "return 'ColorHex';"], + ["[a-zA-Z][[a-zA-Z0-9]*", "return 'Identifier';"] + ] + }, + "operators": [ + ["right", "AdjSequence"] + ], + "bnf": { + "Document": [ + [ "StatementSequence", "return $1" ] + ], + "StatementSequence": [ + [ "Statement", "$$ = $1" ], + [ "StatementSequence . Statement", "$$ = [...$1, ...$3]"] + ], + "Statement": [ + [ "ColorSequence", "$$ = $1" ], + [ "Color", "$$ = [$1]" ], + [ "Assignment", "$$ = []" ], + [ "testcase Number", "$$ = $2" ], + [ "testcase Color", "$$ = $2" ], + [ "testcase Assignment", "$$ = identifiers" ] + ], + "Assignment": [ + [ "Identifier is Color", "identifiers[$1] = $3; $$ = $3" ] + ], + "Number": [ + [ "digits", "$$ = Number($1)" ] + ], + "Color": [ + [ "Identifier", "$$ = identifiers[$1]" ], + [ "ColorHex", "$$ = cam16.hex_to_cam16_ucs_ingamut($1);" ], + [ "hmj ( Number Number Number )", "$$ = cam16.cam16_ucs_to_hex_ingamut({ Hu: $3, Mu: $4, Ju: $5 })" ], + [ "Color Adjustment","$$ = cam16.cam16_ucs_adjust($2, $1)[0];" ] + ], + "ColorSequence" :[ + [ "Color AdjSequence","$$ = cam16.cam16_ucs_adjust($2, $1);" ], + [ "ColorSequence AdjSequence","$$ = cam16.cam16_ucs_adjust($2, ...$1);" ], + [ "rainbow in Number steps","$$ = cam16.cam16_ucs_rainbow({ steps: $3 });" ] + ], + "AdjSequence": [ + ["Adjustment in Number steps", "$$ = {...$1, steps: $3 }"] + ], + "Adjustment" :[ + [ "lighter","$$ = { Jub: +5 }" ], + [ "darker","$$ = { Jub: -5 }" ], + [ "shaded","$$ = { Jua: 0.95, Mua: 0.95 }" ], + [ "contrast","$$ = { Jub: +75, contrast: true }" ], + [ "stronger","$$ = { Mub: +5 }" ], + [ "weaker","$$ = { Mub: -5 }" ], + [ "warmer","$$ = { Hub: +5 }" ], + [ "cooler","$$ = { Hub: -5 }" ], + [ "1st triadic","$$ = { Hub: +120 }" ], + [ "2nd triadic","$$ = { Hub: +240 }" ], + [ "1st tetradic","$$ = { Hub: +90 }" ], + [ "2nd tetradic","$$ = { Hub: +180 }" ], + [ "3rd tetradic","$$ = { Hub: +270 }" ], + [ "lighter by Number","$$ = { Jub: +$3 }" ], + [ "darker by Number","$$ = { Jub: -$3 }" ], + [ "shaded by Number","$$ = { Jua: 1-$3/100, Mua: 1-$3/100 }" ], + [ "contrast by Number","$$ = { Jub: +$3, contrast: true }" ], + [ "stronger by Number","$$ = { Mub: +$3 }" ], + [ "weaker by Number","$$ = { Mub: -$3 }" ], + [ "warmer by Number","$$ = { Hub: +$3 }" ], + [ "cooler by Number","$$ = { Hub: -$3 }" ], + [ "lighter to Number","$$ = { Jua: 0, Jub: +$3 }" ], + [ "darker to Number","$$ = { Jua: 0, Jub: +$3 }" ], + [ "stronger to Number","$$ = { Mua: 0, Mub: +$3 }" ], + [ "weaker to Number","$$ = { Mua: 0, Mub: +$3 }" ], + [ "warmer to Number","$$ = { Hua: 0, Hub: +$3 }" ], + [ "cooler to Number","$$ = { Hua: 0, Hub: +$3 }" ], + [ "to Color","$$ = { Jua: 0, Jub: +$2.Ju, Mua: 0, Mub: +$2.Mu, Hua: 0, Hub: +$2.Hu }" ] + ] + } +} diff --git a/src/language.ts b/src/language.ts deleted file mode 100644 index d33c5ab..0000000 --- a/src/language.ts +++ /dev/null @@ -1 +0,0 @@ -export const parser = {} \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts new file mode 100644 index 0000000..171cdbb --- /dev/null +++ b/src/parser.ts @@ -0,0 +1,30 @@ +import { JuMuHuHex } from './types' +import { cam16_ucs_adjust } from './analysis' +import { cam16_ucs_to_hex_ingamut } from './transform_rev' +import { hex_to_cam16_ucs_ingamut } from './transform_fwd' + +// functions passed to language.js +const cam16 = { + cam16_ucs_adjust, + cam16_ucs_to_hex_ingamut, + hex_to_cam16_ucs_ingamut +} + +///////////////////////////////////////////////////////////////////////////////// +// WARNING - with OPTION2 whenever language.json is changed, must re-run jison // +///////////////////////////////////////////////////////////////////////////////// + +// OPTION 1: Runtime generation of parse +// import { Parser } from 'jison' +// import { readFileSync } from 'fs' +// const grammar = readFileSync('./language.json', 'utf8') +// const theme_grammar = (new Parser(JSON.parse(grammar))) +// const parse = function (t:string, c:Cam16) { return theme_grammar.parse.apply(theme_grammar, [t, c]); }; + +// OPTION 2 Buildtime generation of parse with command 'jison language.json' +import { parse } from './language' + +export function parse_color_theme(text: string): JuMuHuHex[] { + return parse(text, cam16) +} + diff --git a/test/parser.spec.ts b/test/parser.spec.ts new file mode 100644 index 0000000..a982225 --- /dev/null +++ b/test/parser.spec.ts @@ -0,0 +1,67 @@ +import { describe, expect, test } from '@jest/globals' +import { parse_color_theme } from '../src/index' + +describe('Color Language Parser Functions', () => { + + test('should be defined', () => { + expect(true).toBeDefined(); + }); + + test('should parse +/- Numbers into js number', () => { + const definitions = [ + { text: 'testcase 10', result: 10 }, + { text: 'testcase 1.3', result: 1.3 }, + { text: 'testcase +0.1', result: 0.1 }, + { text: 'testcase 0', result: 0 }, + { text: 'testcase -100', result: -100 }, + { text: 'testcase -1.3', result: -1.3 }, + ] + definitions.forEach(({ text, result }) => { + expect(parse_color_theme(text)).toEqual(result); + + }) + }); + + test('should parse a Colors into js Objects with cam16 ucs components and hex', () => { + const definitions = [ + { text: 'testcase #ff0000', result: { hexLabel2: "52J101" } }, + { text: 'testcase hmj(0,40,50)', result: { hexLabel2: "50I80" } }, + { text: 'testcase hmj(0,100,50)', result: { hexLabel2: "50I97" } }, + { text: 'testcase hmj(270,20,50) darker by 21', result: { hexLabel2: "29v40" } }, + ] + definitions.forEach(({ text, result }) => { + expect(parse_color_theme(text)).toMatchObject(result); + + }) + }); + + // test('should parse color assignments and use of identifiers', () => { + // const definitions = [ + // { text: 'primary is hmj(10,10,50). secondary is hmj(180,20,40). primary lighter by 8', result: [{ Ju: 58 }] }, + // { text: 'primary is hmj(10,10,50). secondary is hmj(180,20,40). primary to secondary in 3 steps', result: [{ Ju: 50 },{ Ju: 45 },{ Ju: 40 }] }, + // ] + // definitions.forEach(({ text, result }) => { + // expect(parse_color_theme(text)).toMatchObject(result); + + // }) + // }); + + // test('should parse a color theme into an array of colors', () => { + // const definitions = [ + // // { text: '#800000 lighter by 30 in 3 steps', result: '#ff8000' }, + // // { text: '#ff8000, warmer, in 5 steps. #cdeee1, darker by 10, in 5 steps. ', result: '#jjj' }, + // // { text: '#ff8000', result: '#ff8000' }, + // // { text: 'primary is darker', result: {Ju: -5, Mu:0, Hu:0} }, + // // { text: 'primary is darker by 7', result: 10 }, + // // { text: 'primary is v-model. primary swatches, stronger from 0 to 100 in 5 steps , darker from 100 to 0 in 5 steps.', result: 20 }, + // // { text: 'text is primary, contrasting by 100', result: 30 }, + // // { text: 'gradient is from red to 1st triadic, in 6 steps', result: 30 }, + // // { text: 'gradient 2 is from blue to 1st triadic, in 6 steps', result: 30 }, + // ] + // definitions.forEach(({ text, result }) => { + // expect(parse_color_theme(text).map(c => c.hex)).toEqual(result); + // }) + // }); + + +}) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2134096..708fd22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -667,6 +667,16 @@ dependencies: "@types/yargs-parser" "*" +JSONSelect@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.4.0.tgz#a08edcc67eb3fcbe99ed630855344a0cf282bb8d" + integrity sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40= + +"JSV@>= 4.0.x": + version "4.0.2" + resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" + integrity sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c= + abab@^2.0.3, abab@^2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" @@ -722,6 +732,11 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -753,6 +768,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= + anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -936,6 +956,15 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -951,6 +980,13 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== +cjson@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.3.0.tgz#e6439b90703d312ff6e2224097bea92ce3d02a14" + integrity sha1-5kObkHA9MS/24iJAl76pLOPQKhQ= + dependencies: + jsonlint "1.6.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -994,6 +1030,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colors@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" + integrity sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q= + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1114,6 +1155,11 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" +ebnf-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/ebnf-parser/-/ebnf-parser-0.1.10.tgz#cd1f6ba477c5638c40c97ed9b572db5bab5d8331" + integrity sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE= + electron-to-chromium@^1.4.118: version "1.4.121" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.121.tgz#e2fa3b7bd592643c6b12ae6de2882550a29b7799" @@ -1156,6 +1202,17 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escodegen@1.3.x: + version "1.3.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23" + integrity sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM= + dependencies: + esprima "~1.1.1" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.33" + escodegen@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" @@ -1255,6 +1312,11 @@ espree@^9.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^3.3.0" +esprima@1.1.x, esprima@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" + integrity sha1-W28VR/TRAuZw4UDFCb5ncdautUk= + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -1279,11 +1341,21 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + integrity sha1-hno+jlip+EYYr7bC3bzZFrfLr3E= + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + integrity sha1-gVHTWOIMisx/t0XnRywAJf5JZXA= + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1461,6 +1533,11 @@ graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2064,6 +2141,28 @@ jest@27: import-local "^3.0.2" jest-cli "^27.5.1" +jison-lex@0.3.x: + version "0.3.4" + resolved "https://registry.yarnpkg.com/jison-lex/-/jison-lex-0.3.4.tgz#81ca28d84f84499dfa8c594dcde3d8a3f26ec7a5" + integrity sha1-gcoo2E+ESZ36jFlNzePYo/Jux6U= + dependencies: + lex-parser "0.1.x" + nomnom "1.5.2" + +jison@^0.4.18: + version "0.4.18" + resolved "https://registry.yarnpkg.com/jison/-/jison-0.4.18.tgz#c68a6a54bfe7028fa40bcfc6cc8bbd9ed291f502" + integrity sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w== + dependencies: + JSONSelect "0.4.0" + cjson "0.3.0" + ebnf-parser "0.1.10" + escodegen "1.3.x" + esprima "1.1.x" + jison-lex "0.3.x" + lex-parser "~0.1.3" + nomnom "1.5.2" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -2149,6 +2248,14 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonlint@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.0.tgz#88aa46bc289a7ac93bb46cae2d58a187a9bb494a" + integrity sha1-iKpGvCiaesk7tGyuLVihh6m7SUo= + dependencies: + JSV ">= 4.0.x" + nomnom ">= 1.5.x" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -2175,6 +2282,11 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lex-parser@0.1.x, lex-parser@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/lex-parser/-/lex-parser-0.1.4.tgz#64c4f025f17fd53bfb45763faeb16f015a747550" + integrity sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA= + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -2290,6 +2402,22 @@ node-releases@^2.0.3: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== +nomnom@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f" + integrity sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8= + dependencies: + colors "0.5.x" + underscore "1.1.x" + +"nomnom@>= 1.5.x": + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc= + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2609,6 +2737,13 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map@~0.1.33: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2645,6 +2780,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -2848,6 +2988,16 @@ typescript@^4.6.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== +underscore@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.1.7.tgz#40bab84bad19d230096e8d6ef628bff055d83db0" + integrity sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA= + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + integrity sha1-izixDKze9jM3uLJOT/htRa6lKag= + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"