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.
181 lines
5.6 KiB
181 lines
5.6 KiB
4 years ago
|
var cmpChar = require('../../tokenizer').cmpChar;
|
||
|
var isNumber = require('../../tokenizer').isNumber;
|
||
|
var TYPE = require('../../tokenizer').TYPE;
|
||
|
|
||
|
var IDENTIFIER = TYPE.Identifier;
|
||
|
var NUMBER = TYPE.Number;
|
||
|
var PLUSSIGN = TYPE.PlusSign;
|
||
|
var HYPHENMINUS = TYPE.HyphenMinus;
|
||
|
var N = 110; // 'n'.charCodeAt(0)
|
||
|
var DISALLOW_SIGN = true;
|
||
|
var ALLOW_SIGN = false;
|
||
|
|
||
|
function checkTokenIsInteger(scanner, disallowSign) {
|
||
|
var pos = scanner.tokenStart;
|
||
|
|
||
|
if (scanner.source.charCodeAt(pos) === PLUSSIGN ||
|
||
|
scanner.source.charCodeAt(pos) === HYPHENMINUS) {
|
||
|
if (disallowSign) {
|
||
|
scanner.error();
|
||
|
}
|
||
|
pos++;
|
||
|
}
|
||
|
|
||
|
for (; pos < scanner.tokenEnd; pos++) {
|
||
|
if (!isNumber(scanner.source.charCodeAt(pos))) {
|
||
|
scanner.error('Unexpected input', pos);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
|
||
|
module.exports = {
|
||
|
name: 'AnPlusB',
|
||
|
structure: {
|
||
|
a: [String, null],
|
||
|
b: [String, null]
|
||
|
},
|
||
|
parse: function() {
|
||
|
var start = this.scanner.tokenStart;
|
||
|
var end = start;
|
||
|
var prefix = '';
|
||
|
var a = null;
|
||
|
var b = null;
|
||
|
|
||
|
if (this.scanner.tokenType === NUMBER ||
|
||
|
this.scanner.tokenType === PLUSSIGN) {
|
||
|
checkTokenIsInteger(this.scanner, ALLOW_SIGN);
|
||
|
prefix = this.scanner.getTokenValue();
|
||
|
this.scanner.next();
|
||
|
end = this.scanner.tokenStart;
|
||
|
}
|
||
|
|
||
|
if (this.scanner.tokenType === IDENTIFIER) {
|
||
|
var bStart = this.scanner.tokenStart;
|
||
|
|
||
|
if (cmpChar(this.scanner.source, bStart, HYPHENMINUS)) {
|
||
|
if (prefix === '') {
|
||
|
prefix = '-';
|
||
|
bStart++;
|
||
|
} else {
|
||
|
this.scanner.error('Unexpected hyphen minus');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!cmpChar(this.scanner.source, bStart, N)) {
|
||
|
this.scanner.error();
|
||
|
}
|
||
|
|
||
|
a = prefix === '' ? '1' :
|
||
|
prefix === '+' ? '+1' :
|
||
|
prefix === '-' ? '-1' :
|
||
|
prefix;
|
||
|
|
||
|
var len = this.scanner.tokenEnd - bStart;
|
||
|
if (len > 1) {
|
||
|
// ..n-..
|
||
|
if (this.scanner.source.charCodeAt(bStart + 1) !== HYPHENMINUS) {
|
||
|
this.scanner.error('Unexpected input', bStart + 1);
|
||
|
}
|
||
|
|
||
|
if (len > 2) {
|
||
|
// ..n-{number}..
|
||
|
this.scanner.tokenStart = bStart + 2;
|
||
|
} else {
|
||
|
// ..n- {number}
|
||
|
this.scanner.next();
|
||
|
this.scanner.skipSC();
|
||
|
}
|
||
|
|
||
|
checkTokenIsInteger(this.scanner, DISALLOW_SIGN);
|
||
|
b = '-' + this.scanner.getTokenValue();
|
||
|
this.scanner.next();
|
||
|
end = this.scanner.tokenStart;
|
||
|
} else {
|
||
|
prefix = '';
|
||
|
this.scanner.next();
|
||
|
end = this.scanner.tokenStart;
|
||
|
this.scanner.skipSC();
|
||
|
|
||
|
if (this.scanner.tokenType === HYPHENMINUS ||
|
||
|
this.scanner.tokenType === PLUSSIGN) {
|
||
|
prefix = this.scanner.getTokenValue();
|
||
|
this.scanner.next();
|
||
|
this.scanner.skipSC();
|
||
|
}
|
||
|
|
||
|
if (this.scanner.tokenType === NUMBER) {
|
||
|
checkTokenIsInteger(this.scanner, prefix !== '');
|
||
|
|
||
|
if (!isNumber(this.scanner.source.charCodeAt(this.scanner.tokenStart))) {
|
||
|
prefix = this.scanner.source.charAt(this.scanner.tokenStart);
|
||
|
this.scanner.tokenStart++;
|
||
|
}
|
||
|
|
||
|
if (prefix === '') {
|
||
|
// should be an operator before number
|
||
|
this.scanner.error();
|
||
|
} else if (prefix === '+') {
|
||
|
// plus is using by default
|
||
|
prefix = '';
|
||
|
}
|
||
|
|
||
|
b = prefix + this.scanner.getTokenValue();
|
||
|
|
||
|
this.scanner.next();
|
||
|
end = this.scanner.tokenStart;
|
||
|
} else {
|
||
|
if (prefix) {
|
||
|
this.scanner.eat(NUMBER);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (prefix === '' || prefix === '+') { // no number
|
||
|
this.scanner.error(
|
||
|
'Number or identifier is expected',
|
||
|
this.scanner.tokenStart + (
|
||
|
this.scanner.tokenType === PLUSSIGN ||
|
||
|
this.scanner.tokenType === HYPHENMINUS
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
b = prefix;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
type: 'AnPlusB',
|
||
|
loc: this.getLocation(start, end),
|
||
|
a: a,
|
||
|
b: b
|
||
|
};
|
||
|
},
|
||
|
generate: function(node) {
|
||
|
var a = node.a !== null && node.a !== undefined;
|
||
|
var b = node.b !== null && node.b !== undefined;
|
||
|
|
||
|
if (a) {
|
||
|
this.chunk(
|
||
|
node.a === '+1' ? '+n' :
|
||
|
node.a === '1' ? 'n' :
|
||
|
node.a === '-1' ? '-n' :
|
||
|
node.a + 'n'
|
||
|
);
|
||
|
|
||
|
if (b) {
|
||
|
b = String(node.b);
|
||
|
if (b.charAt(0) === '-' || b.charAt(0) === '+') {
|
||
|
this.chunk(b.charAt(0));
|
||
|
this.chunk(b.substr(1));
|
||
|
} else {
|
||
|
this.chunk('+');
|
||
|
this.chunk(b);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
this.chunk(String(node.b));
|
||
|
}
|
||
|
}
|
||
|
};
|