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.
147 lines
4.2 KiB
147 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; |
|
}
|
|
|