How to use lookahead_1 method in Cucumber-gherkin

Best JavaScript code snippet using cucumber-gherkin

Run Cucumber-gherkin automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

index.js

Source: index.js Github

copy
1const JisonLex           = require("jison-lex"),
2      path               = require("path").win32,
3      fs                 = require("fs"),
4      escapeRegexpString = require("escape-string-regexp");
5
6const grammar = fs.readFileSync(require.resolve("./comspec.l")).toString(),
7      lexer   = new JisonLex(grammar);
8
9// ;;;;;;;;;;;;;;;;;;;;;;;
10// ;; Utility functions ;;
11// ;;;;;;;;;;;;;;;;;;;;;;;
12//
13function stringify_tokens(tokens) {
14    return tokens.map(t => t.text).join("");
15}
16function has (obj, key) {
17    return obj.hasOwnProperty(key);
18}
19
20function hasAll (obj, keys) {
21    return keys.every(k => obj.hasOwnProperty(k));
22}
23
24function hasAny (obj, keys) {
25    return keys.some(k => obj.hasOwnProperty(k));
26}
27
28// ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29// ;;                                    ;;
30// ;; TYPE DEFINITIONS FOR DOCUMENTATION ;;
31// ;;                                    ;;
32// ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33//
34// Token
35// =====
36/**
37 * @typedef {Object} Token
38 * @property {string} name  - Name of the token (LITERAL, SET, ESCAPE, ...).
39 * @property {string} match - Match object for the matched token.
40 * @property {string} line  - Line number upon which the token was found.
41 * @property {string} text  - Similar to 'match'.
42 * @property {number} len   - Length (in chars) of the matched token.
43 * @property {Object} loc   - Location of match (first/last line, first/last col).
44 */
45//
46// Identified Command
47// ==================
48/**
49 * @typedef {Object} IdentifiedCommand
50 * @property {string} command - The name of the command ("" if unknown).
51 * @property {number} offset  - The offset of where the command identifier
52 *                              ends in the tokens array.
53 */
54
55
56/**
57 * Command dispatch table maps commands we can handle to functions
58 * which do the command handling.  Generally, when we're talking about
59 * "handling a command", we mean altering the parsed token stream so
60 * that the tokens are correctly altered based upon the command
61 * handling them.  For example, we may have been passed something
62 * like:
63 *
64 *   cmd "set foo=bar"
65 *
66 * The token stream for this command will look something like:
67 *
68 *   LIT(c), LIT(m), LIT(d), STR("), STRLIT(s), STRLIT(e), ...
69 *
70 * If we remove the leading "cmd " from the string, and strip the
71 * surrounding double quotes from the command and re-tokenise it,
72 * we'll get a new tokenised sequence which we can handle.
73 *
74 */
75const cmd_dispatch = {
76    cmd: FILTER_handle_cmd
77};
78
79/**
80 * Provides specific command clean-up for the 'cmd.exe' command.
81 *
82 * @param {IdentifiedCommand} ident - The identified command object.
83 * @param {Tokens|Array} tokens - The array of tokens from parsing the cmd.
84 *
85 * @returns {Tokens|Array}
86 */
87function FILTER_handle_cmd (ident, tokens) {
88
89    tokens = Array.prototype.slice.call(tokens);
90
91    if (ident.offset >= tokens.length) {
92        return {
93            tokens: tokens,
94            switches: {},
95            finished: true
96        };
97    }
98
99    let cmd = tokens
100            .slice(ident.offset)
101            .map(t => t.text)
102            .join("")
103            .replace(/^\s+/,  "");
104
105    // A note about argument parsing
106    // =============================
107    //
108    // The CMD.EXE help page says that the syntax of the 'cmd.exe'
109    // command is:
110    //
111    //   CMD [charset] [options] [/C command]
112    //   CMD [charset] [options] [/K command]
113    //
114    // For example:
115    //
116    //   CMD /V:on "set foo=bar& calc.exe"
117    //
118    //
119    // The important part is the location of the first dquote, which
120    // tells us where the COMMAND part of the line begins.  We capture
121    // the location of this char (if exists), and use its string
122    // offset as the point at which we stop looking for command
123    // switches.
124    //
125    const first_dquote_offset = cmd.split("").findIndex(chr => chr === '"'),
126          switch_re           = /\/([A-Z])([:][^\s]+)?(?:$|\s)/ig;
127
128    let match             = undefined,
129        last_match_offset = undefined,
130        switches          = {
131            delayed_expansion: false
132        };
133
134    const switch_lookup = {
135        "c": "run_then_terminate",
136        "C": "run_then_terminate",
137        "v": "delayed_expansion",
138        "V": "delayed_expansion",
139        "e": "cmd_extensions",
140        "E": "cmd_extensions",
141        "f": "path_autocomplete",
142        "F": "path_autocomplete"
143    };
144
145    while ((match = switch_re.exec(cmd))) {
146
147        let wholematch       = match[0],
148            _switch          = match[1],
149            _value           = "",
150            match_end_offset = match[0].length + match.index;
151
152        last_match_offset = match_end_offset;
153
154        if (match[2] !== undefined) {
155            _value = match[2].replace(/^:/, "");
156        }
157
158        if (/^[efv]$/i.test(_switch)) {
159            _switch = switch_lookup[_switch];
160            switch (_value.toLowerCase()) {
161            case "off":
162                _value = false;
163                break;
164            default:
165                _value = true;
166            }
167        }
168        else if (has(switch_lookup, _switch)) {
169            _switch = switch_lookup[_switch];
170        }
171
172        switches[_switch] = _value;
173
174        if (match_end_offset && (match_end_offset > first_dquote_offset)) {
175            break;
176        }
177    }
178
179    // Now we've finished parsing the command arguments, we can strip
180    // the args leaving only the next part of the command string.
181    if (last_match_offset !== undefined) {
182        cmd = cmd.substr(last_match_offset);
183    }
184
185    // If the remaining command part starts and ends with a double
186    // quote, we strip them.
187    cmd = cmd.replace(/^\"|\"$/g, "");
188
189    return {
190        tokens: tokenise(cmd),
191        switches: switches,
192        finished: false
193    };
194}
195
196/**
197 * Parses a given command string in to individual commands, before
198 * applying expansion and de-obfuscation filters to each command.
199 *
200 * @param {string} cmdstr - The original command string to be
201 * de-obfuscated.
202 *
203*/
204function parse_cmdstr (cmdstr, options) {
205
206    const DEFAULTS = {
207        delayed_expansion: false,
208        expand_inline:     false,
209        vars: {}
210    };
211
212    options = options || {};
213    options = Object.assign({}, DEFAULTS, options);
214
215    let collector = { vars: {}, switches: {}, output: [] };
216
217    cmdstr = expand_environment_variables(cmdstr, options.vars);
218
219    (function parse_cmdstr_rec (cmdstr, switches) {
220
221        switches = switches || {};
222
223        split_command(cmdstr).forEach(cmd => {
224
225            let result = interpret_command(cmd);
226            collector.vars = Object.assign(collector.vars, result.vars);
227
228            if (result.ident.finished) {
229                collector.output.push(stringify_tokens(result.ident.tokens));
230            }
231            else if (result.ident.command === "cmd") {
232                //
233                // NOTES ON DELAYED EXPANSION
234                // ==========================
235                //
236                // We have support for delayed expansion.  Tests on
237                // Win7 and Win10 hosts show that delayed expansion is
238                // only enabled for the current CMD context, for
239                // example, given the following command:
240                //
241                //   cmd /V "set foo=bar& echo !foo!"
242                //
243                // The output will be "echo bar" because delayed
244                // expansion is set.  However, it does not cascade in
245                // to lower-down CMD instances, for example:
246                //
247                //   cmd /V "cmd \"set foo=bar& echo !foo!\""
248                //
249                // This will produce "echo !foo!" because we created a
250                // sub-cmd context, and the default was applied.
251                //
252                let new_cmd = stringify_tokens(result.ident.tokens);
253
254                if (new_cmd.toLowerCase() !== "cmd") { // infinite loop protection.
255                    parse_cmdstr_rec(
256                        stringify_tokens(result.ident.tokens),
257                        result.ident.switches
258                    );
259                }
260            }
261            else {
262
263                let delayed_exp = Object.assign({}, options, switches).delayed_expansion;
264
265                // We do not want to expand percentage vars as
266                // that time has passed.
267                cmd = expand_environment_variables(
268                    result.clean,
269                    collector.vars,
270                    {
271                        expand_percent_vars: options.expand_inline,
272                        delayed_expansion: delayed_exp
273                    }
274                );
275
276                collector.output.push(cmd);
277            }
278        });
279    }(cmdstr));
280
281    return collector.output;
282}
283
284/**
285 * Given an array of Token objects, attempts to identify the command
286 * being run.  If a command is found, an IdentifiedCommand object is
287 * returned which will contain both the command name and the offset
288 * from where abouts in the tokens array the command string ends.  If
289 * the command cannot be found, returns an empty name ("") and -1 for
290 * the offset.
291 *
292 * For best results, this command should be called AFTER all filtering
293 * has taken place, thus ensuring the command is in the least
294 * obfuscated state BEFORE attempting command identification.
295 *
296 * @param {Token|Array} tokens - The command string to analyse.
297 * @returns {IdentifiedCommand}
298 */
299function try_identify_command (tokens) {
300
301    tokens = Array.prototype.slice.call(tokens);
302
303    let identified_command = {
304        command : "",
305        switches: {},
306        offset  : -1
307    };
308
309    /*
310     * Double-Quoted commands
311     * ======================
312     *
313     * For example, matches something similar to:
314     *
315     *   "C:\Windows\System32\cmd.exe"
316     *   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
317     */
318    if (tokens[0].name === "STRING_DQUOTE_BEGIN") {
319
320        let dquote_end_index = tokens.findIndex(
321            (t, i) => i > 0 && t.name === "STRING_DQUOTE_END"
322        );
323
324        if (!dquote_end_index) {
325            // We can't do much if the CMD doesn't have an ending
326            // DQUOTE.  Bad command.
327            return identified_command;
328        }
329
330        let cmd = tokens
331                .splice(0, dquote_end_index)
332                .map(tok => tok.text)
333                .join("")
334                .replace(/^\"|\"$/g, "");
335
336        identified_command.command = path.basename(cmd).replace(/\.exe$/i, "");
337        identified_command.offset  = dquote_end_index + 1;
338    }
339    else if (tokens[0].name === "SET") {
340        identified_command.command = "set";
341        identified_command.offset  = 1;
342    }
343    else {
344
345        let end_index = tokens.findIndex(t => (t.text === " " || t.name === "SEMICOLON"));
346        end_index = (end_index < 0) ? tokens.length : end_index;
347
348        let cmd = tokens
349                .splice(0, end_index)
350                .map(tok => tok.text)
351                .join("");
352
353        if (/[\\/]/.test(cmd) || /^[a-z]:/i.test(cmd)) {
354            // If the path contains path separators, or some drive
355            // identifier such as 'C:', then clean-up the path and
356            // return the command.
357            identified_command.command = path.basename(cmd).replace(/\.exe$/i, "");
358            identified_command.offset  = end_index + 1;
359        }
360        else if (cmd) {
361            identified_command.command = cmd.replace(/\.exe$/i, "");
362            identified_command.offset  = end_index;
363        }
364    }
365
366    return identified_command;
367}
368
369/**
370 * Given an array of Token objects, attempts to remove all non-quoted
371 * contiguous whitespace LITERALS, leaving a single space between each
372 * word boundary.
373 *
374 * @param {Token|Array} tokens - An array of tokens.
375 * @returns {Token|Array}
376 */
377function FILTER_strip_excessive_whitespace (tokens) {
378
379    for (let i = 0; i < tokens.length; i++) {
380
381        let token      = tokens[i],
382            lookahead  = tokens[i + 1];
383
384        if (token.name === "LITERAL" && token.text === " ") {
385            if (i === 0) {
386                tokens.splice(0,1);
387                i = -1;
388            }
389            else if (i === (tokens.length - 1) && token.text === " ") {
390                tokens.splice(i, 1);
391                i = -1;
392            }
393            else if (lookahead && lookahead.name === "LITERAL" && lookahead.text === " ") {
394                tokens.splice(i, 1);
395                i = -1;
396            }
397
398        }
399    }
400
401    return tokens;
402}
403
404
405/**
406 * Given a command string, attempts to slurp all LITERAL,
407 * non-whitespace tokens surrounding a string inside that string.  For
408 * example:
409 *
410 *   c"alc".exe  --[slurped]--> "calc.exe"
411 *
412 * @param {Token|Array} tokens - An array of tokens.
413 * @returns {Token|Array}
414 */
415function FILTER_slurp_literals_into_strings (tokens) {
416
417    for (let i = 0; i < tokens.length; i++) {
418
419        let token      = tokens[i],
420            lookahead  = tokens[i + 1],
421            lookbehind = tokens[i - 1];
422
423        if (token.name === "STRING_DQUOTE_BEGIN") {
424            if (lookbehind && lookbehind.name === "LITERAL" && lookbehind.text !== " ") {
425                tokens[i - 1] = token;
426                tokens[i]     = lookbehind;
427                tokens[i].name = "STRING_DQUOTE_CHAR";
428                i = 0;
429            }
430        }
431        else if (token.name === "STRING_DQUOTE_END") {
432            if (lookahead && lookahead.name === "LITERAL" && lookahead.text !== " ") {
433                tokens[i + 1] = token;
434                tokens[i]     = lookahead;
435                tokens[i].name = "STRING_DQUOTE_CHAR";
436            }
437        }
438    }
439
440    // We need to clean-up the tokens.  Consider the following input:
441    //
442    //   h"t"t"p"
443    //
444    // The way the algorithm works, we'll end up with our tokens being
445    // ordered:
446    //
447    //   "htt""p"
448    //
449    for (i = 0; i < tokens.length; i++) {
450
451        let token       = tokens[i],
452            lookahead_1 = tokens[i + 1],
453            lookahead_2 = tokens[i + 2];
454
455        if (token.name === "STRING_DQUOTE_END") {
456            if (lookahead_1 && lookahead_1.name === "STRING_DQUOTE_BEGIN") {
457                tokens.splice(i, 2);
458            }
459        }
460    }
461
462    return tokens;
463}
464
465/**
466 * Given an array of Tokens, attempts to remove all empty strings ("")
467 * from the list, returning a new list of tokens with empty string
468 * tokens removed.
469 *
470 * @param {Token|Array} tokens - An array of tokens.
471 * @returns {Token|Array}
472 */
473function FILTER_strip_empty_strings (tokens) {
474
475    let out_tokens = [],
476        skip_token = false;
477
478    for (let i = 0; i < tokens.length; i++) {
479
480        let token      = tokens[i],
481            lookahead  = tokens[i + 1];
482
483        if (skip_token) {
484            out_tokens.pop();
485            skip_token = false;
486            continue;
487        }
488
489        out_tokens.push(token);
490
491        switch (token.name) {
492        case "STRING_DQUOTE_BEGIN":
493            if (lookahead && lookahead.name === "STRING_DQUOTE_END") {
494                skip_token = true;
495            }
496            break;
497        }
498    }
499
500    return out_tokens;
501}
502
503/**
504 * Given an array of Tokens, attempts to remove all unnecessary commas
505 * from the tokenised sequence.
506 *
507 * @param {Token|Array} tokens - An array of tokens.
508 * @returns {Token|Array}
509 */
510function FILTER_strip_commas (tokens) {
511    return tokens.filter(token => token.name !== "COMMA");
512}
513
514/**
515 * Given an array of Tokens, attempts to fix-up all tokens which were
516 * previously escaped tokens.
517 *
518 * @param {Token|Array} tokens - An array of tokens.
519 * @returns {Token|Array}
520 */
521function FILTER_apply_escapes (tokens) {
522
523    let filtered = tokens
524        .filter(tok => tok.name !== "ESCAPE")
525        .map((tok, i, tokens) => {
526            if (tok.name === "ESCAPED_LITERAL") tokens[i].name = "LITERAL";
527            return tokens[i];
528        });
529
530    return filtered;
531}
532
533/**
534 * Given a command string, attempts to partially interpret the
535 * command, returning an object which can be used to present the
536 * command in an easy-to-understand way.
537 *
538 * @param {string} cmdstr - The command to run/parse.
539 * @returns {Object}
540 */
541function interpret_command (cmdstr) {
542
543    let clean_cmdstr = cmdstr.replace(/^\s+|\s+$/, "");
544
545    // Parse the command string in to an array of Token objects.
546    let tokens = tokenise(clean_cmdstr),
547        ident  = try_identify_command(tokens);
548
549    if (cmd_dispatch.hasOwnProperty(ident.command)) {
550        let handled = cmd_dispatch[ident.command](ident, tokens);
551        ident.tokens   = handled.tokens;
552        ident.switches = handled.switches;
553        ident.finished = handled.finished;
554    }
555
556    let flags  = {
557            in_set_cmd              : false,
558            capturing_env_var_name  : false,
559            capturing_env_var_value : false
560        };
561
562    let env_vars      = {},
563        env_var_name  = "",
564        env_var_value = "";
565
566    // The `outbuf` var holds a cleaned-up version of the command with
567    // all obfuscation removed.
568    let outbuf = [];
569
570    // When TRUE, the parser skips the next token.  Used in cases
571    // where we want to ignore "".
572    let skip = false;
573
574    for (let i = 0; i < tokens.length; i++) {
575
576        if (skip) {
577            outbuf.pop();
578            skip = false;
579            continue;
580        }
581
582        let token     = tokens[i],
583            lookahead = tokens[i + 1];
584
585        outbuf.push(token.text);
586
587        switch (token.name) {
588
589        case "LITERAL":
590
591            if (flags.in_set_cmd) {
592                if (flags.capturing_env_var_name) {
593                    env_var_name += token.text;
594                }
595                else if (flags.capturing_env_var_value) {
596                    env_var_value += token.text;
597                }
598            }
599            break;
600
601        case "ESCAPED":
602            break;
603
604        case "SET":
605            flags.capturing_env_var_name = true;
606            flags.in_set_cmd             = true;
607            break;
608
609        case "SET_ASSIGNMENT":
610            flags.capturing_env_var_name  = false;
611            flags.capturing_env_var_value = true;
612            break;
613
614        case "SET_DQUOTE_CHAR":
615
616            if (flags.capturing_env_var_name) {
617                env_var_name += token.text;
618            }
619            else if (flags.capturing_env_var_value) {
620                env_var_value += token.text;
621            }
622
623            break;
624
625        case "SET_DQUOTE_BEGIN":
626        case "SET_DQUOTE_END":
627            // TODO: may need to add another flag here...
628            break;
629
630        case "STRING_DQUOTE_BEGIN":
631            if (lookahead.name === "STRING_DQUOTE_END") {
632                skip = true;
633            }
634            break;
635
636        default:
637            //console.log("UNKNOWN TOK>", token.name, token.text);
638        }
639    }
640
641    if (env_var_name.length && env_var_value.length) {
642
643        if (/^%[^%]+[^%]%$/.test(env_var_name)) {
644            // Special handling for the case where someone sets:
645            //
646            //   SET %foo%=bar
647            //
648            // In this case, '%foo%' is treated as 'foo'.  This is
649            // different from something like:
650            //
651            //   SET %%foo%%=bar
652            //
653            // which Windows treats as '%%foo%%' which is !== '%foo%'.
654            //
655            env_var_name = env_var_name.replace(/^%|%$/g, "");
656        }
657
658        env_vars[env_var_name] = {
659            first: env_var_value,
660            curr: env_var_value
661        };
662    }
663
664    return {
665        ident: ident,
666        clean: outbuf.join(""),
667        vars: env_vars
668    };
669}
670
671/**
672 * Given a command string, attempts to split the string, returning an
673 * array of individual command strings.
674 *
675 * @param {string} command - a CMD.EXE command.
676 * @returns {Tokens|Array} Each command is an element in the array.
677 */
678function split_command (command_str) {
679
680    let tokens   = tokenise(command_str, { filter: false }),
681        index    = 0,
682        commands = [""];
683
684    tokens.forEach(tok => {
685
686        if (/^(?:CALL|COND_CALL|SEMICOLON)$/.test(tok.name)) {
687            index++;
688            commands[index] = "";
689        }
690        else {
691            commands[index] += tok.text;
692        }
693    });
694
695    return commands
696        .map(cmd => cmd.replace(/^\s*|\s*$/g, "")) // Remove leading and trailing whitespace
697        .filter(cmd => ! /^\s*$/.test(cmd));
698}
699
700/**
701 * Given a command string, attempts to split the string in to an array
702 * of Token objects.
703 *
704 * @param {string} cmdstr - The command string to split in to tokens.
705 * @param {string} [options] - Set .filter T|F to enable/disable filtering.
706 * @returns {Token|Array} Token objects, one-per-token.
707 */
708function tokenise (cmdstr, options) {
709
710    options = options || {};
711    options = Object.assign({}, { escapes_as_literals: false, filter: true }, options);
712
713    lexer.setInput(cmdstr);
714
715    let tokens = [];
716
717    while (true) {
718        let token = lexer.lex();
719        if (token === "EOF") break;
720
721        if (options.escapes_as_literals) {
722            if (token.name === "ESCAPE") {
723                token.name = "LITERAL";
724            }
725            else if (token.name === "ESCAPED_LITERAL") {
726                if (token.text === "=") {
727                    token.name = "SET_ASSIGNMENT";
728                }
729                else {
730                    token.name = "LITERAL";
731                }
732            }
733        }
734
735        tokens.push(token);
736    }
737
738    if (options.filter) {
739        tokens = FILTER_apply_escapes(tokens);
740        tokens = FILTER_strip_empty_strings(tokens);
741        tokens = FILTER_slurp_literals_into_strings(tokens);
742        tokens = FILTER_strip_excessive_whitespace(tokens);
743        //tokens = FILTER_strip_commas(tokens);
744    }
745
746    let cleancmd = stringify_tokens(tokens);
747
748    if (cmdstr !== cleancmd) {
749        return tokenise(cleancmd, { escapes_as_literals: true });
750    }
751
752    return tokens;
753}
754
755/**
756 * Attempts to perform a find/replace with variable expansion against
757 * a given DOS command with values read from an optional variable
758 * key/value object.  BATCH implements some syntactic-sugar to support
759 * finding and replacing characters within an environment variable:
760 *
761 * @example
762 * // Replace all 'a' chars with 'b' in var 'foo':
763 * "%foo:a=b%"
764 *
765 * @param {string} cmdstr - DOS command we wish to deobfuscate.
766 * @param {Object} [vars] - An object mapping var names to values.
767 *
768 * @returns {string} An expanded form of `cmdstr` with all variable
769 * find/replace operations performed.
770 */
771function substr_replace (cmdstr, vars) {
772
773    let find_replace_re = /%([^:]*):([^\s]+)=([^\s]+)?%/ig,
774        got_match;
775
776    while ((got_match = find_replace_re.exec(cmdstr))) {
777
778        let wholematch = got_match[0],
779            findstr    = got_match[2],
780            replstr    = got_match[3] || "",
781            varname    = got_match[1].toLowerCase(),
782            varvalue   = vars[varname];
783
784        if (vars.hasOwnProperty(varname) === false) {
785            continue;
786        }
787
788        let replaced_varvalue = varvalue.first.split(findstr).join(replstr);
789
790        cmdstr = cmdstr.split(wholematch).join(replaced_varvalue);
791    }
792
793    return cmdstr;
794}
795
796/**
797 * Given a command string an an object mapping varname => varvalue,
798 * attempts to apply the range of text manipulations supported by the
799 * BATCH language.  The following features are supported:
800 *
801 *   - expansion  :: %foo% expands to the valueOf(%foo%).
802 *   - substrings :: %foo:~5%, %foo:0,3%, %foo:~-3%
803 *   -
804 *
805 */
806function expand_environment_variables (cmdstr, vars, options) {
807
808    options = options || {};
809    const defaults = {
810        expand_percent_vars: true,
811        delayed_expansion: false
812    };
813    options = Object.assign({}, defaults, options);
814
815    const default_vars = {
816        appdata: {
817            first: `C:\\Users\\whoami\\AppData\\Roaming`,
818            curr:  `C:\\Users\\whoami\\AppData\\Roaming`
819        },
820        comspec: {
821            first: `C:\\Windows\\System32\\cmd.exe`,
822            curr:  `C:\\Windows\\System32\\cmd.exe`
823        }
824    };
825
826    if (vars) {
827        Object.keys(vars).forEach(varname => {
828            const varvalue = vars[varname];
829            if (typeof varvalue === "string") {
830                vars[varname] = {
831                    first: varvalue,
832                    curr:  varvalue
833                };
834            }
835        });
836    }
837    vars = Object.assign(default_vars, vars);
838
839    // Expand Variables
840    // ================
841    //
842    // Take all instances of '%foo%' and replace with the value found
843    // within the 'vars' dict.
844    //
845    let cmd = cmdstr;
846
847    if (options.expand_percent_vars) {
848        Object.keys(vars).forEach(varname => {
849            cmd = cmd.replace(
850                new RegExp(escapeRegexpString(`%${varname}%`), "gi"), vars[varname].first
851            );
852        });
853    }
854
855    // Delayed Expansion
856    // =================
857    //
858    // Instead of '%foo%', delayed expansion works with '!foo!', and
859    // reads from '.curr' instead of '.first'.
860    //
861    if (options.delayed_expansion) {
862        Object.keys(vars).forEach(varname => {
863            cmd = cmd.replace(
864                new RegExp(escapeRegexpString(`!${varname}!`), "gi"), // find
865                vars[varname].curr                                    // replace
866            );
867        });
868    }
869
870    // Apply Find/Replace
871    // ==================
872    //
873    // Searches the variable for all instances of STR, replacing with
874    // REP, for example:
875    //
876    //   %foo:STR=REP%
877    //   %foo:cat=dog%
878    //
879    cmd = substr_replace(cmd, vars);
880
881    // Substring handling
882    // ==================
883    //
884    // There are a few different ways we can apply substrings.  Assume
885    // %foo% = "abcdef".
886    //
887    //  - %foo:~3%      => def
888    //  - %foo:~0,3%    => abc
889    //  - %foo:~-3%     => def
890    //  - %foo:~1,3%    => bcd
891    //
892    let substr_re    = /%([^:]*):\s*~\s*([+-]?\d+)(?:,([+-]?\d+))?%/ig,
893        replacements = [],
894        substr_match;
895
896    while ((substr_match = substr_re.exec(cmd))) {
897
898        let var_name     = substr_match[1].toLowerCase(),
899            var_value    = vars[var_name],
900            substr_start = substr_match[2],
901            substr_end   = substr_match[3];
902
903        if (substr_start !== undefined) {
904            substr_start = parseInt(substr_start, 10);
905        }
906
907        if (substr_end !== undefined) {
908            substr_end = parseInt(substr_end, 10);
909        }
910
911        if (var_value === undefined) {
912            continue;
913        }
914        else {
915            var_value = var_value.first;
916        }
917
918        let replace = {
919            find: substr_match[0]
920        };
921
922        let rev = s => s.split("").reverse().join("");
923
924        if ((substr_start !== undefined) && (substr_end === undefined)) {
925
926            if (substr_start == 0) {
927                // Special case -- when the substr pattern is
928                // something like:
929                //
930                //   %FOO:~0%
931                //
932                // Windows expands this to the full variable value.
933                replace.replace = var_value;
934                replacements.push(replace);
935                continue;
936            }
937            else if (substr_start < 0) {
938                // Negative substr values start from the last char and
939                // substr forwards.
940                let rev_var_value = rev(var_value);
941                var_value = rev(rev_var_value.substr(0, (substr_start * -1)));
942
943                replace.replace = var_value;
944                replacements.push(replace);
945                continue;
946            }
947
948            replace.replace = var_value.substring(substr_start, substr_end);
949        }
950        else if ((substr_start !== undefined) && (substr_end !== undefined)) {
951
952            if (substr_start < 0 && substr_end < 0) {
953
954                substr_start = (substr_start * -1);
955                substr_end   = (substr_end   * -1);
956
957                let tmpstart = Math.min(substr_start, substr_end),
958                    tmpend   = Math.max(substr_start, substr_end);
959
960                replace.replace = rev(rev(var_value).split("").slice(tmpstart, tmpend).join(""));
961            }
962            else if (substr_start < 0 && substr_end > 0) {
963                /*
964                 * Handles cases such as: %foo:~-10,3%.
965                 */
966                let substr_offset = (substr_end + substr_start) * -1;
967                replace.replace = rev((rev(var_value).substr(substr_offset, substr_end)));
968            }
969            else if (substr_end < 0 && substr_start === 0) {
970                replace.replace = rev(rev(var_value).substr(substr_end * -1));
971            }
972            else if (substr_start === 0) {
973                replace.replace = var_value.substring(0, substr_end);
974            }
975            else if (substr_start > 0) {
976                replace.replace = var_value.substring(substr_start, substr_end + substr_start);
977            }
978        }
979
980        replacements.push(replace);
981    }
982
983    replacements.forEach(r => {
984        cmd = cmd.replace(new RegExp(escapeRegexpString(r.find), "gi"), r.replace);
985    });
986
987    return cmd;
988}
989
990module.exports = {
991
992    filter: {
993        widen_strings:       FILTER_slurp_literals_into_strings,
994        strip_escapes:       FILTER_apply_escapes,
995        strip_whitespace:    FILTER_strip_excessive_whitespace,
996        strip_empty_strings: FILTER_strip_empty_strings,
997        strip_commas:        FILTER_strip_commas,
998
999        // Command handlers
1000        handle_CMD: FILTER_handle_cmd,
1001    },
1002
1003    try_identify_command: try_identify_command,
1004
1005    tokenise:    tokenise,
1006    split_command: split_command,
1007    parse: parse_cmdstr,
1008    expand_variables: expand_environment_variables
1009};
1010
Full Screen

main.js

Source: main.js Github

copy
1const agl_processor=window['net.akehurst.language-agl-processor'];
2const Agl = agl_processor.net.akehurst.language.agl.processor.Agl;
3const AutomatonKind = agl_processor.net.akehurst.language.api.processor.AutomatonKind_api;
4
5function parse() {
6    try {
7        
8        const grammarStr = document.getElementById('grammar').value;
9        const sentenceStr = document.getElementById('sentence').value;
10
11        const p = Agl.processorFromString(grammarStr);
12        const tree = p.parse(sentenceStr, AutomatonKind.LOOKAHEAD_1);
13
14        document.getElementById('result').value = tree.toStringAllWithIndent("  ");
15        
16    } catch (ex) {
17        document.getElementById('result').value = 'ERROR: '+ex
18    }
19}
Full Screen

chevrotain.js

Source: chevrotain.js Github

copy
1/*! chevrotain - v1.0.1 */
2(function webpackUniversalModuleDefinition(root, factory) {
3	if(typeof exports === 'object' && typeof module === 'object')
4		module.exports = factory();
5	else if(typeof define === 'function' && define.amd)
6		define("chevrotain", [], factory);
7	else if(typeof exports === 'object')
8		exports["chevrotain"] = factory();
9	else
10		root["chevrotain"] = factory();
11})(typeof self !== 'undefined' ? self : this, function() {
12return /******/ (function(modules) { // webpackBootstrap
13/******/ 	// The module cache
14/******/ 	var installedModules = {};
15/******/
16/******/ 	// The require function
17/******/ 	function __webpack_require__(moduleId) {
18/******/
19/******/ 		// Check if module is in cache
20/******/ 		if(installedModules[moduleId]) {
21/******/ 			return installedModules[moduleId].exports;
22/******/ 		}
23/******/ 		// Create a new module (and put it into the cache)
24/******/ 		var module = installedModules[moduleId] = {
25/******/ 			i: moduleId,
26/******/ 			l: false,
27/******/ 			exports: {}
28/******/ 		};
29/******/
30/******/ 		// Execute the module function
31/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
32/******/
33/******/ 		// Flag the module as loaded
34/******/ 		module.l = true;
35/******/
36/******/ 		// Return the exports of the module
37/******/ 		return module.exports;
38/******/ 	}
39/******/
40/******/
41/******/ 	// expose the modules object (__webpack_modules__)
42/******/ 	__webpack_require__.m = modules;
43/******/
44/******/ 	// expose the module cache
45/******/ 	__webpack_require__.c = installedModules;
46/******/
47/******/ 	// define getter function for harmony exports
48/******/ 	__webpack_require__.d = function(exports, name, getter) {
49/******/ 		if(!__webpack_require__.o(exports, name)) {
50/******/ 			Object.defineProperty(exports, name, {
51/******/ 				configurable: false,
52/******/ 				enumerable: true,
53/******/ 				get: getter
54/******/ 			});
55/******/ 		}
56/******/ 	};
57/******/
58/******/ 	// getDefaultExport function for compatibility with non-harmony modules
59/******/ 	__webpack_require__.n = function(module) {
60/******/ 		var getter = module && module.__esModule ?
61/******/ 			function getDefault() { return module['default']; } :
62/******/ 			function getModuleExports() { return module; };
63/******/ 		__webpack_require__.d(getter, 'a', getter);
64/******/ 		return getter;
65/******/ 	};
66/******/
67/******/ 	// Object.prototype.hasOwnProperty.call
68/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
69/******/
70/******/ 	// __webpack_public_path__
71/******/ 	__webpack_require__.p = "";
72/******/
73/******/ 	// Load entry module and return exports
74/******/ 	return __webpack_require__(__webpack_require__.s = 20);
75/******/ })
76/************************************************************************/
77/******/ ([
78/* 0 */
79/***/ (function(module, exports, __webpack_require__) {
80
81"use strict";
82
83Object.defineProperty(exports, "__esModule", { value: true });
84/*
85 Utils using lodash style API. (not necessarily 100% compliant) for functional and other utils.
86 These utils should replace usage of lodash in the production code base. not because they are any better...
87 but for the purpose of being a dependency free library.
88
89 The hotspots in the code are already written in imperative style for performance reasons.
90 so writing several dozen utils which may be slower than the original lodash, does not matter as much
91 considering they will not be invoked in hotspots...
92 */
93function isEmpty(arr) {
94    return arr && arr.length === 0;
95}
96exports.isEmpty = isEmpty;
97function keys(obj) {
98    if (obj === undefined || obj === null) {
99        return [];
100    }
101    return Object.keys(obj);
102}
103exports.keys = keys;
104function values(obj) {
105    var vals = [];
106    var keys = Object.keys(obj);
107    for (var i = 0; i < keys.length; i++) {
108        vals.push(obj[keys[i]]);
109    }
110    return vals;
111}
112exports.values = values;
113function mapValues(obj, callback) {
114    var result = [];
115    var objKeys = keys(obj);
116    for (var idx = 0; idx < objKeys.length; idx++) {
117        var currKey = objKeys[idx];
118        result.push(callback.call(null, obj[currKey], currKey));
119    }
120    return result;
121}
122exports.mapValues = mapValues;
123function map(arr, callback) {
124    var result = [];
125    for (var idx = 0; idx < arr.length; idx++) {
126        result.push(callback.call(null, arr[idx], idx));
127    }
128    return result;
129}
130exports.map = map;
131function flatten(arr) {
132    var result = [];
133    for (var idx = 0; idx < arr.length; idx++) {
134        var currItem = arr[idx];
135        if (Array.isArray(currItem)) {
136            result = result.concat(flatten(currItem));
137        }
138        else {
139            result.push(currItem);
140        }
141    }
142    return result;
143}
144exports.flatten = flatten;
145function first(arr) {
146    return isEmpty(arr) ? undefined : arr[0];
147}
148exports.first = first;
149function last(arr) {
150    var len = arr && arr.length;
151    return len ? arr[len - 1] : undefined;
152}
153exports.last = last;
154function forEach(collection, iteratorCallback) {
155    if (Array.isArray(collection)) {
156        for (var i = 0; i < collection.length; i++) {
157            iteratorCallback.call(null, collection[i], i);
158        }
159    }
160    else if (isObject(collection)) {
161        var colKeys = keys(collection);
162        for (var i = 0; i < colKeys.length; i++) {
163            var key = colKeys[i];
164            var value = collection[key];
165            iteratorCallback.call(null, value, key);
166        }
167    }
168    else {
169        /* istanbul ignore next */
170        throw Error("non exhaustive match");
171    }
172}
173exports.forEach = forEach;
174function isString(item) {
175    return typeof item === "string";
176}
177exports.isString = isString;
178function isUndefined(item) {
179    return item === undefined;
180}
181exports.isUndefined = isUndefined;
182function isFunction(item) {
183    return item instanceof Function;
184}
185exports.isFunction = isFunction;
186function drop(arr, howMuch) {
187    if (howMuch === void 0) { howMuch = 1; }
188    return arr.slice(howMuch, arr.length);
189}
190exports.drop = drop;
191function dropRight(arr, howMuch) {
192    if (howMuch === void 0) { howMuch = 1; }
193    return arr.slice(0, arr.length - howMuch);
194}
195exports.dropRight = dropRight;
196function filter(arr, predicate) {
197    var result = [];
198    if (Array.isArray(arr)) {
199        for (var i = 0; i < arr.length; i++) {
200            var item = arr[i];
201            if (predicate.call(null, item)) {
202                result.push(item);
203            }
204        }
205    }
206    return result;
207}
208exports.filter = filter;
209function reject(arr, predicate) {
210    return filter(arr, function (item) { return !predicate(item); });
211}
212exports.reject = reject;
213function pick(obj, predicate) {
214    var keys = Object.keys(obj);
215    var result = {};
216    for (var i = 0; i < keys.length; i++) {
217        var currKey = keys[i];
218        var currItem = obj[currKey];
219        if (predicate(currItem)) {
220            result[currKey] = currItem;
221        }
222    }
223    return result;
224}
225exports.pick = pick;
226function has(obj, prop) {
227    if (isObject(obj)) {
228        return obj.hasOwnProperty(prop);
229    }
230    return false;
231}
232exports.has = has;
233function contains(arr, item) {
234    return find(arr, function (currItem) { return currItem === item; }) !== undefined ? true : false;
235}
236exports.contains = contains;
237/**
238 * shallow clone
239 */
240function cloneArr(arr) {
241    var newArr = [];
242    for (var i = 0; i < arr.length; i++) {
243        newArr.push(arr[i]);
244    }
245    return newArr;
246}
247exports.cloneArr = cloneArr;
248/**
249 * shallow clone
250 */
251function cloneObj(obj) {
252    var clonedObj = {};
253    for (var key in obj) {
254        /* istanbul ignore else */
255        if (Object.prototype.hasOwnProperty.call(obj, key)) {
256            clonedObj[key] = obj[key];
257        }
258    }
259    return clonedObj;
260}
261exports.cloneObj = cloneObj;
262function find(arr, predicate) {
263    for (var i = 0; i < arr.length; i++) {
264        var item = arr[i];
265        if (predicate.call(null, item)) {
266            return item;
267        }
268    }
269    return undefined;
270}
271exports.find = find;
272function findAll(arr, predicate) {
273    var found = [];
274    for (var i = 0; i < arr.length; i++) {
275        var item = arr[i];
276        if (predicate.call(null, item)) {
277            found.push(item);
278        }
279    }
280    return found;
281}
282exports.findAll = findAll;
283function reduce(arrOrObj, iterator, initial) {
284    var vals = Array.isArray(arrOrObj)
285        ? arrOrObj
286        : values(arrOrObj);
287    var accumulator = initial;
288    for (var i = 0; i < vals.length; i++) {
289        accumulator = iterator.call(null, accumulator, vals[i], i);
290    }
291    return accumulator;
292}
293exports.reduce = reduce;
294function compact(arr) {
295    return reject(arr, function (item) { return item === null || item === undefined; });
296}
297exports.compact = compact;
298function uniq(arr, identity) {
299    if (identity === void 0) { identity = function (item) { return item; }; }
300    var identities = [];
301    return reduce(arr, function (result, currItem) {
302        var currIdentity = identity(currItem);
303        if (contains(identities, currIdentity)) {
304            return result;
305        }
306        else {
307            identities.push(currIdentity);
308            return result.concat(currItem);
309        }
310    }, []);
311}
312exports.uniq = uniq;
313function partial(func) {
314    var restArgs = [];
315    for (var _i = 1; _i < arguments.length; _i++) {
316        restArgs[_i - 1] = arguments[_i];
317    }
318    var firstArg = [null];
319    var allArgs = firstArg.concat(restArgs);
320    return Function.bind.apply(func, allArgs);
321}
322exports.partial = partial;
323function isArray(obj) {
324    return Array.isArray(obj);
325}
326exports.isArray = isArray;
327function isRegExp(obj) {
328    return obj instanceof RegExp;
329}
330exports.isRegExp = isRegExp;
331function isObject(obj) {
332    return obj instanceof Object;
333}
334exports.isObject = isObject;
335function every(arr, predicate) {
336    for (var i = 0; i < arr.length; i++) {
337        if (!predicate(arr[i], i)) {
338            return false;
339        }
340    }
341    return true;
342}
343exports.every = every;
344function difference(arr, values) {
345    return reject(arr, function (item) { return contains(values, item); });
346}
347exports.difference = difference;
348function some(arr, predicate) {
349    for (var i = 0; i < arr.length; i++) {
350        if (predicate(arr[i])) {
351            return true;
352        }
353    }
354    return false;
355}
356exports.some = some;
357function indexOf(arr, value) {
358    for (var i = 0; i < arr.length; i++) {
359        if (arr[i] === value) {
360            return i;
361        }
362    }
363    return -1;
364}
365exports.indexOf = indexOf;
366function sortBy(arr, orderFunc) {
367    var result = cloneArr(arr);
368    result.sort(function (a, b) { return orderFunc(a) - orderFunc(b); });
369    return result;
370}
371exports.sortBy = sortBy;
372function zipObject(keys, values) {
373    if (keys.length !== values.length) {
374        throw Error("can't zipObject with different number of keys and values!");
375    }
376    var result = {};
377    for (var i = 0; i < keys.length; i++) {
378        result[keys[i]] = values[i];
379    }
380    return result;
381}
382exports.zipObject = zipObject;
383/**
384 * mutates! (and returns) target
385 */
386function assign(target) {
387    var sources = [];
388    for (var _i = 1; _i < arguments.length; _i++) {
389        sources[_i - 1] = arguments[_i];
390    }
391    for (var i = 0; i < sources.length; i++) {
392        var curSource = sources[i];
393        var currSourceKeys = keys(curSource);
394        for (var j = 0; j < currSourceKeys.length; j++) {
395            var currKey = currSourceKeys[j];
396            target[currKey] = curSource[currKey];
397        }
398    }
399    return target;
400}
401exports.assign = assign;
402/**
403 * mutates! (and returns) target
404 */
405function assignNoOverwrite(target) {
406    var sources = [];
407    for (var _i = 1; _i < arguments.length; _i++) {
408        sources[_i - 1] = arguments[_i];
409    }
410    for (var i = 0; i < sources.length; i++) {
411        var curSource = sources[i];
412        if (isUndefined(curSource)) {
413            continue;
414        }
415        var currSourceKeys = keys(curSource);
416        for (var j = 0; j < currSourceKeys.length; j++) {
417            var currKey = currSourceKeys[j];
418            if (!has(target, currKey)) {
419                target[currKey] = curSource[currKey];
420            }
421        }
422    }
423    return target;
424}
425exports.assignNoOverwrite = assignNoOverwrite;
426function defaults() {
427    var sources = [];
428    for (var _i = 0; _i < arguments.length; _i++) {
429        sources[_i] = arguments[_i];
430    }
431    return assignNoOverwrite.apply(null, [{}].concat(sources));
432}
433exports.defaults = defaults;
434function groupBy(arr, groupKeyFunc) {
435    var result = {};
436    forEach(arr, function (item) {
437        var currGroupKey = groupKeyFunc(item);
438        var currGroupArr = result[currGroupKey];
439        if (currGroupArr) {
440            currGroupArr.push(item);
441        }
442        else {
443            result[currGroupKey] = [item];
444        }
445    });
446    return result;
447}
448exports.groupBy = groupBy;
449/**
450 * Merge obj2 into obj1.
451 * Will overwrite existing properties with the same name
452 */
453function merge(obj1, obj2) {
454    var result = cloneObj(obj1);
455    var keys2 = keys(obj2);
456    for (var i = 0; i < keys2.length; i++) {
457        var key = keys2[i];
458        var value = obj2[key];
459        result[key] = value;
460    }
461    return result;
462}
463exports.merge = merge;
464function NOOP() { }
465exports.NOOP = NOOP;
466function IDENTITY(item) {
467    return item;
468}
469exports.IDENTITY = IDENTITY;
470//# sourceMappingURL=utils.js.map
471
472/***/ }),
473/* 1 */
474/***/ (function(module, exports, __webpack_require__) {
475
476"use strict";
477
478var __extends = (this && this.__extends) || (function () {
479    var extendStatics = Object.setPrototypeOf ||
480        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
481        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
482    return function (d, b) {
483        extendStatics(d, b);
484        function __() { this.constructor = d; }
485        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
486    };
487})();
488Object.defineProperty(exports, "__esModule", { value: true });
489var utils_1 = __webpack_require__(0);
490var tokens_public_1 = __webpack_require__(2);
491var gast;
492(function (gast) {
493    var AbstractProduction = /** @class */ (function () {
494        function AbstractProduction(definition) {
495            this.definition = definition;
496        }
497        AbstractProduction.prototype.accept = function (visitor) {
498            visitor.visit(this);
499            utils_1.forEach(this.definition, function (prod) {
500                prod.accept(visitor);
501            });
502        };
503        return AbstractProduction;
504    }());
505    gast.AbstractProduction = AbstractProduction;
506    var NonTerminal = /** @class */ (function (_super) {
507        __extends(NonTerminal, _super);
508        function NonTerminal(nonTerminalName, referencedRule, occurrenceInParent, implicitOccurrenceIndex) {
509            if (referencedRule === void 0) { referencedRule = undefined; }
510            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
511            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
512            var _this = _super.call(this, []) || this;
513            _this.nonTerminalName = nonTerminalName;
514            _this.referencedRule = referencedRule;
515            _this.occurrenceInParent = occurrenceInParent;
516            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
517            return _this;
518        }
519        Object.defineProperty(NonTerminal.prototype, "definition", {
520            get: function () {
521                if (this.referencedRule !== undefined) {
522                    return this.referencedRule.definition;
523                }
524                return [];
525            },
526            set: function (definition) {
527                // immutable
528            },
529            enumerable: true,
530            configurable: true
531        });
532        NonTerminal.prototype.accept = function (visitor) {
533            visitor.visit(this);
534            // don't visit children of a reference, we will get cyclic infinite loops if we do so
535        };
536        return NonTerminal;
537    }(AbstractProduction));
538    gast.NonTerminal = NonTerminal;
539    var Rule = /** @class */ (function (_super) {
540        __extends(Rule, _super);
541        function Rule(name, definition, orgText) {
542            if (orgText === void 0) { orgText = ""; }
543            var _this = _super.call(this, definition) || this;
544            _this.name = name;
545            _this.orgText = orgText;
546            return _this;
547        }
548        return Rule;
549    }(AbstractProduction));
550    gast.Rule = Rule;
551    var Flat = /** @class */ (function (_super) {
552        __extends(Flat, _super);
553        // A named Flat production is used to indicate a Nested Rule in an alternation
554        function Flat(definition, name) {
555            var _this = _super.call(this, definition) || this;
556            _this.name = name;
557            return _this;
558        }
559        return Flat;
560    }(AbstractProduction));
561    gast.Flat = Flat;
562    var Option = /** @class */ (function (_super) {
563        __extends(Option, _super);
564        function Option(definition, occurrenceInParent, name, implicitOccurrenceIndex) {
565            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
566            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
567            var _this = _super.call(this, definition) || this;
568            _this.occurrenceInParent = occurrenceInParent;
569            _this.name = name;
570            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
571            return _this;
572        }
573        return Option;
574    }(AbstractProduction));
575    gast.Option = Option;
576    var RepetitionMandatory = /** @class */ (function (_super) {
577        __extends(RepetitionMandatory, _super);
578        function RepetitionMandatory(definition, occurrenceInParent, name, implicitOccurrenceIndex) {
579            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
580            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
581            var _this = _super.call(this, definition) || this;
582            _this.occurrenceInParent = occurrenceInParent;
583            _this.name = name;
584            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
585            return _this;
586        }
587        return RepetitionMandatory;
588    }(AbstractProduction));
589    gast.RepetitionMandatory = RepetitionMandatory;
590    var RepetitionMandatoryWithSeparator = /** @class */ (function (_super) {
591        __extends(RepetitionMandatoryWithSeparator, _super);
592        function RepetitionMandatoryWithSeparator(definition, separator, occurrenceInParent, name, implicitOccurrenceIndex) {
593            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
594            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
595            var _this = _super.call(this, definition) || this;
596            _this.separator = separator;
597            _this.occurrenceInParent = occurrenceInParent;
598            _this.name = name;
599            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
600            return _this;
601        }
602        return RepetitionMandatoryWithSeparator;
603    }(AbstractProduction));
604    gast.RepetitionMandatoryWithSeparator = RepetitionMandatoryWithSeparator;
605    var Repetition = /** @class */ (function (_super) {
606        __extends(Repetition, _super);
607        function Repetition(definition, occurrenceInParent, name, implicitOccurrenceIndex) {
608            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
609            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
610            var _this = _super.call(this, definition) || this;
611            _this.occurrenceInParent = occurrenceInParent;
612            _this.name = name;
613            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
614            return _this;
615        }
616        return Repetition;
617    }(AbstractProduction));
618    gast.Repetition = Repetition;
619    var RepetitionWithSeparator = /** @class */ (function (_super) {
620        __extends(RepetitionWithSeparator, _super);
621        function RepetitionWithSeparator(definition, separator, occurrenceInParent, name, implicitOccurrenceIndex) {
622            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
623            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
624            var _this = _super.call(this, definition) || this;
625            _this.separator = separator;
626            _this.occurrenceInParent = occurrenceInParent;
627            _this.name = name;
628            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
629            return _this;
630        }
631        return RepetitionWithSeparator;
632    }(AbstractProduction));
633    gast.RepetitionWithSeparator = RepetitionWithSeparator;
634    var Alternation = /** @class */ (function (_super) {
635        __extends(Alternation, _super);
636        function Alternation(definition, occurrenceInParent, name, implicitOccurrenceIndex) {
637            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
638            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
639            var _this = _super.call(this, definition) || this;
640            _this.occurrenceInParent = occurrenceInParent;
641            _this.name = name;
642            _this.implicitOccurrenceIndex = implicitOccurrenceIndex;
643            return _this;
644        }
645        return Alternation;
646    }(AbstractProduction));
647    gast.Alternation = Alternation;
648    var Terminal = /** @class */ (function () {
649        function Terminal(terminalType, occurrenceInParent, implicitOccurrenceIndex) {
650            if (occurrenceInParent === void 0) { occurrenceInParent = 1; }
651            if (implicitOccurrenceIndex === void 0) { implicitOccurrenceIndex = false; }
652            this.terminalType = terminalType;
653            this.occurrenceInParent = occurrenceInParent;
654            this.implicitOccurrenceIndex = implicitOccurrenceIndex;
655        }
656        Terminal.prototype.accept = function (visitor) {
657            visitor.visit(this);
658        };
659        return Terminal;
660    }());
661    gast.Terminal = Terminal;
662    var GAstVisitor = /** @class */ (function () {
663        function GAstVisitor() {
664        }
665        GAstVisitor.prototype.visit = function (node) {
666            if (node instanceof NonTerminal) {
667                return this.visitNonTerminal(node);
668            }
669            else if (node instanceof Flat) {
670                return this.visitFlat(node);
671            }
672            else if (node instanceof Option) {
673                return this.visitOption(node);
674            }
675            else if (node instanceof RepetitionMandatory) {
676                return this.visitRepetitionMandatory(node);
677            }
678            else if (node instanceof RepetitionMandatoryWithSeparator) {
679                return this.visitRepetitionMandatoryWithSeparator(node);
680            }
681            else if (node instanceof RepetitionWithSeparator) {
682                return this.visitRepetitionWithSeparator(node);
683            }
684            else if (node instanceof Repetition) {
685                return this.visitRepetition(node);
686            }
687            else if (node instanceof Alternation) {
688                return this.visitAlternation(node);
689            }
690            else if (node instanceof Terminal) {
691                return this.visitTerminal(node);
692            }
693            else if (node instanceof Rule) {
694                return this.visitRule(node);
695            }
696            else {
697                /* istanbul ignore next */
698                throw Error("non exhaustive match");
699            }
700        };
701        GAstVisitor.prototype.visitNonTerminal = function (node) { };
702        GAstVisitor.prototype.visitFlat = function (node) { };
703        GAstVisitor.prototype.visitOption = function (node) { };
704        GAstVisitor.prototype.visitRepetition = function (node) { };
705        GAstVisitor.prototype.visitRepetitionMandatory = function (node) { };
706        GAstVisitor.prototype.visitRepetitionMandatoryWithSeparator = function (node) { };
707        GAstVisitor.prototype.visitRepetitionWithSeparator = function (node) { };
708        GAstVisitor.prototype.visitAlternation = function (node) { };
709        GAstVisitor.prototype.visitTerminal = function (node) { };
710        GAstVisitor.prototype.visitRule = function (node) { };
711        return GAstVisitor;
712    }());
713    gast.GAstVisitor = GAstVisitor;
714    function serializeGrammar(topRules) {
715        return utils_1.map(topRules, serializeProduction);
716    }
717    gast.serializeGrammar = serializeGrammar;
718    function serializeProduction(node) {
719        function convertDefinition(definition) {
720            return utils_1.map(definition, serializeProduction);
721        }
722        if (node instanceof NonTerminal) {
723            return {
724                type: "NonTerminal",
725                name: node.nonTerminalName,
726                occurrenceInParent: node.occurrenceInParent
727            };
728        }
729        else if (node instanceof Flat) {
730            return {
731                type: "Flat",
732                definition: convertDefinition(node.definition)
733            };
734        }
735        else if (node instanceof Option) {
736            return {
737                type: "Option",
738                definition: convertDefinition(node.definition)
739            };
740        }
741        else if (node instanceof RepetitionMandatory) {
742            return {
743                type: "RepetitionMandatory",
744                definition: convertDefinition(node.definition)
745            };
746        }
747        else if (node instanceof RepetitionMandatoryWithSeparator) {
748            return {
749                type: "RepetitionMandatoryWithSeparator",
750                separator: serializeProduction(new Terminal(node.separator)),
751                definition: convertDefinition(node.definition)
752            };
753        }
754        else if (node instanceof RepetitionWithSeparator) {
755            return {
756                type: "RepetitionWithSeparator",
757                separator: serializeProduction(new Terminal(node.separator)),
758                definition: convertDefinition(node.definition)
759            };
760        }
761        else if (node instanceof Repetition) {
762            return {
763                type: "Repetition",
764                definition: convertDefinition(node.definition)
765            };
766        }
767        else if (node instanceof Alternation) {
768            return {
769                type: "Alternation",
770                definition: convertDefinition(node.definition)
771            };
772        }
773        else if (node instanceof Terminal) {
774            var serializedTerminal = {
775                type: "Terminal",
776                name: tokens_public_1.tokenName(node.terminalType),
777                label: tokens_public_1.tokenLabel(node.terminalType),
778                occurrenceInParent: node.occurrenceInParent
779            };
780            var pattern = node.terminalType.PATTERN;
781            if (node.terminalType.PATTERN) {
782                serializedTerminal.pattern = utils_1.isRegExp(pattern)
783                    ? pattern.source
784                    : pattern;
785            }
786            return serializedTerminal;
787        }
788        else if (node instanceof Rule) {
789            // IGNORE ABOVE ELSE
790            return {
791                type: "Rule",
792                name: node.name,
793                definition: convertDefinition(node.definition)
794            };
795        }
796        else {
797            /* istanbul ignore next */
798            throw Error("non exhaustive match");
799        }
800    }
801    gast.serializeProduction = serializeProduction;
802})(gast = exports.gast || (exports.gast = {}));
803//# sourceMappingURL=gast_public.js.map
804
805/***/ }),
806/* 2 */
807/***/ (function(module, exports, __webpack_require__) {
808
809"use strict";
810
811Object.defineProperty(exports, "__esModule", { value: true });
812var utils_1 = __webpack_require__(0);
813var lang_extensions_1 = __webpack_require__(3);
814var lexer_public_1 = __webpack_require__(8);
815var tokens_1 = __webpack_require__(4);
816/**
817 *  This can be used to improve the quality/readability of error messages or syntax diagrams.
818 *
819 * @param {TokenType} clazz - A constructor for a Token subclass
820 * @returns {string} - The Human readable label for a Token if it exists.
821 */
822function tokenLabel(clazz) {
823    if (hasTokenLabel(clazz)) {
824        return clazz.LABEL;
825    }
826    else {
827        return tokenName(clazz);
828    }
829}
830exports.tokenLabel = tokenLabel;
831function hasTokenLabel(obj) {
832    return utils_1.isString(obj.LABEL) && obj.LABEL !== "";
833}
834exports.hasTokenLabel = hasTokenLabel;
835function tokenName(obj) {
836    // The tokenName property is needed under some old versions of node.js (0.10/0.12)
837    // where the Function.prototype.name property is not defined as a 'configurable' property
838    // enable producing readable error messages.
839    /* istanbul ignore if -> will only run in old versions of node.js */
840    if (utils_1.isObject(obj) &&
841        obj.hasOwnProperty("tokenName") &&
842        utils_1.isString(obj.tokenName)) {
843        return obj.tokenName;
844    }
845    else {
846        return lang_extensions_1.functionName(obj);
847    }
848}
849exports.tokenName = tokenName;
850var PARENT = "parent";
851var CATEGORIES = "categories";
852var LABEL = "label";
853var GROUP = "group";
854var PUSH_MODE = "push_mode";
855var POP_MODE = "pop_mode";
856var LONGER_ALT = "longer_alt";
857var LINE_BREAKS = "line_breaks";
858/**
859 * @param {ITokenConfig} config - The configuration for
860 * @returns {TokenType} - A constructor for the new Token subclass
861 */
862function createToken(config) {
863    return createTokenInternal(config);
864}
865exports.createToken = createToken;
866function createTokenInternal(config) {
867    var tokenName = config.name;
868    var pattern = config.pattern;
869    var tokenType = {};
870    // can be overwritten according to:
871    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/
872    // name?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fname
873    /* istanbul ignore if -> will only run in old versions of node.js */
874    if (!lang_extensions_1.defineNameProp(tokenType, tokenName)) {
875        // hack to save the tokenName in situations where the constructor's name property cannot be reconfigured
876        tokenType.tokenName = tokenName;
877    }
878    if (!utils_1.isUndefined(pattern)) {
879        tokenType.PATTERN = pattern;
880    }
881    if (utils_1.has(config, PARENT)) {
882        throw "The parent property is no longer supported.\n" +
883            "See: [TODO-add link] for details.";
884    }
885    if (utils_1.has(config, CATEGORIES)) {
886        tokenType.CATEGORIES = config[CATEGORIES];
887    }
888    tokens_1.augmentTokenTypes([tokenType]);
889    if (utils_1.has(config, LABEL)) {
890        tokenType.LABEL = config[LABEL];
891    }
892    if (utils_1.has(config, GROUP)) {
893        tokenType.GROUP = config[GROUP];
894    }
895    if (utils_1.has(config, POP_MODE)) {
896        tokenType.POP_MODE = config[POP_MODE];
897    }
898    if (utils_1.has(config, PUSH_MODE)) {
899        tokenType.PUSH_MODE = config[PUSH_MODE];
900    }
901    if (utils_1.has(config, LONGER_ALT)) {
902        tokenType.LONGER_ALT = config[LONGER_ALT];
903    }
904    if (utils_1.has(config, LINE_BREAKS)) {
905        tokenType.LINE_BREAKS = config[LINE_BREAKS];
906    }
907    return tokenType;
908}
909exports.EOF = createToken({ name: "EOF", pattern: lexer_public_1.Lexer.NA });
910tokens_1.augmentTokenTypes([exports.EOF]);
911/**
912 * Utility to create Chevrotain Token "instances"
913 * Note that Chevrotain tokens are not real instances, and thus the instanceOf cannot be used.
914 *
915 * @param tokType
916 * @param image
917 * @param startOffset
918 * @param endOffset
919 * @param startLine
920 * @param endLine
921 * @param startColumn
922 * @param endColumn
923 * @returns {{image: string,
924 *            startOffset: number,
925 *            endOffset: number,
926 *            startLine: number,
927 *            endLine: number,
928 *            startColumn: number,
929 *            endColumn: number,
930 *            tokenType}}
931 */
932function createTokenInstance(tokType, image, startOffset, endOffset, startLine, endLine, startColumn, endColumn) {
933    return {
934        image: image,
935        startOffset: startOffset,
936        endOffset: endOffset,
937        startLine: startLine,
938        endLine: endLine,
939        startColumn: startColumn,
940        endColumn: endColumn,
941        tokenTypeIdx: tokType.tokenTypeIdx,
942        tokenType: tokType
943    };
944}
945exports.createTokenInstance = createTokenInstance;
946/**
947 * A Utility method to check if a token is of the type of the argument Token class.
948 * This utility is needed because Chevrotain tokens support "categories" which means
949 * A TokenType may have multiple categories, so a TokenType for the "true" literal in JavaScript
950 * May be both a Keyword Token and a Literal Token.
951 *
952 * @param token {IToken}
953 * @param tokType {TokenType}
954 * @returns {boolean}
955 */
956function tokenMatcher(token, tokType) {
957    return tokens_1.tokenStructuredMatcher(token, tokType);
958}
959exports.tokenMatcher = tokenMatcher;
960//# sourceMappingURL=tokens_public.js.map
961
962/***/ }),
963/* 3 */
964/***/ (function(module, exports, __webpack_require__) {
965
966"use strict";
967
968Object.defineProperty(exports, "__esModule", { value: true });
969var utils = __webpack_require__(0);
970var utils_1 = __webpack_require__(0);
971function classNameFromInstance(instance) {
972    return functionName(instance.constructor);
973}
974exports.classNameFromInstance = classNameFromInstance;
975var FUNC_NAME_REGEXP = /^\s*function\s*(\S*)\s*\(/;
976var NAME = "name";
977/* istanbul ignore next too many hacks for IE/old versions of node.js here*/
978function functionName(func) {
979    // Engines that support Function.prototype.name OR the nth (n>1) time after
980    // the name has been computed in the following else block.
981    var existingNameProp = func.name;
982    if (existingNameProp) {
983        return existingNameProp;
984    }
985    // hack for IE and engines that do not support Object.defineProperty on function.name (Node.js 0.10 && 0.12)
986    var computedName = func.toString().match(FUNC_NAME_REGEXP)[1];
987    return computedName;
988}
989exports.functionName = functionName;
990/**
991 * @returns {boolean} - has the property been successfully defined
992 */
993function defineNameProp(obj, nameValue) {
994    var namePropDescriptor = Object.getOwnPropertyDescriptor(obj, NAME);
995    /* istanbul ignore else -> will only run in old versions of node.js */
996    if (utils_1.isUndefined(namePropDescriptor) || namePropDescriptor.configurable) {
997        Object.defineProperty(obj, NAME, {
998            enumerable: false,
999            configurable: true,
1000            writable: false,
1001            value: nameValue
1002        });
1003        return true;
1004    }
1005    /* istanbul ignore next -> will only run in old versions of node.js */
1006    return false;
1007}
1008exports.defineNameProp = defineNameProp;
1009/**
1010 * simple Hashtable between a string and some generic value
1011 * this should be removed once typescript supports ES6 style Hashtable
1012 */
1013var HashTable = /** @class */ (function () {
1014    function HashTable() {
1015        this._state = {};
1016    }
1017    HashTable.prototype.keys = function () {
1018        return utils.keys(this._state);
1019    };
1020    HashTable.prototype.values = function () {
1021        return utils.values(this._state);
1022    };
1023    HashTable.prototype.put = function (key, value) {
1024        this._state[key] = value;
1025    };
1026    HashTable.prototype.putAll = function (other) {
1027        this._state = utils.assign(this._state, other._state);
1028    };
1029    HashTable.prototype.get = function (key) {
1030        // To avoid edge case with a key called "hasOwnProperty" we need to perform the commented out check below
1031        // -> if (Object.prototype.hasOwnProperty.call(this._state, key)) { ... } <-
1032        // however this costs nearly 25% of the parser's runtime.
1033        // if someone decides to name their Parser class "hasOwnProperty" they deserve what they will get :)
1034        return this._state[key];
1035    };
1036    HashTable.prototype.containsKey = function (key) {
1037        return utils.has(this._state, key);
1038    };
1039    HashTable.prototype.clear = function () {
1040        this._state = {};
1041    };
1042    return HashTable;
1043}());
1044exports.HashTable = HashTable;
1045//# sourceMappingURL=lang_extensions.js.map
1046
1047/***/ }),
1048/* 4 */
1049/***/ (function(module, exports, __webpack_require__) {
1050
1051"use strict";
1052
1053Object.defineProperty(exports, "__esModule", { value: true });
1054var utils_1 = __webpack_require__(0);
1055var lang_extensions_1 = __webpack_require__(3);
1056var tokens_public_1 = __webpack_require__(2);
1057function tokenStructuredMatcher(tokInstance, tokConstructor) {
1058    var instanceType = tokInstance.tokenTypeIdx;
1059    if (instanceType === tokConstructor.tokenTypeIdx) {
1060        return true;
1061    }
1062    else {
1063        return (tokConstructor.isParent === true &&
1064            tokConstructor.categoryMatchesMap[instanceType] === true);
1065    }
1066}
1067exports.tokenStructuredMatcher = tokenStructuredMatcher;
1068// Optimized tokenMatcher in case our grammar does not use token categories
1069// Being so tiny it is much more likely to be in-lined and this avoid the function call overhead
1070function tokenStructuredMatcherNoCategories(token, tokType) {
1071    return token.tokenTypeIdx === tokType.tokenTypeIdx;
1072}
1073exports.tokenStructuredMatcherNoCategories = tokenStructuredMatcherNoCategories;
1074exports.tokenShortNameIdx = 1;
1075exports.tokenIdxToClass = new lang_extensions_1.HashTable();
1076function augmentTokenTypes(tokenTypes) {
1077    // collect the parent Token Types as well.
1078    var tokenTypesAndParents = expandCategories(tokenTypes);
1079    // add required tokenType and categoryMatches properties
1080    assignTokenDefaultProps(tokenTypesAndParents);
1081    // fill up the categoryMatches
1082    assignCategoriesMapProp(tokenTypesAndParents);
1083    assignCategoriesTokensProp(tokenTypesAndParents);
1084    utils_1.forEach(tokenTypesAndParents, function (tokType) {
1085        tokType.isParent = tokType.categoryMatches.length > 0;
1086    });
1087}
1088exports.augmentTokenTypes = augmentTokenTypes;
1089function expandCategories(tokenTypes) {
1090    var result = utils_1.cloneArr(tokenTypes);
1091    var categories = tokenTypes;
1092    var searching = true;
1093    while (searching) {
1094        categories = utils_1.compact(utils_1.flatten(utils_1.map(categories, function (currTokType) { return currTokType.CATEGORIES; })));
1095        var newCategories = utils_1.difference(categories, result);
1096        result = result.concat(newCategories);
1097        if (utils_1.isEmpty(newCategories)) {
1098            searching = false;
1099        }
1100        else {
1101            categories = newCategories;
1102        }
1103    }
1104    return result;
1105}
1106exports.expandCategories = expandCategories;
1107function assignTokenDefaultProps(tokenTypes) {
1108    utils_1.forEach(tokenTypes, function (currTokType) {
1109        if (!hasShortKeyProperty(currTokType)) {
1110            exports.tokenIdxToClass.put(exports.tokenShortNameIdx, currTokType);
1111            currTokType.tokenTypeIdx = exports.tokenShortNameIdx++;
1112        }
1113        // CATEGORIES? : TokenType | TokenType[]
1114        if (hasCategoriesProperty(currTokType) &&
1115            !utils_1.isArray(currTokType.CATEGORIES)) {
1116            currTokType.CATEGORIES = [currTokType.CATEGORIES];
1117        }
1118        if (!hasCategoriesProperty(currTokType)) {
1119            currTokType.CATEGORIES = [];
1120        }
1121        if (!hasExtendingTokensTypesProperty(currTokType)) {
1122            currTokType.categoryMatches = [];
1123        }
1124        if (!hasExtendingTokensTypesMapProperty(currTokType)) {
1125            currTokType.categoryMatchesMap = {};
1126        }
1127        if (!hasTokenNameProperty(currTokType)) {
1128            // saved for fast access during CST building.
1129            currTokType.tokenName = tokens_public_1.tokenName(currTokType);
1130        }
1131    });
1132}
1133exports.assignTokenDefaultProps = assignTokenDefaultProps;
1134function assignCategoriesTokensProp(tokenTypes) {
1135    utils_1.forEach(tokenTypes, function (currTokType) {
1136        // avoid duplications
1137        currTokType.categoryMatches = [];
1138        utils_1.forEach(currTokType.categoryMatchesMap, function (val, key) {
1139            currTokType.categoryMatches.push(exports.tokenIdxToClass.get(key).tokenTypeIdx);
1140        });
1141    });
1142}
1143exports.assignCategoriesTokensProp = assignCategoriesTokensProp;
1144function assignCategoriesMapProp(tokenTypes) {
1145    utils_1.forEach(tokenTypes, function (currTokType) {
1146        singleAssignCategoriesToksMap([], currTokType);
1147    });
1148}
1149exports.assignCategoriesMapProp = assignCategoriesMapProp;
1150function singleAssignCategoriesToksMap(path, nextNode) {
1151    utils_1.forEach(path, function (pathNode) {
1152        nextNode.categoryMatchesMap[pathNode.tokenTypeIdx] = true;
1153    });
1154    utils_1.forEach(nextNode.CATEGORIES, function (nextCategory) {
1155        var newPath = path.concat(nextNode);
1156        if (!utils_1.contains(newPath, nextCategory)) {
1157            singleAssignCategoriesToksMap(newPath, nextCategory);
1158        }
1159    });
1160}
1161function hasShortKeyProperty(tokType) {
1162    return utils_1.has(tokType, "tokenTypeIdx");
1163}
1164exports.hasShortKeyProperty = hasShortKeyProperty;
1165function hasCategoriesProperty(tokType) {
1166    return utils_1.has(tokType, "CATEGORIES");
1167}
1168exports.hasCategoriesProperty = hasCategoriesProperty;
1169function hasExtendingTokensTypesProperty(tokType) {
1170    return utils_1.has(tokType, "categoryMatches");
1171}
1172exports.hasExtendingTokensTypesProperty = hasExtendingTokensTypesProperty;
1173function hasExtendingTokensTypesMapProperty(tokType) {
1174    return utils_1.has(tokType, "categoryMatchesMap");
1175}
1176exports.hasExtendingTokensTypesMapProperty = hasExtendingTokensTypesMapProperty;
1177function hasTokenNameProperty(tokType) {
1178    return utils_1.has(tokType, "tokenName");
1179}
1180exports.hasTokenNameProperty = hasTokenNameProperty;
1181function isTokenType(tokType) {
1182    return utils_1.has(tokType, "tokenTypeIdx");
1183}
1184exports.isTokenType = isTokenType;
1185//# sourceMappingURL=tokens.js.map
1186
1187/***/ }),
1188/* 5 */
1189/***/ (function(module, exports, __webpack_require__) {
1190
1191"use strict";
1192
1193var __extends = (this && this.__extends) || (function () {
1194    var extendStatics = Object.setPrototypeOf ||
1195        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
1196        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
1197    return function (d, b) {
1198        extendStatics(d, b);
1199        function __() { this.constructor = d; }
1200        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1201    };
1202})();
1203Object.defineProperty(exports, "__esModule", { value: true });
1204/* tslint:disable:no-use-before-declare */
1205var rest_1 = __webpack_require__(10);
1206var gast_public_1 = __webpack_require__(1);
1207var utils_1 = __webpack_require__(0);
1208var tokens_public_1 = __webpack_require__(2);
1209var first_1 = __webpack_require__(15);
1210/* tslint:enable:no-use-before-declare */
1211var AbstractNextPossibleTokensWalker = /** @class */ (function (_super) {
1212    __extends(AbstractNextPossibleTokensWalker, _super);
1213    function AbstractNextPossibleTokensWalker(topProd, path) {
1214        var _this = _super.call(this) || this;
1215        _this.topProd = topProd;
1216        _this.path = path;
1217        _this.possibleTokTypes = [];
1218        _this.nextProductionName = "";
1219        _this.nextProductionOccurrence = 0;
1220        _this.found = false;
1221        _this.isAtEndOfPath = false;
1222        return _this;
1223    }
1224    AbstractNextPossibleTokensWalker.prototype.startWalking = function () {
1225        this.found = false;
1226        if (this.path.ruleStack[0] !== this.topProd.name) {
1227            throw Error("The path does not start with the walker's top Rule!");
1228        }
1229        // immutable for the win
1230        this.ruleStack = utils_1.cloneArr(this.path.ruleStack).reverse(); // intelij bug requires assertion
1231        this.occurrenceStack = utils_1.cloneArr(this.path.occurrenceStack).reverse(); // intelij bug requires assertion
1232        // already verified that the first production is valid, we now seek the 2nd production
1233        this.ruleStack.pop();
1234        this.occurrenceStack.pop();
1235        this.updateExpectedNext();
1236        this.walk(this.topProd);
1237        return this.possibleTokTypes;
1238    };
1239    AbstractNextPossibleTokensWalker.prototype.walk = function (prod, prevRest) {
1240        if (prevRest === void 0) { prevRest = []; }
1241        // stop scanning once we found the path
1242        if (!this.found) {
1243            _super.prototype.walk.call(this, prod, prevRest);
1244        }
1245    };
1246    AbstractNextPossibleTokensWalker.prototype.walkProdRef = function (refProd, currRest, prevRest) {
1247        // found the next production, need to keep walking in it
1248        if (refProd.referencedRule.name === this.nextProductionName &&
1249            refProd.occurrenceInParent === this.nextProductionOccurrence) {
1250            var fullRest = currRest.concat(prevRest);
1251            this.updateExpectedNext();
1252            this.walk(refProd.referencedRule, fullRest);
1253        }
1254    };
1255    AbstractNextPossibleTokensWalker.prototype.updateExpectedNext = function () {
1256        // need to consume the Terminal
1257        if (utils_1.isEmpty(this.ruleStack)) {
1258            // must reset nextProductionXXX to avoid walking down another Top Level production while what we are
1259            // really seeking is the last Terminal...
1260            this.nextProductionName = "";
1261            this.nextProductionOccurrence = 0;
1262            this.isAtEndOfPath = true;
1263        }
1264        else {
1265            this.nextProductionName = this.ruleStack.pop();
1266            this.nextProductionOccurrence = this.occurrenceStack.pop();
1267        }
1268    };
1269    return AbstractNextPossibleTokensWalker;
1270}(rest_1.RestWalker));
1271exports.AbstractNextPossibleTokensWalker = AbstractNextPossibleTokensWalker;
1272var NextAfterTokenWalker = /** @class */ (function (_super) {
1273    __extends(NextAfterTokenWalker, _super);
1274    function NextAfterTokenWalker(topProd, path) {
1275        var _this = _super.call(this, topProd, path) || this;
1276        _this.path = path;
1277        _this.nextTerminalName = "";
1278        _this.nextTerminalOccurrence = 0;
1279        _this.nextTerminalName = tokens_public_1.tokenName(_this.path.lastTok);
1280        _this.nextTerminalOccurrence = _this.path.lastTokOccurrence;
1281        return _this;
1282    }
1283    NextAfterTokenWalker.prototype.walkTerminal = function (terminal, currRest, prevRest) {
1284        if (this.isAtEndOfPath &&
1285            tokens_public_1.tokenName(terminal.terminalType) === this.nextTerminalName &&
1286            terminal.occurrenceInParent === this.nextTerminalOccurrence &&
1287            !this.found) {
1288            var fullRest = currRest.concat(prevRest);
1289            var restProd = new gast_public_1.gast.Flat(fullRest);
1290            this.possibleTokTypes = first_1.first(restProd);
1291            this.found = true;
1292        }
1293    };
1294    return NextAfterTokenWalker;
1295}(AbstractNextPossibleTokensWalker));
1296exports.NextAfterTokenWalker = NextAfterTokenWalker;
1297/**
1298 * This walker only "walks" a single "TOP" level in the Grammar Ast, this means
1299 * it never "follows" production refs
1300 */
1301var AbstractNextTerminalAfterProductionWalker = /** @class */ (function (_super) {
1302    __extends(AbstractNextTerminalAfterProductionWalker, _super);
1303    function AbstractNextTerminalAfterProductionWalker(topRule, occurrence) {
1304        var _this = _super.call(this) || this;
1305        _this.topRule = topRule;
1306        _this.occurrence = occurrence;
1307        _this.result = {
1308            token: undefined,
1309            occurrence: undefined,
1310            isEndOfRule: undefined
1311        };
1312        return _this;
1313    }
1314    AbstractNextTerminalAfterProductionWalker.prototype.startWalking = function () {
1315        this.walk(this.topRule);
1316        return this.result;
1317    };
1318    return AbstractNextTerminalAfterProductionWalker;
1319}(rest_1.RestWalker));
1320exports.AbstractNextTerminalAfterProductionWalker = AbstractNextTerminalAfterProductionWalker;
1321var NextTerminalAfterManyWalker = /** @class */ (function (_super) {
1322    __extends(NextTerminalAfterManyWalker, _super);
1323    function NextTerminalAfterManyWalker() {
1324        return _super !== null && _super.apply(this, arguments) || this;
1325    }
1326    NextTerminalAfterManyWalker.prototype.walkMany = function (manyProd, currRest, prevRest) {
1327        if (manyProd.occurrenceInParent === this.occurrence) {
1328            var firstAfterMany = utils_1.first(currRest.concat(prevRest));
1329            this.result.isEndOfRule = firstAfterMany === undefined;
1330            if (firstAfterMany instanceof gast_public_1.gast.Terminal) {
1331                this.result.token = firstAfterMany.terminalType;
1332                this.result.occurrence = firstAfterMany.occurrenceInParent;
1333            }
1334        }
1335        else {
1336            _super.prototype.walkMany.call(this, manyProd, currRest, prevRest);
1337        }
1338    };
1339    return NextTerminalAfterManyWalker;
1340}(AbstractNextTerminalAfterProductionWalker));
1341exports.NextTerminalAfterManyWalker = NextTerminalAfterManyWalker;
1342var NextTerminalAfterManySepWalker = /** @class */ (function (_super) {
1343    __extends(NextTerminalAfterManySepWalker, _super);
1344    function NextTerminalAfterManySepWalker() {
1345        return _super !== null && _super.apply(this, arguments) || this;
1346    }
1347    NextTerminalAfterManySepWalker.prototype.walkManySep = function (manySepProd, currRest, prevRest) {
1348        if (manySepProd.occurrenceInParent === this.occurrence) {
1349            var firstAfterManySep = utils_1.first(currRest.concat(prevRest));
1350            this.result.isEndOfRule = firstAfterManySep === undefined;
1351            if (firstAfterManySep instanceof gast_public_1.gast.Terminal) {
1352                this.result.token = firstAfterManySep.terminalType;
1353                this.result.occurrence = firstAfterManySep.occurrenceInParent;
1354            }
1355        }
1356        else {
1357            _super.prototype.walkManySep.call(this, manySepProd, currRest, prevRest);
1358        }
1359    };
1360    return NextTerminalAfterManySepWalker;
1361}(AbstractNextTerminalAfterProductionWalker));
1362exports.NextTerminalAfterManySepWalker = NextTerminalAfterManySepWalker;
1363var NextTerminalAfterAtLeastOneWalker = /** @class */ (function (_super) {
1364    __extends(NextTerminalAfterAtLeastOneWalker, _super);
1365    function NextTerminalAfterAtLeastOneWalker() {
1366        return _super !== null && _super.apply(this, arguments) || this;
1367    }
1368    NextTerminalAfterAtLeastOneWalker.prototype.walkAtLeastOne = function (atLeastOneProd, currRest, prevRest) {
1369        if (atLeastOneProd.occurrenceInParent === this.occurrence) {
1370            var firstAfterAtLeastOne = utils_1.first(currRest.concat(prevRest));
1371            this.result.isEndOfRule = firstAfterAtLeastOne === undefined;
1372            if (firstAfterAtLeastOne instanceof gast_public_1.gast.Terminal) {
1373                this.result.token = firstAfterAtLeastOne.terminalType;
1374                this.result.occurrence = firstAfterAtLeastOne.occurrenceInParent;
1375            }
1376        }
1377        else {
1378            _super.prototype.walkAtLeastOne.call(this, atLeastOneProd, currRest, prevRest);
1379        }
1380    };
1381    return NextTerminalAfterAtLeastOneWalker;
1382}(AbstractNextTerminalAfterProductionWalker));
1383exports.NextTerminalAfterAtLeastOneWalker = NextTerminalAfterAtLeastOneWalker;
1384// TODO: reduce code duplication in the AfterWalkers
1385var NextTerminalAfterAtLeastOneSepWalker = /** @class */ (function (_super) {
1386    __extends(NextTerminalAfterAtLeastOneSepWalker, _super);
1387    function NextTerminalAfterAtLeastOneSepWalker() {
1388        return _super !== null && _super.apply(this, arguments) || this;
1389    }
1390    NextTerminalAfterAtLeastOneSepWalker.prototype.walkAtLeastOneSep = function (atleastOneSepProd, currRest, prevRest) {
1391        if (atleastOneSepProd.occurrenceInParent === this.occurrence) {
1392            var firstAfterfirstAfterAtLeastOneSep = utils_1.first(currRest.concat(prevRest));
1393            this.result.isEndOfRule =
1394                firstAfterfirstAfterAtLeastOneSep === undefined;
1395            if (firstAfterfirstAfterAtLeastOneSep instanceof gast_public_1.gast.Terminal) {
1396                this.result.token =
1397                    firstAfterfirstAfterAtLeastOneSep.terminalType;
1398                this.result.occurrence =
1399                    firstAfterfirstAfterAtLeastOneSep.occurrenceInParent;
1400            }
1401        }
1402        else {
1403            _super.prototype.walkAtLeastOneSep.call(this, atleastOneSepProd, currRest, prevRest);
1404        }
1405    };
1406    return NextTerminalAfterAtLeastOneSepWalker;
1407}(AbstractNextTerminalAfterProductionWalker));
1408exports.NextTerminalAfterAtLeastOneSepWalker = NextTerminalAfterAtLeastOneSepWalker;
1409function possiblePathsFrom(targetDef, maxLength, currPath) {
1410    if (currPath === void 0) { currPath = []; }
1411    // avoid side effects
1412    currPath = utils_1.cloneArr(currPath);
1413    var result = [];
1414    var i = 0;
1415    function remainingPathWith(nextDef) {
1416        return nextDef.concat(utils_1.drop(targetDef, i + 1));
1417    }
1418    function getAlternativesForProd(definition) {
1419        var alternatives = possiblePathsFrom(remainingPathWith(definition), maxLength, currPath);
1420        return result.concat(alternatives);
1421    }
1422    /**
1423     * Mandatory productions will halt the loop as the paths computed from their recursive calls will already contain the
1424     * following (rest) of the targetDef.
1425     *
1426     * For optional productions (Option/Repetition/...) the loop will continue to represent the paths that do not include the
1427     * the optional production.
1428     */
1429    while (currPath.length < maxLength && i < targetDef.length) {
1430        var prod = targetDef[i];
1431        if (prod instanceof gast_public_1.gast.Flat) {
1432            return getAlternativesForProd(prod.definition);
1433        }
1434        else if (prod instanceof gast_public_1.gast.NonTerminal) {
1435            return getAlternativesForProd(prod.definition);
1436        }
1437        else if (prod instanceof gast_public_1.gast.Option) {
1438            result = getAlternativesForProd(prod.definition);
1439        }
1440        else if (prod instanceof gast_public_1.gast.RepetitionMandatory) {
1441            return getAlternativesForProd(prod.definition);
1442        }
1443        else if (prod instanceof gast_public_1.gast.RepetitionMandatoryWithSeparator) {
1444            var newDef = [
1445                new gast_public_1.gast.Flat(prod.definition),
1446                new gast_public_1.gast.Repetition([new gast_public_1.gast.Terminal(prod.separator)].concat(prod.definition))
1447            ];
1448            return getAlternativesForProd(newDef);
1449        }
1450        else if (prod instanceof gast_public_1.gast.RepetitionWithSeparator) {
1451            var newDef = prod.definition.concat([
1452                new gast_public_1.gast.Repetition([new gast_public_1.gast.Terminal(prod.separator)].concat(prod.definition))
1453            ]);
1454            result = getAlternativesForProd(newDef);
1455        }
1456        else if (prod instanceof gast_public_1.gast.Repetition) {
1457            result = getAlternativesForProd(prod.definition);
1458        }
1459        else if (prod instanceof gast_public_1.gast.Alternation) {
1460            utils_1.forEach(prod.definition, function (currAlt) {
1461                result = getAlternativesForProd(currAlt.definition);
1462            });
1463            return result;
1464        }
1465        else if (prod instanceof gast_public_1.gast.Terminal) {
1466            currPath.push(prod.terminalType);
1467        }
1468        else {
1469            /* istanbul ignore next */
1470            throw Error("non exhaustive match");
1471        }
1472        i++;
1473    }
1474    result.push({
1475        partialPath: currPath,
1476        suffixDef: utils_1.drop(targetDef, i)
1477    });
1478    return result;
1479}
1480exports.possiblePathsFrom = possiblePathsFrom;
1481function nextPossibleTokensAfter(initialDef, tokenVector, tokMatcher, maxLookAhead) {
1482    var EXIT_NON_TERMINAL = "EXIT_NONE_TERMINAL";
1483    // to avoid creating a new Array each time.
1484    var EXIT_NON_TERMINAL_ARR = [EXIT_NON_TERMINAL];
1485    var EXIT_ALTERNATIVE = "EXIT_ALTERNATIVE";
1486    var foundCompletePath = false;
1487    var tokenVectorLength = tokenVector.length;
1488    var minimalAlternativesIndex = tokenVectorLength - maxLookAhead - 1;
1489    var result = [];
1490    var possiblePaths = [];
1491    possiblePaths.push({
1492        idx: -1,
1493        def: initialDef,
1494        ruleStack: [],
1495        occurrenceStack: []
1496    });
1497    while (!utils_1.isEmpty(possiblePaths)) {
1498        var currPath = possiblePaths.pop();
1499        // skip alternatives if no more results can be found (assuming deterministic grammar with fixed lookahead)
1500        if (currPath === EXIT_ALTERNATIVE) {
1501            if (foundCompletePath &&
1502                utils_1.last(possiblePaths).idx <= minimalAlternativesIndex) {
1503                // remove irrelevant alternative
1504                possiblePaths.pop();
1505            }
1506            continue;
1507        }
1508        var currDef = currPath.def;
1509        var currIdx = currPath.idx;
1510        var currRuleStack = currPath.ruleStack;
1511        var currOccurrenceStack = currPath.occurrenceStack;
1512        // For Example: an empty path could exist in a valid grammar in the case of an EMPTY_ALT
1513        if (utils_1.isEmpty(currDef)) {
1514            continue;
1515        }
1516        var prod = currDef[0];
1517        if (prod === EXIT_NON_TERMINAL) {
1518            var nextPath = {
1519                idx: currIdx,
1520                def: utils_1.drop(currDef),
1521                ruleStack: utils_1.dropRight(currRuleStack),
1522                occurrenceStack: utils_1.dropRight(currOccurrenceStack)
1523            };
1524            possiblePaths.push(nextPath);
1525        }
1526        else if (prod instanceof gast_public_1.gast.Terminal) {
1527            if (currIdx < tokenVectorLength - 1) {
1528                var nextIdx = currIdx + 1;
1529                var actualToken = tokenVector[nextIdx];
1530                if (tokMatcher(actualToken, prod.terminalType)) {
1531                    var nextPath = {
1532                        idx: nextIdx,
1533                        def: utils_1.drop(currDef),
1534                        ruleStack: currRuleStack,
1535                        occurrenceStack: currOccurrenceStack
1536                    };
1537                    possiblePaths.push(nextPath);
1538                }
1539                // end of the line
1540            }
1541            else if (currIdx === tokenVectorLength - 1) {
1542                // IGNORE ABOVE ELSE
1543                result.push({
1544                    nextTokenType: prod.terminalType,
1545                    nextTokenOccurrence: prod.occurrenceInParent,
1546                    ruleStack: currRuleStack,
1547                    occurrenceStack: currOccurrenceStack
1548                });
1549                foundCompletePath = true;
1550            }
1551            else {
1552                /* istanbul ignore next */
1553                throw Error("non exhaustive match");
1554            }
1555        }
1556        else if (prod instanceof gast_public_1.gast.NonTerminal) {
1557            var newRuleStack = utils_1.cloneArr(currRuleStack);
1558            newRuleStack.push(prod.nonTerminalName);
1559            var newOccurrenceStack = utils_1.cloneArr(currOccurrenceStack);
1560            newOccurrenceStack.push(prod.occurrenceInParent);
1561            var nextPath = {
1562                idx: currIdx,
1563                def: prod.definition.concat(EXIT_NON_TERMINAL_ARR, utils_1.drop(currDef)),
1564                ruleStack: newRuleStack,
1565                occurrenceStack: newOccurrenceStack
1566            };
1567            possiblePaths.push(nextPath);
1568        }
1569        else if (prod instanceof gast_public_1.gast.Option) {
1570            // the order of alternatives is meaningful, FILO (Last path will be traversed first).
1571            var nextPathWithout = {
1572                idx: currIdx,
1573                def: utils_1.drop(currDef),
1574                ruleStack: currRuleStack,
1575                occurrenceStack: currOccurrenceStack
1576            };
1577            possiblePaths.push(nextPathWithout);
1578            // required marker to avoid backtracking paths whose higher priority alternatives already matched
1579            possiblePaths.push(EXIT_ALTERNATIVE);
1580            var nextPathWith = {
1581                idx: currIdx,
1582                def: prod.definition.concat(utils_1.drop(currDef)),
1583                ruleStack: currRuleStack,
1584                occurrenceStack: currOccurrenceStack
1585            };
1586            possiblePaths.push(nextPathWith);
1587        }
1588        else if (prod instanceof gast_public_1.gast.RepetitionMandatory) {
1589            // TODO:(THE NEW operators here take a while...) (convert once?)
1590            var secondIteration = new gast_public_1.gast.Repetition(prod.definition, prod.occurrenceInParent);
1591            var nextDef = prod.definition.concat([secondIteration], utils_1.drop(currDef));
1592            var nextPath = {
1593                idx: currIdx,
1594                def: nextDef,
1595                ruleStack: currRuleStack,
1596                occurrenceStack: currOccurrenceStack
1597            };
1598            possiblePaths.push(nextPath);
1599        }
1600        else if (prod instanceof gast_public_1.gast.RepetitionMandatoryWithSeparator) {
1601            // TODO:(THE NEW operators here take a while...) (convert once?)
1602            var separatorGast = new gast_public_1.gast.Terminal(prod.separator);
1603            var secondIteration = new gast_public_1.gast.Repetition([separatorGast].concat(prod.definition), prod.occurrenceInParent);
1604            var nextDef = prod.definition.concat([secondIteration], utils_1.drop(currDef));
1605            var nextPath = {
1606                idx: currIdx,
1607                def: nextDef,
1608                ruleStack: currRuleStack,
1609                occurrenceStack: currOccurrenceStack
1610            };
1611            possiblePaths.push(nextPath);
1612        }
1613        else if (prod instanceof gast_public_1.gast.RepetitionWithSeparator) {
1614            // the order of alternatives is meaningful, FILO (Last path will be traversed first).
1615            var nextPathWithout = {
1616                idx: currIdx,
1617                def: utils_1.drop(currDef),
1618                ruleStack: currRuleStack,
1619                occurrenceStack: currOccurrenceStack
1620            };
1621            possiblePaths.push(nextPathWithout);
1622            // required marker to avoid backtracking paths whose higher priority alternatives already matched
1623            possiblePaths.push(EXIT_ALTERNATIVE);
1624            var separatorGast = new gast_public_1.gast.Terminal(prod.separator);
1625            var nthRepetition = new gast_public_1.gast.Repetition([separatorGast].concat(prod.definition), prod.occurrenceInParent);
1626            var nextDef = prod.definition.concat([nthRepetition], utils_1.drop(currDef));
1627            var nextPathWith = {
1628                idx: currIdx,
1629                def: nextDef,
1630                ruleStack: currRuleStack,
1631                occurrenceStack: currOccurrenceStack
1632            };
1633            possiblePaths.push(nextPathWith);
1634        }
1635        else if (prod instanceof gast_public_1.gast.Repetition) {
1636            // the order of alternatives is meaningful, FILO (Last path will be traversed first).
1637            var nextPathWithout = {
1638                idx: currIdx,
1639                def: utils_1.drop(currDef),
1640                ruleStack: currRuleStack,
1641                occurrenceStack: currOccurrenceStack
1642            };
1643            possiblePaths.push(nextPathWithout);
1644            // required marker to avoid backtracking paths whose higher priority alternatives already matched
1645            possiblePaths.push(EXIT_ALTERNATIVE);
1646            // TODO: an empty repetition will cause infinite loops here, will the parser detect this in selfAnalysis?
1647            var nthRepetition = new gast_public_1.gast.Repetition(prod.definition, prod.occurrenceInParent);
1648            var nextDef = prod.definition.concat([nthRepetition], utils_1.drop(currDef));
1649            var nextPathWith = {
1650                idx: currIdx,
1651                def: nextDef,
1652                ruleStack: currRuleStack,
1653                occurrenceStack: currOccurrenceStack
1654            };
1655            possiblePaths.push(nextPathWith);
1656        }
1657        else if (prod instanceof gast_public_1.gast.Alternation) {
1658            // the order of alternatives is meaningful, FILO (Last path will be traversed first).
1659            for (var i = prod.definition.length - 1; i >= 0; i--) {
1660                var currAlt = prod.definition[i];
1661                var currAltPath = {
1662                    idx: currIdx,
1663                    def: currAlt.definition.concat(utils_1.drop(currDef)),
1664                    ruleStack: currRuleStack,
1665                    occurrenceStack: currOccurrenceStack
1666                };
1667                possiblePaths.push(currAltPath);
1668                possiblePaths.push(EXIT_ALTERNATIVE);
1669            }
1670        }
1671        else if (prod instanceof gast_public_1.gast.Flat) {
1672            possiblePaths.push({
1673                idx: currIdx,
1674                def: prod.definition.concat(utils_1.drop(currDef)),
1675                ruleStack: currRuleStack,
1676                occurrenceStack: currOccurrenceStack
1677            });
1678        }
1679        else if (prod instanceof gast_public_1.gast.Rule) {
1680            // last because we should only encounter at most a single one of these per invocation.
1681            possiblePaths.push(expandTopLevelRule(prod, currIdx, currRuleStack, currOccurrenceStack));
1682        }
1683        else {
1684            /* istanbul ignore next */
1685            throw Error("non exhaustive match");
1686        }
1687    }
1688    return result;
1689}
1690exports.nextPossibleTokensAfter = nextPossibleTokensAfter;
1691function expandTopLevelRule(topRule, currIdx, currRuleStack, currOccurrenceStack) {
1692    var newRuleStack = utils_1.cloneArr(currRuleStack);
1693    newRuleStack.push(topRule.name);
1694    var newCurrOccurrenceStack = utils_1.cloneArr(currOccurrenceStack);
1695    // top rule is always assumed to have been called with occurrence index 1
1696    newCurrOccurrenceStack.push(1);
1697    return {
1698        idx: currIdx,
1699        def: topRule.definition,
1700        ruleStack: newRuleStack,
1701        occurrenceStack: newCurrOccurrenceStack
1702    };
1703}
1704//# sourceMappingURL=interpreter.js.map
1705
1706/***/ }),
1707/* 6 */
1708/***/ (function(module, exports, __webpack_require__) {
1709
1710"use strict";
1711
1712Object.defineProperty(exports, "__esModule", { value: true });
1713var cache = __webpack_require__(7);
1714var cache_1 = __webpack_require__(7);
1715var exceptions_public_1 = __webpack_require__(12);
1716var lang_extensions_1 = __webpack_require__(3);
1717var resolver_1 = __webpack_require__(21);
1718var checks_1 = __webpack_require__(13);
1719var utils_1 = __webpack_require__(0);
1720var follow_1 = __webpack_require__(23);
1721var tokens_public_1 = __webpack_require__(2);
1722var lookahead_1 = __webpack_require__(14);
1723var gast_builder_1 = __webpack_require__(24);
1724var interpreter_1 = __webpack_require__(5);
1725var constants_1 = __webpack_require__(18);
1726var gast_public_1 = __webpack_require__(1);
1727var gast_1 = __webpack_require__(9);
1728var tokens_1 = __webpack_require__(4);
1729var cst_1 = __webpack_require__(16);
1730var keys_1 = __webpack_require__(17);
1731var cst_visitor_1 = __webpack_require__(26);
1732var errors_public_1 = __webpack_require__(19);
1733var serializeGrammar = gast_public_1.gast.serializeGrammar;
1734var ParserDefinitionErrorType;
1735(function (ParserDefinitionErrorType) {
1736    ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_RULE_NAME"] = 0] = "INVALID_RULE_NAME";
1737    ParserDefinitionErrorType[ParserDefinitionErrorType["DUPLICATE_RULE_NAME"] = 1] = "DUPLICATE_RULE_NAME";
1738    ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_RULE_OVERRIDE"] = 2] = "INVALID_RULE_OVERRIDE";
1739    ParserDefinitionErrorType[ParserDefinitionErrorType["DUPLICATE_PRODUCTIONS"] = 3] = "DUPLICATE_PRODUCTIONS";
1740    ParserDefinitionErrorType[ParserDefinitionErrorType["UNRESOLVED_SUBRULE_REF"] = 4] = "UNRESOLVED_SUBRULE_REF";
1741    ParserDefinitionErrorType[ParserDefinitionErrorType["LEFT_RECURSION"] = 5] = "LEFT_RECURSION";
1742    ParserDefinitionErrorType[ParserDefinitionErrorType["NONE_LAST_EMPTY_ALT"] = 6] = "NONE_LAST_EMPTY_ALT";
1743    ParserDefinitionErrorType[ParserDefinitionErrorType["AMBIGUOUS_ALTS"] = 7] = "AMBIGUOUS_ALTS";
1744    ParserDefinitionErrorType[ParserDefinitionErrorType["CONFLICT_TOKENS_RULES_NAMESPACE"] = 8] = "CONFLICT_TOKENS_RULES_NAMESPACE";
1745    ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_TOKEN_NAME"] = 9] = "INVALID_TOKEN_NAME";
1746    ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_NESTED_RULE_NAME"] = 10] = "INVALID_NESTED_RULE_NAME";
1747    ParserDefinitionErrorType[ParserDefinitionErrorType["DUPLICATE_NESTED_NAME"] = 11] = "DUPLICATE_NESTED_NAME";
1748    ParserDefinitionErrorType[ParserDefinitionErrorType["NO_NON_EMPTY_LOOKAHEAD"] = 12] = "NO_NON_EMPTY_LOOKAHEAD";
1749    ParserDefinitionErrorType[ParserDefinitionErrorType["AMBIGUOUS_PREFIX_ALTS"] = 13] = "AMBIGUOUS_PREFIX_ALTS";
1750    ParserDefinitionErrorType[ParserDefinitionErrorType["TOO_MANY_ALTS"] = 14] = "TOO_MANY_ALTS";
1751})(ParserDefinitionErrorType = exports.ParserDefinitionErrorType || (exports.ParserDefinitionErrorType = {}));
1752var IN_RULE_RECOVERY_EXCEPTION = "InRuleRecoveryException";
1753exports.END_OF_FILE = tokens_public_1.createTokenInstance(tokens_public_1.EOF, "", NaN, NaN, NaN, NaN, NaN, NaN);
1754Object.freeze(exports.END_OF_FILE);
1755var DEFAULT_PARSER_CONFIG = Object.freeze({
1756    recoveryEnabled: false,
1757    maxLookahead: 4,
1758    ignoredIssues: {},
1759    dynamicTokensEnabled: false,
1760    // TODO: Document this breaking change, can it be mitigated?
1761    // TODO: change to true
1762    outputCst: false,
1763    errorMessageProvider: errors_public_1.defaultErrorProvider
1764});
1765var DEFAULT_RULE_CONFIG = Object.freeze({
1766    recoveryValueFunc: function () { return undefined; },
1767    resyncEnabled: true
1768});
1769/**
1770 * Convenience used to express an empty alternative in an OR (alternation).
1771 * can be used to more clearly describe the intent in a case of empty alternation.
1772 *
1773 * For example:
1774 *
1775 * 1. without using EMPTY_ALT:
1776 *
1777 *    this.OR([
1778 *      {ALT: () => {
1779 *        this.CONSUME1(OneTok)
1780 *        return "1"
1781 *      }},
1782 *      {ALT: () => {
1783 *        this.CONSUME1(TwoTok)
1784 *        return "2"
1785 *      }},
1786 *      {ALT: () => { // implicitly empty because there are no invoked grammar rules (OR/MANY/CONSUME...) inside this alternative.
1787 *        return "666"
1788 *      }},
1789 *    ])
1790 *
1791 *
1792 * 2. using EMPTY_ALT:
1793 *
1794 *    this.OR([
1795 *      {ALT: () => {
1796 *        this.CONSUME1(OneTok)
1797 *        return "1"
1798 *      }},
1799 *      {ALT: () => {
1800 *        this.CONSUME1(TwoTok)
1801 *        return "2"
1802 *      }},
1803 *      {ALT: EMPTY_ALT("666")}, // explicitly empty, clearer intent
1804 *    ])
1805 *
1806 */
1807function EMPTY_ALT(value) {
1808    if (value === void 0) { value = undefined; }
1809    return function () {
1810        return value;
1811    };
1812}
1813exports.EMPTY_ALT = EMPTY_ALT;
1814var EOF_FOLLOW_KEY = {};
1815/**
1816 * A Recognizer capable of self analysis to determine it's grammar structure
1817 * This is used for more advanced features requiring such information.
1818 * For example: Error Recovery, Automatic lookahead calculation.
1819 */
1820var Parser = /** @class */ (function () {
1821    function Parser(input, tokensDictionary, config) {
1822        if (config === void 0) { config = DEFAULT_PARSER_CONFIG; }
1823        this._errors = [];
1824        this.isBackTrackingStack = [];
1825        this.RULE_STACK = [];
1826        this.RULE_OCCURRENCE_STACK = [];
1827        this.CST_STACK = [];
1828        this.tokensMap = undefined;
1829        this.definedRulesNames = [];
1830        this.shortRuleNameToFull = new lang_extensions_1.HashTable();
1831        this.fullRuleNameToShort = new lang_extensions_1.HashTable();
1832        // The shortName Index must be coded "after" the first 8bits to enable building unique lookahead keys
1833        this.ruleShortNameIdx = 256;
1834        this.LAST_EXPLICIT_RULE_STACK = [];
1835        this.selfAnalysisDone = false;
1836        this.currIdx = -1;
1837        /**
1838         * Only used internally for storing productions as they are built for the first time.
1839         * The final productions should be accessed from the static cache.
1840         */
1841        this._productions = new lang_extensions_1.HashTable();
1842        this.input = input;
1843        // configuration
1844        this.recoveryEnabled = utils_1.has(config, "recoveryEnabled")
1845            ? config.recoveryEnabled
1846            : DEFAULT_PARSER_CONFIG.recoveryEnabled;
1847        // performance optimization, NOOP will be inlined which
1848        // effectively means that this optional feature does not exist
1849        // when not used.
1850        if (!this.recoveryEnabled) {
1851            this.attemptInRepetitionRecovery = utils_1.NOOP;
1852        }
1853        this.dynamicTokensEnabled = utils_1.has(config, "dynamicTokensEnabled")
1854            ? config.dynamicTokensEnabled
1855            : DEFAULT_PARSER_CONFIG.dynamicTokensEnabled;
1856        this.maxLookahead = utils_1.has(config, "maxLookahead")
1857            ? config.maxLookahead
1858            : DEFAULT_PARSER_CONFIG.maxLookahead;
1859        this.ignoredIssues = utils_1.has(config, "ignoredIssues")
1860            ? config.ignoredIssues
1861            : DEFAULT_PARSER_CONFIG.ignoredIssues;
1862        this.outputCst = utils_1.has(config, "outputCst")
1863            ? config.outputCst
1864            : DEFAULT_PARSER_CONFIG.outputCst;
1865        this.errorMessageProvider = utils_1.defaults(config.errorMessageProvider, DEFAULT_PARSER_CONFIG.errorMessageProvider);
1866        if (!this.outputCst) {
1867            this.cstInvocationStateUpdate = utils_1.NOOP;
1868            this.cstFinallyStateUpdate = utils_1.NOOP;
1869            this.cstPostTerminal = utils_1.NOOP;
1870            this.cstPostNonTerminal = utils_1.NOOP;
1871            this.getLastExplicitRuleShortName = this.getLastExplicitRuleShortNameNoCst;
1872            this.getPreviousExplicitRuleShortName = this.getPreviousExplicitRuleShortNameNoCst;
1873            this.getPreviousExplicitRuleOccurenceIndex = this.getPreviousExplicitRuleOccurenceIndexNoCst;
1874            this.manyInternal = this.manyInternalNoCst;
1875            this.orInternal = this.orInternalNoCst;
1876            this.optionInternal = this.optionInternalNoCst;
1877            this.atLeastOneInternal = this.atLeastOneInternalNoCst;
1878            this.manySepFirstInternal = this.manySepFirstInternalNoCst;
1879            this.atLeastOneSepFirstInternal = this.atLeastOneSepFirstInternalNoCst;
1880        }
1881        this.className = lang_extensions_1.classNameFromInstance(this);
1882        this.firstAfterRepMap = cache.getFirstAfterRepForClass(this.className);
1883        this.classLAFuncs = cache.getLookaheadFuncsForClass(this.className);
1884        this.cstDictDefForRule = cache.getCstDictDefPerRuleForClass(this.className);
1885        if (!cache.CLASS_TO_DEFINITION_ERRORS.containsKey(this.className)) {
1886            this.definitionErrors = [];
1887            cache.CLASS_TO_DEFINITION_ERRORS.put(this.className, this.definitionErrors);
1888        }
1889        else {
1890            this.definitionErrors = cache.CLASS_TO_DEFINITION_ERRORS.get(this.className);
1891        }
1892        if (utils_1.isArray(tokensDictionary)) {
1893            this.tokensMap = utils_1.reduce(tokensDictionary, function (acc, tokenClazz) {
1894                acc[tokens_public_1.tokenName(tokenClazz)] = tokenClazz;
1895                return acc;
1896            }, {});
1897        }
1898        else if (utils_1.has(tokensDictionary, "modes") &&
1899            utils_1.every(utils_1.flatten(utils_1.values(tokensDictionary.modes)), tokens_1.isTokenType)) {
1900            var allTokenTypes = utils_1.flatten(utils_1.values(tokensDictionary.modes));
1901            var uniqueTokens = utils_1.uniq(allTokenTypes);
1902            this.tokensMap = utils_1.reduce(uniqueTokens, function (acc, tokenClazz) {
1903                acc[tokens_public_1.tokenName(tokenClazz)] = tokenClazz;
1904                return acc;
1905            }, {});
1906        }
1907        else