StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
5.1 KiB
177 lines
5.1 KiB
'use strict';
|
|
|
|
var Tokenizer = require('../tokenizer');
|
|
var List = require('../utils/list');
|
|
var sequence = require('./sequence');
|
|
var noop = function() {};
|
|
|
|
function createParseContext(name) {
|
|
return function() {
|
|
return this[name]();
|
|
};
|
|
}
|
|
|
|
function processConfig(config) {
|
|
var parserConfig = {
|
|
context: {},
|
|
scope: {},
|
|
atrule: {},
|
|
pseudo: {}
|
|
};
|
|
|
|
if (config.parseContext) {
|
|
for (var name in config.parseContext) {
|
|
switch (typeof config.parseContext[name]) {
|
|
case 'function':
|
|
parserConfig.context[name] = config.parseContext[name];
|
|
break;
|
|
|
|
case 'string':
|
|
parserConfig.context[name] = createParseContext(config.parseContext[name]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config.scope) {
|
|
for (var name in config.scope) {
|
|
parserConfig.scope[name] = config.scope[name];
|
|
}
|
|
}
|
|
|
|
if (config.atrule) {
|
|
for (var name in config.atrule) {
|
|
var atrule = config.atrule[name];
|
|
|
|
if (atrule.parse) {
|
|
parserConfig.atrule[name] = atrule.parse;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config.pseudo) {
|
|
for (var name in config.pseudo) {
|
|
var pseudo = config.pseudo[name];
|
|
|
|
if (pseudo.parse) {
|
|
parserConfig.pseudo[name] = pseudo.parse;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (config.node) {
|
|
for (var name in config.node) {
|
|
parserConfig[name] = config.node[name].parse;
|
|
}
|
|
}
|
|
|
|
return parserConfig;
|
|
}
|
|
|
|
module.exports = function createParser(config) {
|
|
var parser = {
|
|
scanner: new Tokenizer(),
|
|
filename: '<unknown>',
|
|
needPositions: false,
|
|
onParseError: noop,
|
|
onParseErrorThrow: false,
|
|
parseAtrulePrelude: true,
|
|
parseRulePrelude: true,
|
|
parseValue: true,
|
|
parseCustomProperty: false,
|
|
|
|
readSequence: sequence,
|
|
|
|
createList: function() {
|
|
return new List();
|
|
},
|
|
createSingleNodeList: function(node) {
|
|
return new List().appendData(node);
|
|
},
|
|
getFirstListNode: function(list) {
|
|
return list && list.first();
|
|
},
|
|
getLastListNode: function(list) {
|
|
return list.last();
|
|
},
|
|
|
|
parseWithFallback: function(consumer, fallback) {
|
|
var startToken = this.scanner.currentToken;
|
|
|
|
try {
|
|
return consumer.call(this);
|
|
} catch (e) {
|
|
if (this.onParseErrorThrow) {
|
|
throw e;
|
|
}
|
|
|
|
var fallbackNode = fallback.call(this, startToken);
|
|
|
|
this.onParseErrorThrow = true;
|
|
this.onParseError(e, fallbackNode);
|
|
this.onParseErrorThrow = false;
|
|
|
|
return fallbackNode;
|
|
}
|
|
},
|
|
|
|
getLocation: function(start, end) {
|
|
if (this.needPositions) {
|
|
return this.scanner.getLocationRange(
|
|
start,
|
|
end,
|
|
this.filename
|
|
);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
getLocationFromList: function(list) {
|
|
if (this.needPositions) {
|
|
var head = this.getFirstListNode(list);
|
|
var tail = this.getLastListNode(list);
|
|
return this.scanner.getLocationRange(
|
|
head !== null ? head.loc.start.offset - this.scanner.startOffset : this.scanner.tokenStart,
|
|
tail !== null ? tail.loc.end.offset - this.scanner.startOffset : this.scanner.tokenStart,
|
|
this.filename
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
config = processConfig(config || {});
|
|
for (var key in config) {
|
|
parser[key] = config[key];
|
|
}
|
|
|
|
return function(source, options) {
|
|
options = options || {};
|
|
|
|
var context = options.context || 'default';
|
|
var ast;
|
|
|
|
parser.scanner.setSource(source, options.offset, options.line, options.column);
|
|
parser.filename = options.filename || '<unknown>';
|
|
parser.needPositions = Boolean(options.positions);
|
|
parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop;
|
|
parser.onParseErrorThrow = false;
|
|
parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
|
|
parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
|
|
parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
|
|
parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
|
|
|
|
if (!parser.context.hasOwnProperty(context)) {
|
|
throw new Error('Unknown context `' + context + '`');
|
|
}
|
|
|
|
ast = parser.context[context].call(parser, options);
|
|
|
|
if (!parser.scanner.eof) {
|
|
parser.scanner.error();
|
|
}
|
|
|
|
return ast;
|
|
};
|
|
};
|
|
|