kanat is too fat
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.

148 lines
4.2 KiB

function parse(text) {
// https://github.com/shioyadan/Konata/blob/master/docs/kanata-log-format.md
const before = performance.now();
let line_start = 0;
let line_index = 0;
//console.log(text);
for (let i = 0; i < text.length; ++i) {
const c = text[i];
if (c === '\n') {
// TODO: speed
const line_copy = text.substring(line_start, i);
const line_parts = line_copy.split(/\s+/);
if (line_parts.length === 0) {
console.error('Parser error: empty line');
return false;
}
const command = line_parts[0];
switch (command) {
case 'Kanata': {
if (!assert_arglen(line_parts, 1, 'Kanata')) return false;
const version = Number(line_parts[1]);
if (version !== 4) {
console.error('Parser error: only Kanata traces version 4 are supported');
return false;
}
break;
}
case 'C=': {
if (!assert_arglen(line_parts, 1, 'C=')) return false;
const cycles = Number(line_parts[1]);
break;
}
case 'C': {
if (!assert_arglen(line_parts, 1, 'C')) return false;
const cycles = Number(line_parts[1]);
break;
}
case 'I': {
if (!assert_arglen(line_parts, 3, 'I')) return false;
const insn_id_in_file = Number(line_parts[1]);
const insn_id_in_sim = Number(line_parts[2]);
const thread_id = Number(line_parts[3]);
break;
}
case 'L': {
if (!assert_arglenmin(line_parts, 3, 'L')) return false;
const id = Number(line_parts[1]);
const type = Number(line_parts[2]);
const text = line_parts.slice(3).join(' '); // TODO: preserve spacing, newlines
break;
}
case 'S': {
if (!assert_arglen(line_parts, 3, 'S')) return false;
const id = Number(line_parts[1]);
const lane = Number(line_parts[2]);
const stage = line_parts[3];
break;
}
case 'E': {
if (!assert_arglen(line_parts, 3, 'E')) return false;
const id = Number(line_parts[1]);
const lane = Number(line_parts[2]);
const stage = line_parts[3];
break;
}
case 'R': {
if (!assert_arglen(line_parts, 3, 'R')) return false;
const id = Number(line_parts[1]);
const retire_id = Number(line_parts[2]);
const type = Number(line_parts[3]);
break;
}
case 'W': {
if (!assert_arglen(line_parts, 3, 'W')) return false;
const consumer_id = Number(line_parts[1]);
const producer_id = Number(line_parts[2]);
const type = Number(line_parts[3]);
break;
}
default: {
console.error('Parser error: unexpected command', command);
return false;
}
}
//console.log(command);
line_start = i + 1;
line_index += 1;
}
}
const after = performance.now();
console.log(`Parsed in ${Math.round(after - before)}ms`);
}
function assert_arglen(args, arglen, command) {
if (args.length !== arglen + 1) {
console.error(`Parser error: command ${command} requires ${arglen} argument(s)`);
return false;
}
return true;
}
function assert_arglenmin(args, arglen, command) {
if (args.length < arglen + 1) {
console.error(`Parser error: command ${command} requires at least ${arglen} argument(s)`);
return false;
}
return true;
}