Chevrotain / chevrotain

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

Please help me to resolve MANY #1888

Closed Serhioromano closed 1 year ago

Serhioromano commented 1 year ago

This is a code I have

/* eslint-disable @typescript-eslint/naming-convention */
const chevrotain = require("chevrotain");

const createToken = chevrotain.createToken;
const Lexer = chevrotain.Lexer;
const CstParser = chevrotain.CstParser;

const ws = createToken({ name: "WhiteSpace", pattern: /\s+/, group: Lexer.SKIPPED });
const ns = createToken({ name: "NAMESPACE", pattern: /NAMESPACE/ });
const ens = createToken({ name: "END_NAMESPACE", pattern: /END_NAMESPACE/ });
const pg = createToken({ name: "PROGRAM", pattern: /PROGRAM/ });
const epg = createToken({ name: "END_PROGRAM", pattern: /END_PROGRAM/ });
const fun = createToken({ name: "FUNCTION", pattern: /FUNCTION/ });
const efun = createToken({ name: "END_FUNCTION", pattern: /END_FUNCTION/ });
const variable = createToken({ name: "simbol", pattern: /[a-zA-Z]+[a-zA-Z0-9_]*/ });

const allTokens = [
    ws, ens, ns, epg, pg, efun, fun, variable
];

const stLexer = new Lexer(allTokens, {
    deferDefinitionErrorsHandling: true,
    recoveryEnabled: true,
    positionTracking: "full",
});

class StParser extends CstParser {
    constructor() {
        super(allTokens);
        const $ = this;

        $.RULE("iecst", () => {
            $.MANY(() => {
                $.SUBRULE($.namespace);
                $.SUBRULE($.function);
                $.SUBRULE($.program);
            });
        });

        $.RULE("namespace", () => {
            $.CONSUME(ns);
            $.CONSUME(variable);
            $.MANY(() => {
                $.SUBRULE($.program);
                $.SUBRULE($.function);
            });
            $.CONSUME(ens);
        });
        $.RULE("function", () => {
            $.CONSUME(fun);
            $.CONSUME(efun);
        });
        $.RULE("program", () => {
            $.CONSUME(pg);
            $.CONSUME(epg);
        });

        this.performSelfAnalysis();
    }
};

let inputText = `
NAMESPACE MySpace

END_NAMESPACE
FUNCTION
END_FUNCTION`;
let lexingResult = stLexer.tokenize(inputText);
console.log(lexingResult?.tokens);

const parser = new StParser();
parser.input = lexingResult.tokens;
parser.iecst();

if (parser.errors.length > 0) {
    console.log(parser.errors[0]);
}

This code produce error Expecting token of type --> PROGRAM <-- but found --> '' <-- and if I use text like this

let inputText = `
NAMESPACE MySpace

END_NAMESPACE`;

It produce error Expecting token of type --> FUNCTION <-- but found --> '' <--

It looks like it require not MANY as 0 or number but exact order.