text: // Generated by CoffeeScript 1.4.0
  (function() {
    var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
  
    Parser = require('jison').Parser;
  
    unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
  
    o = function(patternString, action, options) {
      var match;
      patternString = patternString.replace(/\s{2,}/g, ' ');
      if (!action) {
        return [patternString, '$$ = $1;', options];
      }
      action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
      action = action.replace(/\bnew /g, '$&yy.');
      action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
      return [patternString, "$$ = " + action + ";", options];
    };
  
    grammar = {
      Root: [
        o('', function() {
          return new Block;
        }), o('Body'), o('Block TERMINATOR')
      ],
      Body: [
        o('Line', function() {
          return Block.wrap([$1]);
        }), o('Body TERMINATOR Line', function() {
          return $1.push($3);
        }), o('Body TERMINATOR')
      ],
      Line: [o('Expression'), o('Statement')],
      Statement: [
        o('Return'), o('Comment'), o('STATEMENT', function() {
          return new Literal($1);
        })
      ],
      Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')],
      Block: [
        o('INDENT OUTDENT', function() {
          return new Block;
        }), o('INDENT Body OUTDENT', function() {
          return $2;
        })
      ],
      Identifier: [
        o('IDENTIFIER', function() {
          return new Literal($1);
        })
      ],
      AlphaNumeric: [
        o('NUMBER', function() {
          return new Literal($1);
        }), o('STRING', function() {
          return new Literal($1);
        })
      ],
      Literal: [
        o('AlphaNumeric'), o('JS', function() {
          return new Literal($1);
        }), o('REGEX', function() {
          return new Literal($1);
        }), o('DEBUGGER', function() {
          return new Literal($1);
        }), o('UNDEFINED', function() {
          return new Undefined;
        }), o('NULL', function() {
          return new Null;
        }), o('BOOL', function() {
          return new Bool($1);
        })
      ],
      Assign: [
        o('Assignable = Expression', function() {
          return new Assign($1, $3);
        }), o('Assignable = TERMINATOR Expression', function() {
          return new Assign($1, $4);
        }), o('Assignable = INDENT Expression OUTDENT', function() {
          return new Assign($1, $4);
        })
      ],
      AssignObj: [
        o('ObjAssignable', function() {
          return new Value($1);
        }), o('ObjAssignable : Expression', function() {
          return new Assign(new Value($1), $3, 'object');
        }), o('ObjAssignable :\
         INDENT Expression OUTDENT', function() {
          return new Assign(new Value($1), $4, 'object');
        }), o('Comment')
      ],
      ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
      Return: [
        o('RETURN Expression', function() {
          return new Return($2);
        }), o('RETURN', function() {
          return new Return;
        })
      ],
      Comment: [
        o('HERECOMMENT', function() {
          return new Comment($1);
        })
      ],
      Code: [
        o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
          return new Code($2, $5, $4);
        }), o('FuncGlyph Block', function() {
          return new Code([], $2, $1);
        })
      ],
      FuncGlyph: [
        o('->', function() {
          return 'func';
        }), o('=>', function() {
          return 'boundfunc';
        })
      ],
      OptComma: [o(''), o(',')],
      ParamList: [
        o('', function() {
          return [];
        }), o('Param', function() {
          return [$1];
        }), o('ParamList , Param', function() {
          return $1.concat($3);
        }), o('ParamList OptComma TERMINATOR Param', function() {
          return $1.concat($4);
        }), o('ParamList OptComma INDENT ParamList OptComma OUTDENT', function() {
          return $1.concat($4);
        })
      ],
      Param: [
        o('ParamVar', function() {
          return new Param($1);
        }), o('ParamVar ...', function() {
          return new Param($1, null, true);
        }), o('ParamVar = Expression', function() {
          return new Param($1, $3);
        })
      ],
      ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
      Splat: [
        o('Expression ...', function() {
          return new Splat($1);
        })
      ],
      SimpleAssignable: [
        o('Identifier', function() {
          return new Value($1);
        }), o('Value Accessor', function() {
          return $1.add($2);
        }), o('Invocation Accessor', function() {
          return new Value($1, [].concat($2));
        }), o('ThisProperty')
      ],
      Assignable: [
        o('SimpleAssignable'), o('Array', function() {
          return new Value($1);
        }), o('Object', function() {
          return new Value($1);
        })
      ],
      Value: [
        o('Assignable'), o('Literal', function() {
          return new Value($1);
        }), o('Parenthetical', function() {
          return new Value($1);
        }), o('Range', function() {
          return new Value($1);
        }), o('This')
      ],
      Accessor: [
        o('.  Identifier', function() {
          return new Access($2);
        }), o('?. Identifier', function() {
          return new Access($2, 'soak');
        }), o(':: Identifier', function() {
          return [new Access(new Literal('prototype')), new Access($2)];
        }), o('::', function() {
          return new Access(new Literal('prototype'));
        }), o('Index')
      ],
      Index: [
        o('INDEX_START IndexValue INDEX_END', function() {
          return $2;
        }), o('INDEX_SOAK  Index', function() {
          return extend($2, {
            soak: true
          });
        })
      ],
      IndexValue: [
        o('Expression', function() {
          return new Index($1);
        }), o('Slice', function() {
          return new Slice($1);
        })
      ],
      Object: [
        o('{ AssignList OptComma }', function() {
          return new Obj($2, $1.generated);
        })
      ],
      AssignList: [
        o('', function() {
          return [];
        }), o('AssignObj', function() {
          return [$1];
        }), o('AssignList , AssignObj', function() {
          return $1.concat($3);
        }), o('AssignList OptComma TERMINATOR AssignObj', function() {
          return $1.concat($4);
        }), o('AssignList OptComma INDENT AssignList OptComma OUTDENT', function() {
          return $1.concat($4);
        })
      ],
      Class: [
        o('CLASS', function() {
          return new Class;
        }), o('CLASS Block', function() {
          return new Class(null, null, $2);
        }), o('CLASS EXTENDS Expression', function() {
          return new Class(null, $3);
        }), o('CLASS EXTENDS Expression Block', function() {
          return new Class(null, $3, $4);
        }), o('CLASS SimpleAssignable', function() {
          return new Class($2);
        }), o('CLASS SimpleAssignable Block', function() {
          return new Class($2, null, $3);
        }), o('CLASS SimpleAssignable EXTENDS Expression', function() {
          return new Class($2, $4);
        }), o('CLASS SimpleAssignable EXTENDS Expression Block', function() {
          return new Class($2, $4, $5);
        })
      ],
      Invocation: [
        o('Value OptFuncExist Arguments', function() {
          return new Call($1, $3, $2);
        }), o('Invocation OptFuncExist Arguments', function() {
          return new Call($1, $3, $2);
        }), o('SUPER', function() {
          return new Call('super', [new Splat(new Literal('arguments'))]);
        }), o('SUPER Arguments', function() {
          return new Call('super', $2);
        })
      ],
      OptFuncExist: [
        o('', function() {
          return false;
        }), o('FUNC_EXIST', function() {
          return true;
        })
      ],
      Arguments: [
        o('CALL_START CALL_END', function() {
          return [];
        }), o('CALL_START ArgList OptComma CALL_END', function() {
          return $2;
        })
      ],
      This: [
        o('THIS', function() {
          return new Value(new Literal('this'));
        }), o('@', function() {
          return new Value(new Literal('this'));
        })
      ],
      ThisProperty: [
        o('@ Identifier', function() {
          return new Value(new Literal('this'), [new Access($2)], 'this');
        })
      ],
      Array: [
        o('[ ]', function() {
          return new Arr([]);
        }), o('[ ArgList OptComma ]', function() {
          return new Arr($2);
        })
      ],
      RangeDots: [
        o('..', function() {
          return 'inclusive';
        }), o('...', function() {
          return 'exclusive';
        })
      ],
      Range: [
        o('[ Expression RangeDots Expression ]', function() {
          return new Range($2, $4, $3);
        })
      ],
      Slice: [
        o('Expression RangeDots Expression', function() {
          return new Range($1, $3, $2);
        }), o('Expression RangeDots', function() {
          return new Range($1, null, $2);
        }), o('RangeDots Expression', function() {
          return new Range(null, $2, $1);
        }), o('RangeDots', function() {
          return new Range(null, null, $1);
        })
      ],
      ArgList: [
        o('Arg', function() {
          return [$1];
        }), o('ArgList , Arg', function() {
          return $1.concat($3);
        }), o('ArgList OptComma TERMINATOR Arg', function() {
          return $1.concat($4);
        }), o('INDENT ArgList OptComma OUTDENT', function() {
          return $2;
        }), o('ArgList OptComma INDENT ArgList OptComma OUTDENT', function() {
          return $1.concat($4);
        })
      ],
      Arg: [o('Expression'), o('Splat')],
      SimpleArgs: [
        o('Expression'), o('SimpleArgs , Expression', function() {
          return [].concat($1, $3);
        })
      ],
      Try: [
        o('TRY Block', function() {
          return new Try($2);
        }), o('TRY Block Catch', function() {
          return new Try($2, $3[0], $3[1]);
        }), o('TRY Block FINALLY Block', function() {
          return new Try($2, null, null, $4);
        }), o('TRY Block Catch FINALLY Block', function() {
          return new Try($2, $3[0], $3[1], $5);
        })
      ],
      Catch: [
        o('CATCH Identifier Block', function() {
          return [$2, $3];
        })
      ],
      Throw: [
        o('THROW Expression', function() {
          return new Throw($2);
        })
      ],
      Parenthetical: [
        o('( Body )', function() {
          return new Parens($2);
        }), o('( INDENT Body OUTDENT )', function() {
          return new Parens($3);
        })
      ],
      WhileSource: [
        o('WHILE Expression', function() {
          return new While($2);
        }), o('WHILE Expression WHEN Expression', function() {
          return new While($2, {
            guard: $4
          });
        }), o('UNTIL Expression', function() {
          return new While($2, {
            invert: true
          });
        }), o('UNTIL Expression WHEN Expression', function() {
          return new While($2, {
            invert: true,
            guard: $4
          });
        })
      ],
      While: [
        o('WhileSource Block', function() {
          return $1.addBody($2);
        }), o('Statement  WhileSource', function() {
          return $2.addBody(Block.wrap([$1]));
        }), o('Expression WhileSource', function() {
          return $2.addBody(Block.wrap([$1]));
        }), o('Loop', function() {
          return $1;
        })
      ],
      Loop: [
        o('LOOP Block', function() {
          return new While(new Literal('true')).addBody($2);
        }), o('LOOP Expression', function() {
          return new While(new Literal('true')).addBody(Block.wrap([$2]));
        })
      ],
      For: [
        o('Statement  ForBody', function() {
          return new For($1, $2);
        }), o('Expression ForBody', function() {
          return new For($1, $2);
        }), o('ForBody    Block', function() {
          return new For($2, $1);
        })
      ],
      ForBody: [
        o('FOR Range', function() {
          return {
            source: new Value($2)
          };
        }), o('ForStart ForSource', function() {
          $2.own = $1.own;
          $2.name = $1[0];
          $2.index = $1[1];
          return $2;
        })
      ],
      ForStart: [
        o('FOR ForVariables', function() {
          return $2;
        }), o('FOR OWN ForVariables', function() {
          $3.own = true;
          return $3;
        })
      ],
      ForValue: [
        o('Identifier'), o('ThisProperty'), o('Array', function() {
          return new Value($1);
        }), o('Object', function() {
          return new Value($1);
        })
      ],
      ForVariables: [
        o('ForValue', function() {
          return [$1];
        }), o('ForValue , ForValue', function() {
          return [$1, $3];
        })
      ],
      ForSource: [
        o('FORIN Expression', function() {
          return {
            source: $2
          };
        }), o('FOROF Expression', function() {
          return {
            source: $2,
            object: true
          };
        }), o('FORIN Expression WHEN Expression', function() {
          return {
            source: $2,
            guard: $4
          };
        }), o('FOROF Expression WHEN Expression', function() {
          return {
            source: $2,
            guard: $4,
            object: true
          };
        }), o('FORIN Expression BY Expression', function() {
          return {
            source: $2,
            step: $4
          };
        }), o('FORIN Expression WHEN Expression BY Expression', function() {
          return {
            source: $2,
            guard: $4,
            step: $6
          };
        }), o('FORIN Expression BY Expression WHEN Expression', function() {
          return {
            source: $2,
            step: $4,
            guard: $6
          };
        })
      ],
      Switch: [
        o('SWITCH Expression INDENT Whens OUTDENT', function() {
          return new Switch($2, $4);
        }), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
          return new Switch($2, $4, $6);
        }), o('SWITCH INDENT Whens OUTDENT', function() {
          return new Switch(null, $3);
        }), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
          return new Switch(null, $3, $5);
        })
      ],
      Whens: [
        o('When'), o('Whens When', function() {
          return $1.concat($2);
        })
      ],
      When: [
        o('LEADING_WHEN SimpleArgs Block', function() {
          return [[$2, $3]];
        }), o('LEADING_WHEN SimpleArgs Block TERMINATOR', function() {
          return [[$2, $3]];
        })
      ],
      IfBlock: [
        o('IF Expression Block', function() {
          return new If($2, $3, {
            type: $1
          });
        }), o('IfBlock ELSE IF Expression Block', function() {
          return $1.addElse(new If($4, $5, {
            type: $3
          }));
        })
      ],
      If: [
        o('IfBlock'), o('IfBlock ELSE Block', function() {
          return $1.addElse($3);
        }), o('Statement  POST_IF Expression', function() {
          return new If($3, Block.wrap([$1]), {
            type: $2,
            statement: true
          });
        }), o('Expression POST_IF Expression', function() {
          return new If($3, Block.wrap([$1]), {
            type: $2,
            statement: true
          });
        })
      ],
      Operation: [
        o('UNARY Expression', function() {
          return new Op($1, $2);
        }), o('-     Expression', (function() {
          return new Op('-', $2);
        }), {
          prec: 'UNARY'
        }), o('+     Expression', (function() {
          return new Op('+', $2);
        }), {
          prec: 'UNARY'
        }), o('-- SimpleAssignable', function() {
          return new Op('--', $2);
        }), o('++ SimpleAssignable', function() {
          return new Op('++', $2);
        }), o('SimpleAssignable --', function() {
          return new Op('--', $1, null, true);
        }), o('SimpleAssignable ++', function() {
          return new Op('++', $1, null, true);
        }), o('Expression ?', function() {
          return new Existence($1);
        }), o('Expression +  Expression', function() {
          return new Op('+', $1, $3);
        }), o('Expression -  Expression', function() {
          return new Op('-', $1, $3);
        }), o('Expression MATH     Expression', function() {
          return new Op($2, $1, $3);
        }), o('Expression SHIFT    Expression', function() {
          return new Op($2, $1, $3);
        }), o('Expression COMPARE  Expression', function() {
          return new Op($2, $1, $3);
        }), o('Expression LOGIC    Expression', function() {
          return new Op($2, $1, $3);
        }), o('Expression RELATION Expression', function() {
          if ($2.charAt(0) === '!') {
            return new Op($2.slice(1), $1, $3).invert();
          } else {
            return new Op($2, $1, $3);
          }
        }), o('SimpleAssignable COMPOUND_ASSIGN\
         Expression', function() {
          return new Assign($1, $3, $2);
        }), o('SimpleAssignable COMPOUND_ASSIGN\
         INDENT Expression OUTDENT', function() {
          return new Assign($1, $4, $2);
        }), o('SimpleAssignable EXTENDS Expression', function() {
          return new Extends($1, $3);
        })
      ]
    };
  
    operators = [['left', '.', '?.', '::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
  
    tokens = [];
  
    for (name in grammar) {
      alternatives = grammar[name];
      grammar[name] = (function() {
        var _i, _j, _len, _len1, _ref, _results;
        _results = [];
        for (_i = 0, _len = alternatives.length; _i < _len; _i++) {
          alt = alternatives[_i];
          _ref = alt[0].split(' ');
          for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
            token = _ref[_j];
            if (!grammar[token]) {
              tokens.push(token);
            }
          }
          if (name === 'Root') {
            alt[1] = "return " + alt[1];
          }
          _results.push(alt);
        }
        return _results;
      })();
    }
  
    exports.parser = new Parser({
      tokens: tokens.join(' '),
      bnf: grammar,
      operators: operators.reverse(),
      startSymbol: 'Root'
    });
  
  }).call(this);
  