function compileAction(lexer, ruleName, action) {
    if (!action) {
        return { token: '' };
    }
    else if (typeof (action) === 'string') {
        return action; // { token: action };
    }
    else if (action.token || action.token === '') {
        if (typeof (action.token) !== 'string') {
            throw monarchCommon.createError(lexer, 'a \'token\' attribute must be of type string, in rule: ' + ruleName);
            return { token: '' };
        }
        else {
            // only copy specific typed fields (only happens once during compile Lexer)
            var newAction = { token: action.token };
            if (action.token.indexOf('$') >= 0) {
                newAction.tokenSubst = true;
            }
            if (typeof (action.bracket) === 'string') {
                if (action.bracket === '@open') {
                    newAction.bracket = 1 /* Open */;
                }
                else if (action.bracket === '@close') {
                    newAction.bracket = -1 /* Close */;
                }
                else {
                    throw monarchCommon.createError(lexer, 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName);
                }
            }
            if (action.next) {
                if (typeof (action.next) !== 'string') {
                    throw monarchCommon.createError(lexer, 'the next state must be a string value in rule: ' + ruleName);
                }
                else {
                    var next = action.next;
                    if (!/^(@pop|@push|@popall)$/.test(next)) {
                        if (next[0] === '@') {
                            next = next.substr(1); // peel off starting @ sign
                        }
                        if (next.indexOf('$') < 0) { // no dollar substitution, we can check if the state exists
                            if (!monarchCommon.stateExists(lexer, monarchCommon.substituteMatches(lexer, next, '', [], ''))) {
                                throw monarchCommon.createError(lexer, 'the next state \'' + action.next + '\' is not defined in rule: ' + ruleName);
                            }
                        }
                    }
                    newAction.next = next;
                }
            }
            if (typeof (action.goBack) === 'number') {
                newAction.goBack = action.goBack;
            }
            if (typeof (action.switchTo) === 'string') {
                newAction.switchTo = action.switchTo;
            }
            if (typeof (action.log) === 'string') {
                newAction.log = action.log;
            }
            if (typeof (action.nextEmbedded) === 'string') {
                newAction.nextEmbedded = action.nextEmbedded;
                lexer.usesEmbedded = true;
            }
            return newAction;
        }
    }
    else if (Array.isArray(action)) {
        var results = [];
        for (var idx in action) {
            if (action.hasOwnProperty(idx)) {
                results[idx] = compileAction(lexer, ruleName, action[idx]);
            }
        }
        return { group: results };
    }
    else if (action.cases) {
        // build an array of test cases
        var cases_1 = [];
        // for each case, push a test function and result value
        for (var tkey in action.cases) {
            if (action.cases.hasOwnProperty(tkey)) {
                var val = compileAction(lexer, ruleName, action.cases[tkey]);
                // what kind of case
                if (tkey === '@default' || tkey === '@' || tkey === '') {
                    cases_1.push({ test: undefined, value: val, name: tkey });
                }
                else if (tkey === '@eos') {
                    cases_1.push({ test: function (id, matches, state, eos) { return eos; }, value: val, name: tkey });
                }
                else {
                    cases_1.push(createGuard(lexer, ruleName, tkey, val)); // call separate function to avoid local variable capture
                }
            }
        }
        // create a matching function
        var def_1 = lexer.defaultToken;
        return {
            test: function (id, matches, state, eos) {
                for (var idx in cases_1) {
                    if (cases_1.hasOwnProperty(idx)) {
                        var _case = cases_1[idx];
                        var didmatch = (!_case.test || _case.test(id, matches, state, eos));
                        if (didmatch) {
                            return _case.value;
                        }
                    }
                }
                return def_1;
            }
        };
    }
    else {
        throw monarchCommon.createError(lexer, 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName);
        return '';
    }
}
/**
 * Compiles an action: i.e. optimize regular expressions and case matches
 * and do many sanity checks.
 *
 * This is called only during compilation but if the lexer definition
 * contains user functions as actions (which is usually not allowed), then this
 * may be called during lexing. It is important therefore to compile common cases efficiently
 */


This is called only during compilation but if the lexer definition
contains user functions as actions (which is usually not allowed), then this
may be called during lexing. It is important therefore to compile common cases efficiently
This is called only during compilation but if the lexer definition contains user functions as actions ( which is usually not allowed ) then this may be called during lexing . It is important therefore to compile common cases efficiently
function compileAction(lexer, ruleName, action) {
    if (!action) {
        return { token: '' };
    }
    else if (typeof (action) === 'string') {
        return action; 
    }
    else if (action.token || action.token === '') {
        if (typeof (action.token) !== 'string') {
            throw monarchCommon.createError(lexer, 'a \'token\' attribute must be of type string, in rule: ' + ruleName);
            return { token: '' };
        }
        else {
            var newAction = { token: action.token };
            if (action.token.indexOf('$') >= 0) {
                newAction.tokenSubst = true;
            }
            if (typeof (action.bracket) === 'string') {
                if (action.bracket === '@open') {
                    newAction.bracket = 1 ;
                }
                else if (action.bracket === '@close') {
                    newAction.bracket = -1 ;
                }
                else {
                    throw monarchCommon.createError(lexer, 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName);
                }
            }
            if (action.next) {
                if (typeof (action.next) !== 'string') {
                    throw monarchCommon.createError(lexer, 'the next state must be a string value in rule: ' + ruleName);
                }
                else {
                    var next = action.next;
                    if (!/^(@pop|@push|@popall)$/.test(next)) {
                        if (next[0] === '@') {
                            next = next.substr(1); 
                        }
                        if (next.indexOf('$') < 0) { 
                            if (!monarchCommon.stateExists(lexer, monarchCommon.substituteMatches(lexer, next, '', [], ''))) {
                                throw monarchCommon.createError(lexer, 'the next state \'' + action.next + '\' is not defined in rule: ' + ruleName);
                            }
                        }
                    }
                    newAction.next = next;
                }
            }
            if (typeof (action.goBack) === 'number') {
                newAction.goBack = action.goBack;
            }
            if (typeof (action.switchTo) === 'string') {
                newAction.switchTo = action.switchTo;
            }
            if (typeof (action.log) === 'string') {
                newAction.log = action.log;
            }
            if (typeof (action.nextEmbedded) === 'string') {
                newAction.nextEmbedded = action.nextEmbedded;
                lexer.usesEmbedded = true;
            }
            return newAction;
        }
    }
    else if (Array.isArray(action)) {
        var results = [];
        for (var idx in action) {
            if (action.hasOwnProperty(idx)) {
                results[idx] = compileAction(lexer, ruleName, action[idx]);
            }
        }
        return { group: results };
    }
    else if (action.cases) {
        var cases_1 = [];
        for (var tkey in action.cases) {
            if (action.cases.hasOwnProperty(tkey)) {
                var val = compileAction(lexer, ruleName, action.cases[tkey]);
                if (tkey === '@default' || tkey === '@' || tkey === '') {
                    cases_1.push({ test: undefined, value: val, name: tkey });
                }
                else if (tkey === '@eos') {
                    cases_1.push({ test: function (id, matches, state, eos) { return eos; }, value: val, name: tkey });
                }
                else {
                    cases_1.push(createGuard(lexer, ruleName, tkey, val)); 
                }
            }
        }
        var def_1 = lexer.defaultToken;
        return {
            test: function (id, matches, state, eos) {
                for (var idx in cases_1) {
                    if (cases_1.hasOwnProperty(idx)) {
                        var _case = cases_1[idx];
                        var didmatch = (!_case.test || _case.test(id, matches, state, eos));
                        if (didmatch) {
                            return _case.value;
                        }
                    }
                }
                return def_1;
            }
        };
    }
    else {
        throw monarchCommon.createError(lexer, 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName);
        return '';
    }
}
function compileAction ( lexer , ruleName , action ) { if ( ! action ) { return { token : '' } ; } else if ( typeof ( action ) === 'string' ) { return action ; } else if ( action . token || action . token === '' ) { if ( typeof ( action . token ) !== 'string' ) { throw monarchCommon . createError ( lexer , 'a \'token\' attribute must be of type string, in rule: ' + ruleName ) ; return { token : '' } ; } else { var newAction = { token : action . token } ; if ( action . token . indexOf ( '$' ) >= 0 ) { newAction . tokenSubst = true ; } if ( typeof ( action . bracket ) === 'string' ) { if ( action . bracket === '@open' ) { newAction . bracket = 1 ; } else if ( action . bracket === '@close' ) { newAction . bracket = - 1 ; } else { throw monarchCommon . createError ( lexer , 'a \'bracket\' attribute must be either \'@open\' or \'@close\', in rule: ' + ruleName ) ; } } if ( action . next ) { if ( typeof ( action . next ) !== 'string' ) { throw monarchCommon . createError ( lexer , 'the next state must be a string value in rule: ' + ruleName ) ; } else { var next = action . next ; if ( ! / ^(@pop|@push|@popall)$ / . test ( next ) ) { if ( next [ 0 ] === '@' ) { next = next . substr ( 1 ) ; } if ( next . indexOf ( '$' ) < 0 ) { if ( ! monarchCommon . stateExists ( lexer , monarchCommon . substituteMatches ( lexer , next , '' , [ ] , '' ) ) ) { throw monarchCommon . createError ( lexer , 'the next state \'' + action . next + '\' is not defined in rule: ' + ruleName ) ; } } } newAction . next = next ; } } if ( typeof ( action . goBack ) === 'number' ) { newAction . goBack = action . goBack ; } if ( typeof ( action . switchTo ) === 'string' ) { newAction . switchTo = action . switchTo ; } if ( typeof ( action . log ) === 'string' ) { newAction . log = action . log ; } if ( typeof ( action . nextEmbedded ) === 'string' ) { newAction . nextEmbedded = action . nextEmbedded ; lexer . usesEmbedded = true ; } return newAction ; } } else if ( Array . isArray ( action ) ) { var results = [ ] ; for ( var idx in action ) { if ( action . hasOwnProperty ( idx ) ) { results [ idx ] = compileAction ( lexer , ruleName , action [ idx ] ) ; } } return { group : results } ; } else if ( action . cases ) { var cases_1 = [ ] ; for ( var tkey in action . cases ) { if ( action . cases . hasOwnProperty ( tkey ) ) { var val = compileAction ( lexer , ruleName , action . cases [ tkey ] ) ; if ( tkey === '@default' || tkey === '@' || tkey === '' ) { cases_1 . push ( { test : undefined , value : val , name : tkey } ) ; } else if ( tkey === '@eos' ) { cases_1 . push ( { test : function ( id , matches , state , eos ) { return eos ; } , value : val , name : tkey } ) ; } else { cases_1 . push ( createGuard ( lexer , ruleName , tkey , val ) ) ; } } } var def_1 = lexer . defaultToken ; return { test : function ( id , matches , state , eos ) { for ( var idx in cases_1 ) { if ( cases_1 . hasOwnProperty ( idx ) ) { var _case = cases_1 [ idx ] ; var didmatch = ( ! _case . test || _case . test ( id , matches , state , eos ) ) ; if ( didmatch ) { return _case . value ; } } } return def_1 ; } } ; } else { throw monarchCommon . createError ( lexer , 'an action must be a string, an object with a \'token\' or \'cases\' attribute, or an array of actions; in rule: ' + ruleName ) ; return '' ; } }
Compiles an action: i.e.
Compiles an action : i . e .
// { token: action }; // only copy specific typed fields (only happens once during compile Lexer) /* Open */ /* Close */ // peel off starting @ sign // no dollar substitution, we can check if the state exists // build an array of test cases // for each case, push a test function and result value // what kind of case // call separate function to avoid local variable capture // create a matching function