Chevrotain / chevrotain

Parser Building Toolkit for JavaScript
https://chevrotain.io
Apache License 2.0
2.44k stars 199 forks source link

DSL for parsing bas tag:client title:magic #2033

Closed gaborbernat closed 1 week ago

gaborbernat commented 1 week ago

I am trying to parse a text where keys can have fields attached to it: bas tag:client title:magic, but I am getting NotAllInputParsedException: Redundant input, expecting EOF but found: title:

import { CstParser, Lexer, createToken } from "chevrotain";
const WhiteSpace = createToken({ name: "WhiteSpace", pattern: /\s+/, group: Lexer.SKIPPED });
const Value = createToken({ name: "Identifier", pattern: /[-a-zA-Z0-9]+/ });
const FieldSpecifier = createToken({ name: "Identifier", pattern: /(tag|title):/ });
const allTokens = [WhiteSpace, Value, FieldSpecifier];
const lexer = new Lexer([FieldSpecifier, Value, WhiteSpace]);

class SelectParser extends CstParser {
  constructor() {
    super(allTokens);
    // biome-ignore lint/complexity/noUselessThisAlias: required for chevrotain
    const $ = this;

    $.RULE("element", () => {
      $.OPTION(() => {
        $.CONSUME(FieldSpecifier);
      });
      $.CONSUME2(Value);
    });

    $.RULE("search", () => {
      $.MANY_SEP({
        SEP: WhiteSpace,
        DEF: () => {
          $.SUBRULE($.element);
        },
      });
    });

    this.performSelfAnalysis();
  }
}

const parser = new SelectParser();

export function parse(text: string) {
  const lexingResult = lexer.tokenize(text);
  // "input" is a setter which will reset the parser's state.
  parser.input = lexingResult.tokens;
  parser.search();
  if (parser.errors.length > 0) {
    throw parser.errors[0];
  }
}

Ideas?