"unexpected token: '{'" in GREP

Hi, folks.

I’m doing the GREP exercise in the JS track. All tests pass in my local machine, but when I submit the solution it fails here in Exercism. If I try to run the same code using the online test runner, it shows me this error:

unexpected token: '{'

I copied/pasted the same solution from VSCode to the editor here, thinking it might be some problem with the CLI. But the result is the same.

I can’t for the life of me find this mysterious {, nor does VSCode. Have tried all things that came to mind, checked all strings, double checked all functions and loops, etc. So I thought of checking with you people.

My code is the following:

#!/usr/bin/env node

const fs = require("fs");
const path = require("path");

/**
 * Reads the given file and returns lines.
 *
 * This function works regardless of POSIX (LF) or windows (CRLF) encoding.
 *
 * @param {string} file path to file
 * @returns {string[]} the lines
 */
function readLines(file) {
  const data = fs.readFileSync(path.resolve(file), { encoding: "utf-8" });
  return data.split(/\r?\n/);
}

const VALID_OPTIONS = [
  "-n", // add line numbers
  "-l", // print file names where pattern is found
  "-i", // ignore case
  "-v", // reverse files results
  "-x", // match entire line
];

const ARGS = process.argv.slice(2);

const flags = [];
while (ARGS.length) {
  const arg = ARGS.shift();
  if (VALID_OPTIONS.includes(arg)) flags.push(arg);
  else {
    ARGS.unshift(arg);
    break;
  }
}

const pattern = ARGS.shift();

const files = [];
while (ARGS.length) {
  const arg = ARGS.shift();
  files.push(arg);
}

function processGREP() {
  if (!pattern) {
    console.error("No pattern");
    return;
  }
  if (!files.length) {
    console.error("No files to search");
    return;
  }

  const invert = flags.includes("-v");
  const onlyFileName = flags.includes("-l");
  const lineNum = flags.includes("-n");
  const allLine = flags.includes("-x");
  const caseInsensitive = flags.includes("-i");
  const addFileName = files.length > 1;

  const regex = ((_pattern) => {
    if (allLine) _pattern = `^${_pattern}$`;
    if (caseInsensitive) return new RegExp(_pattern, "i");
    return new RegExp(_pattern);
  })(pattern);

  const text = files.map(readLines);

  if (onlyFileName) {
    return text.reduce((acc, lines, txtIDX) => {
      if (lines.some((line) => invert ^ regex.test(line)))
        acc.push(files[txtIDX]);
      return acc;
    }, []);
  }
  
  return text.map((lines, txtIDX) => {
    return lines.reduce((acc, line, lineIDX) => {
      if (invert ^ regex.test(line)) {
        if (lineNum) line = `${lineIDX + 1}:${line}`;
        if (addFileName) line = `${files[txtIDX]}:${line}`;
        acc.push(line);
      }
      return acc;
    }, []);
  });
}

const results = processGREP();
results?.forEach((result) => {
  if (Array.isArray(result)) {
    result.forEach((line) => {
      console.log(line);
    });
  } else console.log(result);
});
1 Like

I didn’t spot the error, but hooray for XOR!

1 Like

FWIW the error seems to be in the test runner. If you delete all the code and hit run, you’ll get the same error.

+cc @SleeplessByte

2 Likes

Sorry, this exercise is not (yet) supported online. I have not yet marked it as such.

You can submit it using the CLI.

1 Like

I did that and the test failed. So I tried to solve it online. Let me try again.

Maybe it was CloudFlare + BGP hijack?

Now it worked!

I guess it might’ve been some temporary problem, it happened a couple times with other exercises this weekend. The other times I tried the test runner and the same solution passed, so it didn’t occur to me to submit using the CLI a second time.

Anyways, thank you, people. Sorry for taking your time.

1 Like