Improve location info in tracing events

Replace |line|, |column|, and |offset| properties of tracing events with
the |location| property. It contains an object similar to the one
returned by the |location| function available in action code:

  {
    start: { offset: 23, line: 5, column: 6 },
    end:   { offset: 25, line: 5, column: 8 }
  }

For the |rule.match| event, |start| refers to the position at the
beginning of the matched input and |end| refers to the position after
the end of the matched input.

For |rule.enter| and |rule.fail| events, both |start| and |end| refer to
the current position at the time the rule was entered.
redux
David Majda 10 years ago
parent 065f4e1b75
commit d1fe86683b

@ -44,9 +44,10 @@ function generateJavascript(ast, options) {
if (options.trace) {
parts.push([
'peg$trace({',
' type: "rule.enter",',
' rule: ' + ruleNameCode,
'peg$tracer.trace({',
' type: "rule.enter",',
' rule: ' + ruleNameCode + ',',
' location: peg$computeLocation(startPos, startPos)',
'});',
''
].join('\n'));
@ -65,15 +66,17 @@ function generateJavascript(ast, options) {
if (options.trace) {
parts.push([
'if (cached.result !== peg$FAILED) {',
' peg$trace({',
' peg$tracer.trace({',
' type: "rule.match",',
' rule: ' + ruleNameCode + ',',
' result: cached.result',
' result: cached.result,',
' location: peg$computeLocation(startPos, peg$currPos)',
' });',
'} else {',
' peg$trace({',
' peg$tracer.trace({',
' type: "rule.fail",',
' rule: ' + ruleNameCode,
' rule: ' + ruleNameCode + ',',
' location: peg$computeLocation(startPos, startPos)',
' });',
'}',
''
@ -104,15 +107,17 @@ function generateJavascript(ast, options) {
parts.push([
'',
'if (' + resultCode + ' !== peg$FAILED) {',
' peg$trace({',
' peg$tracer.trace({',
' type: "rule.match",',
' rule: ' + ruleNameCode + ',',
' result: ' + resultCode,
' result: ' + resultCode + ',',
' location: peg$computeLocation(startPos, peg$currPos)',
' });',
'} else {',
' peg$trace({',
' peg$tracer.trace({',
' type: "rule.fail",',
' rule: ' + ruleNameCode,
' rule: ' + ruleNameCode + ',',
' location: peg$computeLocation(startPos, startPos)',
' });',
'}'
].join('\n'));
@ -202,15 +207,31 @@ function generateJavascript(ast, options) {
'}',
'',
'function peg$parseRule(index) {',
' var bc = peg$bytecode[index],',
' ip = 0,',
' ips = [],',
' end = bc.length,',
' ends = [],',
' stack = [],',
' params, i;',
].join('\n'));
if (options.trace) {
parts.push([
' var bc = peg$bytecode[index],',
' ip = 0,',
' ips = [],',
' end = bc.length,',
' ends = [],',
' stack = [],',
' startPos = peg$currPos,',
' params, i;',
].join('\n'));
} else {
parts.push([
' var bc = peg$bytecode[index],',
' ip = 0,',
' ips = [],',
' end = bc.length,',
' ends = [],',
' stack = [],',
' params, i;',
].join('\n'));
}
parts.push(indent2(generateRuleHeader('peg$ruleNames[index]', 'index')));
parts.push([
@ -705,10 +726,18 @@ function generateJavascript(ast, options) {
code = compile(rule.bytecode);
parts.push([
'function peg$parse' + rule.name + '() {',
' var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ';',
].join('\n'));
parts.push('function peg$parse' + rule.name + '() {');
if (options.trace) {
parts.push([
' var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ',',
' startPos = peg$currPos;'
].join('\n'));
} else {
parts.push(
' var ' + arrays.map(arrays.range(0, stack.maxSp + 1), s).join(', ') + ';'
);
}
parts.push(indent2(generateRuleHeader(
'"' + js.stringEscape(rule.name) + '"',
@ -782,7 +811,8 @@ function generateJavascript(ast, options) {
' }',
'',
' console.log(',
' event.line + ":" + event.column + " "',
' event.location.start.line + ":" + event.location.start.column + "-"',
' + event.location.end.line + ":" + event.location.end.column + " "',
' + pad(event.type, 10) + " "',
' + repeat(" ", that.indentLevel) + event.rule',
' );',
@ -1102,21 +1132,6 @@ function generateJavascript(ast, options) {
''
].join('\n'));
if (options.trace) {
parts.push([
' function peg$trace(event) {',
' var posDetails = peg$computePosDetails(peg$currPos);',
'',
' event.offset = peg$currPos;',
' event.line = posDetails.line;',
' event.column = posDetails.column;',
'',
' peg$tracer.trace(event);',
' }',
'',
].join('\n'));
}
if (options.optimize === "size") {
parts.push(indent4(generateInterpreter()));
parts.push('');

@ -54,12 +54,12 @@ describe("generated parser API", function() {
parser.parse("b");
expect(console.log).toHaveBeenCalledWith("1:1 rule.enter start");
expect(console.log).toHaveBeenCalledWith("1:1 rule.enter a");
expect(console.log).toHaveBeenCalledWith("1:1 rule.fail a");
expect(console.log).toHaveBeenCalledWith("1:1 rule.enter b");
expect(console.log).toHaveBeenCalledWith("1:2 rule.match b");
expect(console.log).toHaveBeenCalledWith("1:2 rule.match start");
expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter start");
expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter a");
expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.fail a");
expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter b");
expect(console.log).toHaveBeenCalledWith("1:1-1:2 rule.match b");
expect(console.log).toHaveBeenCalledWith("1:1-1:2 rule.match start");
});
});
@ -73,48 +73,54 @@ describe("generated parser API", function() {
parser.parse("b", { tracer: tracer });
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.enter',
rule: 'start',
offset: 0,
line: 1,
column: 1
type: 'rule.enter',
rule: 'start',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.enter',
rule: 'a',
offset: 0,
line: 1,
column: 1
type: 'rule.enter',
rule: 'a',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.fail',
rule: 'a',
offset: 0,
line: 1,
column: 1
type: 'rule.fail',
rule: 'a',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.enter',
rule: 'b',
offset: 0,
line: 1,
column: 1
type: 'rule.enter',
rule: 'b',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.match',
rule: 'b',
result: 'b',
offset: 1,
line: 1,
column: 2
type: 'rule.match',
rule: 'b',
result: 'b',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 1, line: 1, column: 2 }
}
});
expect(tracer.trace).toHaveBeenCalledWith({
type: 'rule.match',
rule: 'start',
result: 'b',
offset: 1,
line: 1,
column: 2
type: 'rule.match',
rule: 'start',
result: 'b',
location: {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 1, line: 1, column: 2 }
}
});
});
});

@ -157,8 +157,8 @@ describe("PEG.js API", function() {
parser.parse("a");
expect(console.log).toHaveBeenCalledWith("1:1 rule.enter start");
expect(console.log).toHaveBeenCalledWith("1:2 rule.match start");
expect(console.log).toHaveBeenCalledWith("1:1-1:1 rule.enter start");
expect(console.log).toHaveBeenCalledWith("1:1-1:2 rule.match start");
});
});
});

Loading…
Cancel
Save