Skip to content
Astera Technology

Preserve who said a nested quotation

Reported speech is attributed to the reporter as their own request.

Download complete case notes and answer keys ↓

Define the local evaluation task

A synthetic conversation extractor accepts only this local line grammar: Reporter reports [Speaker: text]. Names contain ASCII letters and quoted text contains no brackets. A matching line identifies the reporter and quoted speaker separately and establishes no direct request by the reporter. Any other wording remains unparsed rather than guessed.

  1. Match the declared report grammar
  2. Extract reporter and quoted speaker separately
  3. Retain quoted content without making a request

Unmatched lines retain their raw wording for review.

Use the filled cases

Original synthetic input and literal answer key
CaseSupplied inputExpected structured outputDecision and reason
Reported cancellation{"line":"Ada reports [Bo: cancel X]"}{"reporter":"Ada","quotedSpeaker":"Bo","quotedText":"cancel X","reporterRequest":false}Bo is quoted; Ada reports it, without making an Ada request.
Same name in both roles{"line":"Ada reports [Ada: inspect X]"}{"reporter":"Ada","quotedSpeaker":"Ada","quotedText":"inspect X","reporterRequest":false}Even a matching name remains reported speech under this grammar.
Nested wording beyond grammar{"line":"Ada reports [Bo: Cal says [cancel X]]"}{"error":"grammar"}Nested brackets are not supported; retain the raw line for review.
Download editable CSV ↓

Work the nested-unrecognised case. Which output is required, and why?

Show the worked answer

{"error":"grammar"} — Nested brackets are not supported; retain the raw line for review.

Run the self-contained evaluator

Save as .mjs and run with Node.js; supplied fixtures only
import assert from 'node:assert/strict';

function evaluate(x){
 const m=/^([A-Za-z]+) reports \[([A-Za-z]+): ([^\[\]]+)\]$/.exec(x.line);
 return m?{reporter:m[1],quotedSpeaker:m[2],quotedText:m[3],reporterRequest:false}:{error:'grammar'};
}

const cases = [
  {
    "id": "reported-cancellation",
    "input": {
      "line": "Ada reports [Bo: cancel X]"
    },
    "expected": {
      "reporter": "Ada",
      "quotedSpeaker": "Bo",
      "quotedText": "cancel X",
      "reporterRequest": false
    }
  },
  {
    "id": "same-person-two-roles",
    "input": {
      "line": "Ada reports [Ada: inspect X]"
    },
    "expected": {
      "reporter": "Ada",
      "quotedSpeaker": "Ada",
      "quotedText": "inspect X",
      "reporterRequest": false
    }
  },
  {
    "id": "nested-unrecognised",
    "input": {
      "line": "Ada reports [Bo: Cal says [cancel X]]"
    },
    "expected": {
      "error": "grammar"
    }
  }
];
for (const c of cases) assert.deepEqual(evaluate(c.input), c.expected, c.id);
console.log(JSON.stringify({checked:cases.length,caseIds:cases.map(c=>c.id)}));
Download runnable example ↓

Use the two role fields beside the extracted quote. This bounded parser is a reference answer for the fixture grammar; it does not claim to resolve arbitrary natural-language speech or authorise cancellation.

Related resources