chevrotain: Playground error message - question

Hi,

I have an issue that appeared with the playground. It may be just my misakes, but the error message displayed there is not insightful and I can’t progress further after quiet the time, so I am posting here. I looked for a Stack-overflow tag but I could not find one, Please let me know if there is a better place to ask these things, as I see from the current issues that there arent really such help-me question there.

Alright so here, we go. The code in the playground is as follows:

(function jsonGrammarOnlyExample() {
  // ----------------- Lexer -----------------
  const createToken = chevrotain.createToken;
  const Lexer = chevrotain.Lexer;
  const CstParser = chevrotain.CstParser;

  const LSquare = createToken({name: "LSquare", pattern: /\[/});
  const RSquare = createToken({name: "RSquare", pattern: /]/});
  const Slash = createToken({name: "Slash", pattern: /\//});
  const Comma = createToken({name: "Comma", pattern: /,/});
  const MetaChr = createToken({name: "MetaChr", pattern: /[,!@#$%^&*()"':{}=+-;]+/});
  const StringLiteral = createToken({
    name: "StringLiteral", pattern: /(:?[^\\"\n\r]+|\\(:?[bfnrtv"\\/]|u[0-9a-fA-F]{4}))*/
  });
  const NumberLiteral = createToken({
    name: "NumberLiteral", pattern: /-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?/
  });
  const WhiteSpace = createToken({
    name: "WhiteSpace",
    pattern: /\s+/,
    group: Lexer.SKIPPED
  });

  const tokens = [WhiteSpace, NumberLiteral, StringLiteral, LSquare, RSquare, Comma, Slash, MetaChr];

  const yedLexer = new Lexer(tokens, {
    // Less position info tracked, reduces verbosity of the playground output.
    positionTracking: "onlyStart"
  });

  // Labels only affect error messages and Diagrams.
  LSquare.LABEL = "'['";
  RSquare.LABEL = "']'";
  Comma.LABEL = "','";
  Slash.LABEL = "/";

  // ----------------- parser -----------------
  // eventClause
  // : StringLiteral+
  // guardClause
  // : StringLiteral*
  // actionsClause
  // : StringLiteral*
  // edgeClause:
  // [eventClause] [\[ guardClause \]] [/ actionsClause] |

  class Parser extends CstParser {
    constructor() {
      super(tokens, {
        recoveryEnabled: false
      })

      const $ = this;

      $.RULE("yed", () => {
        $.OPTION1(() => {
          $.SUBRULE($.eventClause);
        })
        $.OPTION2(() => {
          $.CONSUME(LSquare);
          $.SUBRULE($.guardClause);
          $.CONSUME(RSquare);
        })
        $.OPTION3(() => {
          $.CONSUME(Slash);
          $.SUBRULE($.actionsClause);
        })
      });

      $.RULE("eventClause", () => {
        $.MANY(() => {
          $.CONSUME(StringLiteral)
        })
      });

      $.RULE("guardClause", () => {
        $.MANY(() => {
          $.CONSUME(StringLiteral)
        })
      });

      $.RULE("actionsClause", () => {
        $.MANY(() => {
          $.CONSUME(StringLiteral)
        })
      });

      // very important to call this after all the rules have been setup.
      // otherwise the parser may not work correctly as it will lack information
      // derived from the self analysis.
      this.performSelfAnalysis();

    }
  }

  // wrapping it all together
  // reuse the same parser instance.
  const parser = new Parser([]);

  // ----------------- Interpreter -----------------
  const BaseCstVisitor = parser.getBaseCstVisitorConstructor()

  class yedInterpreter extends BaseCstVisitor {

    constructor() {
      super(tokens, {recoveryEnabled: false})
      // This helper will detect any missing or redundant methods on this visitor
      this.validateVisitor()
    }

    yed (ctx) {
      return {event: this.visit(ctx.eventClause), guard: this.visit(ctx.guardClause), action: this.visit(ctx.actionsClause)}
    }

    eventClause (ctx){ return ctx.StringLiteral ? ctx.StringLiteral : ""}
    guardClause (ctx){ return ctx.StringLiteral ? ctx.StringLiteral : ""}
    actionsClause (ctx){ return ctx.StringLiteral ? ctx.StringLiteral : ""}
  }

  // for the playground to work the returned object must contain these fields
  return {
    lexer: yedLexer,
    parser: Parser,
    visitor: yedInterpreter,
    defaultRule: "yed"
  };
}())

The input I pass is m m m m / a.

The error message I get is:

Errors during evaluation of the implementation: 
Cannot read property 'PATTERN' of undefined

If that matters, running on Windows in the Brave browser (Chromium 81).

The language I want is fairly simple: a [b] / c for instance shoud be recognized and a, b, c can all be empty strings too. For the STRING_LITERAL, I reused the JSON_LITERAL and removed the starting and end quotes ". When doing that, I get the aforementioned error. If you put the quotes back, the error is no longer but then the string literals are not parsed (because they do not start with a quote).

Any ideas what I can be doing wrong? I don’t see which PATTERN Chevrotain is trying and failing at validating.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

Error handling is hard, and often neglected in most open source projects (just like documentation). In the time I took to implement this small example from scratch from the docs and with no prior knowledge, the truth is the playground and its immediate feedback and helpful error messages was quite helpful. I had the ambiguity messages and a link which helped solve the problem. That’s awesome! A pity it stopped being useful. It is a pretty good tool for starters.

Maybe there should be a quick start template. Sort of like a playground but as a npm package with:

  • Simple Grammar
  • Script to generate diagrams
  • Input file
  • Script to parse the input and serialize it to some JSON output.
  • ???

Basically the flow of the playground but in a real dev env.

The playground is just a simple naive hack not a fully fledged dev env.