/* Parser.java */
/* Generated By:JavaCC: Do not edit this line. Parser.java */
package org.classdump.luna.parser;

import org.classdump.luna.parser.ast.*;

import java.util.*;

import static java.util.Collections.*;

public class Parser implements ParserConstants {

        private static SourceInfo src(Token t) {
                return new SourceInfo(t.beginLine, t.beginColumn);
        }

        private static Attributes attr(Token t) {
                return Attributes.of(src(t));
        }

        private static List<BodyStatement> none() {
                return Collections.<BodyStatement>emptyList();
        }

        private static List<BodyStatement> one(BodyStatement v) {
                return Collections.<BodyStatement>singletonList(v);
        }

        private static List<BodyStatement> pair(BodyStatement u, BodyStatement v) {
                List<BodyStatement> l = new ArrayList<BodyStatement>();
                l.add(u);
                l.add(v);
                return Collections.<BodyStatement>unmodifiableList(l);
        }

        private static List<Name> toNameList(List<SourceElement<Name>> names) {
                List<Name> ns = new ArrayList<Name>();
                for (SourceElement<Name> sn : names) {
                        ns.add(sn.element());
                }
                return Collections.unmodifiableList(ns);
        }

        private static List<Name> prependName(Name n, List<Name> names) {
                List<Name> ns = new ArrayList<Name>();
                ns.add(Objects.requireNonNull(n));
                ns.addAll(Objects.requireNonNull(names));
                return Collections.unmodifiableList(ns);
        }

  final public SourceElement<Name> SrcName() throws ParseException {Token t;
    t = jj_consume_token(NAME);
{if ("" != null) return new SourceElement(src(t), Name.fromString(t.image));}
    throw new Error("Missing return statement in function");
}

  final public Name Name() throws ParseException {SourceElement<Name> sn;
    sn = SrcName();
{if ("" != null) return sn.element();}
    throw new Error("Missing return statement in function");
}

  final public SourceElement<StringLiteral> Str() throws ParseException {Token t, u;
        StringBuilder bld;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case LITERAL_STRING:{
      t = jj_consume_token(LITERAL_STRING);
{if ("" != null) return new SourceElement(src(t), StringLiteral.fromString(t.image));}
      break;
      }
    case LL_BEGIN:{
      t = jj_consume_token(LL_BEGIN);
bld = new StringBuilder();
      label_1:
      while (true) {
        u = jj_consume_token(LL_TAIL);
bld.append(u.image);
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case LL_TAIL:{
          ;
          break;
          }
        default:
          jj_la1[0] = jj_gen;
          break label_1;
        }
      }
// skip the closing bracket
                        bld.setLength(bld.length() - t.image.length());

                        {if ("" != null) return new SourceElement(
                                        src(t),
                                        // skip the leading newline if there is one
                                        StringLiteral.verbatim(bld.length() > 0 && bld.charAt(0) == '\n'
                                                        ? bld.substring(1)
                                                        : bld.toString()));}
      break;
      }
    default:
      jj_la1[1] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public SourceElement<Numeral> Num() throws ParseException {Token t;
    t = jj_consume_token(NUMERAL);
{if ("" != null) return new SourceElement(src(t), Numeral.fromString(t.image));}
    throw new Error("Missing return statement in function");
}

// FIXME: remove when done?
  final public void Eof() throws ParseException {
    jj_consume_token(0);
}

  final public Chunk Chunk() throws ParseException {Block b;
    b = Block();
    jj_consume_token(0);
{if ("" != null) return new Chunk(b);}
    throw new Error("Missing return statement in function");
}

  final public Block Block() throws ParseException {List<BodyStatement> ss;
        List<BodyStatement> stats = new ArrayList<BodyStatement>();
        ReturnStatement ret = null;
    label_2:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case BREAK:
      case DO:
      case FOR:
      case FUNCTION:
      case GOTO:
      case IF:
      case LOCAL:
      case REPEAT:
      case WHILE:
      case NAME:
      case PAREN_OPEN:
      case DOUBLE_COLON:
      case SEMICOLON:{
        ;
        break;
        }
      default:
        jj_la1[2] = jj_gen;
        break label_2;
      }
      ss = BodyStatement();
stats.addAll(ss);
    }
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case RETURN:{
      ret = ReturnStatement();
      break;
      }
    default:
      jj_la1[3] = jj_gen;
      ;
    }
{if ("" != null) return new Block(Collections.unmodifiableList(stats), ret);}
    throw new Error("Missing return statement in function");
}

  final public List<BodyStatement> BodyStatement() throws ParseException {Token t, u;

        Name n, m = null;
        Expr e, f;
        Expr g = null;
        Block b;

        FunctionDefExpr fb;

        List<LValueExpr> vars;
        List<SourceElement<Name>> names = new ArrayList<SourceElement<Name>>();
        List<Expr> exprs = Collections.emptyList();

        BodyStatement s;
        List<BodyStatement> ss = new ArrayList<BodyStatement>();

        SourceElement<Name> sn;

        FunctionNameBuilder fnb = null;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SEMICOLON:{
      jj_consume_token(SEMICOLON);
{if ("" != null) return none();}
      break;
      }
    case NAME:
    case PAREN_OPEN:{
      s = AssignOrCall();
{if ("" != null) return one(s);}
      break;
      }
    case DOUBLE_COLON:{
      t = jj_consume_token(DOUBLE_COLON);
      n = Name();
      jj_consume_token(DOUBLE_COLON);
{if ("" != null) return one(Statements.labelStatement(src(t), n));}
      break;
      }
    case BREAK:{
      t = jj_consume_token(BREAK);
{if ("" != null) return one(Statements.breakStatement(src(t)));}
      break;
      }
    case GOTO:{
      t = jj_consume_token(GOTO);
      n = Name();
{if ("" != null) return one(Statements.gotoStatement(src(t), n));}
      break;
      }
    case DO:{
      t = jj_consume_token(DO);
      b = Block();
      jj_consume_token(END);
{if ("" != null) return one(Statements.doStatement(src(t), b));}
      break;
      }
    case WHILE:{
      t = jj_consume_token(WHILE);
      e = Expr();
      jj_consume_token(DO);
      b = Block();
      jj_consume_token(END);
{if ("" != null) return one(Statements.whileStatement(src(t), e, b));}
      break;
      }
    case REPEAT:{
      t = jj_consume_token(REPEAT);
      b = Block();
      jj_consume_token(UNTIL);
      e = Expr();
{if ("" != null) return one(Statements.repeatUntilStatement(src(t), e, b));}
      break;
      }
    case IF:{
      s = IfStatement();
{if ("" != null) return one(s);}
      break;
      }
    default:
      jj_la1[8] = jj_gen;
      if (jj_2_1(3)) {
        t = jj_consume_token(FOR);
        n = Name();
        jj_consume_token(ASSIGN);
        e = Expr();
        jj_consume_token(COMMA);
        f = Expr();
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case COMMA:{
          jj_consume_token(COMMA);
          g = Expr();
          break;
          }
        default:
          jj_la1[4] = jj_gen;
          ;
        }
        jj_consume_token(DO);
        b = Block();
        jj_consume_token(END);
{if ("" != null) return one(Statements.numericForStatement(src(t), n, e, f, g, b));}
      } else {
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case FOR:{
          t = jj_consume_token(FOR);
          names = NameList();
          jj_consume_token(IN);
          exprs = ExprList();
          jj_consume_token(DO);
          b = Block();
          jj_consume_token(END);
{if ("" != null) return one(Statements.genericForStatement(src(t), toNameList(names), exprs, b));}
          break;
          }
        case FUNCTION:{
          t = jj_consume_token(FUNCTION);
          sn = SrcName();
fnb = new FunctionNameBuilder(sn);
          label_3:
          while (true) {
            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
            case DOT:{
              ;
              break;
              }
            default:
              jj_la1[5] = jj_gen;
              break label_3;
            }
            u = jj_consume_token(DOT);
            sn = SrcName();
fnb.addDotName(src(u), sn);
          }
          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
          case COLON:{
            u = jj_consume_token(COLON);
            sn = SrcName();
fnb.addColonName(src(u), sn);
            break;
            }
          default:
            jj_la1[6] = jj_gen;
            ;
          }
          fb = FunctionBody();
{
                        FunctionDefExpr.Params params = fb.params();
                        Block blk = fb.block();

                        if (fnb.isMethod()) {
                                // defining a method: change fb's signature by prepending a "self" field
                                params = params.update(prependName(Name.fromString("self"), params.names()), params.isVararg());
                        }

                        // re-instantiate with adjusted param list and source information
                        fb = Exprs.functionDef(src(t), params, blk);
                }

                {if ("" != null) return one(Statements.assignStatement(src(t), fnb.get(), fb));}
          break;
          }
        default:
          jj_la1[9] = jj_gen;
          if (jj_2_2(2)) {
            t = jj_consume_token(LOCAL);
            u = jj_consume_token(FUNCTION);
            sn = SrcName();
            fb = FunctionBody();
{if ("" != null) return pair(
                                Statements.localDeclStatement(src(t), sn.element()),
                                Statements.assignStatement(src(t),
                                                Collections.<LValueExpr>singletonList(Exprs.var(sn.sourceInfo(), sn.element())),
                                                Collections.<Expr>singletonList(Exprs.functionDef(src(u), fb.params(), fb.block()))));}
          } else {
            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
            case LOCAL:{
              t = jj_consume_token(LOCAL);
              names = NameList();
              switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
              case ASSIGN:{
                jj_consume_token(ASSIGN);
                exprs = ExprList();
                break;
                }
              default:
                jj_la1[7] = jj_gen;
                ;
              }
{if ("" != null) return one(Statements.localDeclStatement(src(t), toNameList(names), exprs));}
              break;
              }
            default:
              jj_la1[10] = jj_gen;
              jj_consume_token(-1);
              throw new ParseException();
            }
          }
        }
      }
    }
    throw new Error("Missing return statement in function");
}

  final public Expr Expr() throws ParseException {SourceElement<Operator.Unary> uop;
        SourceElement<Operator.Binary> bop;
        Expr e;

        ExprBuilder bld = new ExprBuilder();
    label_4:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case NOT:
      case MINUS:
      case LEN:
      case BNOT:{
        ;
        break;
        }
      default:
        jj_la1[11] = jj_gen;
        break label_4;
      }
      uop = UnOp();
bld.addOp(uop.sourceInfo(), uop.element());
    }
    e = SimpleExpr();
bld.addExpr(e);
    label_5:
    while (true) {
      if (jj_2_3(2)) {
        ;
      } else {
        break label_5;
      }
      bop = BinOp();
bld.addOp(bop.sourceInfo(), bop.element());
      label_6:
      while (true) {
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case NOT:
        case MINUS:
        case LEN:
        case BNOT:{
          ;
          break;
          }
        default:
          jj_la1[12] = jj_gen;
          break label_6;
        }
        uop = UnOp();
bld.addOp(uop.sourceInfo(), uop.element());
      }
      e = SimpleExpr();
bld.addExpr(e);
    }
{if ("" != null) return bld.build();}
    throw new Error("Missing return statement in function");
}

  final public Expr SimpleExpr() throws ParseException {Token t;
        SourceElement<StringLiteral> ss;
        SourceElement<Numeral> sn;
        Expr e;
        FunctionDefExpr fn;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case NIL:{
      t = jj_consume_token(NIL);
{if ("" != null) return Exprs.literal(src(t), NilLiteral.INSTANCE);}
      break;
      }
    case FALSE:{
      t = jj_consume_token(FALSE);
{if ("" != null) return Exprs.literal(src(t), BooleanLiteral.FALSE);}
      break;
      }
    case TRUE:{
      t = jj_consume_token(TRUE);
{if ("" != null) return Exprs.literal(src(t), BooleanLiteral.TRUE);}
      break;
      }
    case NUMERAL:{
      sn = Num();
{if ("" != null) return Exprs.literal(sn.sourceInfo(), sn.element());}
      break;
      }
    case LL_BEGIN:
    case LITERAL_STRING:{
      ss = Str();
{if ("" != null) return Exprs.literal(ss.sourceInfo(), ss.element());}
      break;
      }
    case VARARGS:{
      t = jj_consume_token(VARARGS);
{if ("" != null) return Exprs.varargs(src(t));}
      break;
      }
    case FUNCTION:{
      t = jj_consume_token(FUNCTION);
      fn = FunctionBody();
{if ("" != null) return Exprs.functionDef(src(t), fn.params(), fn.block());}
      break;
      }
    case NAME:
    case PAREN_OPEN:{
      e = PrefixExpr();
{if ("" != null) return e;}
      break;
      }
    case CURLY_OPEN:{
      e = TableConstructor();
{if ("" != null) return e;}
      break;
      }
    default:
      jj_la1[13] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public Expr PrefixExpr() throws ParseException {Expr e;
        PostfixOp op;
    e = VarExpr();
    label_7:
    while (true) {
      if (jj_2_4(2)) {
        ;
      } else {
        break label_7;
      }
      op = __PostfixOp();
e=op.on(e);
    }
{if ("" != null) return e;}
    throw new Error("Missing return statement in function");
}

  final public Expr VarExpr() throws ParseException {SourceElement<Name> sn;
        Expr e;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case NAME:{
      sn = SrcName();
{if ("" != null) return Exprs.var(sn.sourceInfo(), sn.element());}
      break;
      }
    case PAREN_OPEN:{
      jj_consume_token(PAREN_OPEN);
      e = Expr();
      jj_consume_token(PAREN_CLOSE);
{if ("" != null) return Exprs.paren(e);}
      break;
      }
    default:
      jj_la1[14] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public PostfixOp __PostfixOp() throws ParseException {PostfixOp op;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SQUARE_OPEN:
    case DOT:{
      op = __FieldAccessOp();
{if ("" != null) return op;}
      break;
      }
    case LL_BEGIN:
    case LITERAL_STRING:
    case PAREN_OPEN:
    case CURLY_OPEN:
    case COLON:{
      op = __InvokeOp();
{if ("" != null) return op;}
      break;
      }
    default:
      jj_la1[15] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public BodyStatement AssignOrCall() throws ParseException {Expr e;
        AssignRest ar;
    e = PrefixExpr();
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case ASSIGN:
    case COMMA:{
      ar = AssignOrCallRest();
if (e instanceof LValueExpr) {
                                {if ("" != null) return ar.prepend((LValueExpr) e);}
                        }
                        else {
                                {if (true) throw new ParseException("lvalue expected at line " + e.line());}
                        }
      break;
      }
    default:
      jj_la1[16] = jj_gen;
      ;
    }
if (e instanceof CallExpr) {
                        CallExpr ce = (CallExpr) e;
                        {if ("" != null) return Statements.callStatement(ce.sourceInfo(), ce);}
                }
                else {
                        {if (true) throw new ParseException("function call expected at line " + e.line());}
                }
    throw new Error("Missing return statement in function");
}

  final public AssignRest AssignOrCallRest() throws ParseException {Token t;
        LValueExpr v;
        List<LValueExpr> vs = new ArrayList<LValueExpr>();
        List<Expr> es;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case ASSIGN:{
      // single assignment
              t = jj_consume_token(ASSIGN);
      es = ExprList();
{if ("" != null) return new AssignRest(src(t), es);}
      break;
      }
    case COMMA:{
      label_8:
      while (true) {
        jj_consume_token(COMMA);
        v = LValue();
vs.add(v);
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case COMMA:{
          ;
          break;
          }
        default:
          jj_la1[17] = jj_gen;
          break label_8;
        }
      }
      t = jj_consume_token(ASSIGN);
      es = ExprList();
{if ("" != null) return new AssignRest(src(t), Collections.unmodifiableList(vs), es);}
      break;
      }
    default:
      jj_la1[18] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public LValueExpr LValue() throws ParseException {SourceElement<Name> sn;
        Expr e;
//	PostfixOp.FieldAccess fa;

    //	LOOKAHEAD(2) sn=SrcName()  { return Exprs.var(sn.sourceInfo(), sn.element()); }
    //|	e=PrefixExpr() fa=__FieldAccessOp()  { return fa.on(e); }
    
            // FIXME: restrict this using syntactic rule instead
            e = PrefixExpr();
if (e instanceof LValueExpr) {if ("" != null) return (LValueExpr) e;} else {if (true) throw new ParseException("lvalue expected");}
    throw new Error("Missing return statement in function");
}

  final public SourceElement<List<Expr>> Args() throws ParseException {Token t;
        Expr e;
        SourceElement<StringLiteral> ss;
        List<Expr> es = Collections.emptyList();
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case PAREN_OPEN:{
      t = jj_consume_token(PAREN_OPEN);
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case LL_BEGIN:
      case FALSE:
      case FUNCTION:
      case NIL:
      case NOT:
      case TRUE:
      case NAME:
      case NUMERAL:
      case LITERAL_STRING:
      case MINUS:
      case LEN:
      case BNOT:
      case PAREN_OPEN:
      case CURLY_OPEN:
      case VARARGS:{
        es = ExprList();
        break;
        }
      default:
        jj_la1[19] = jj_gen;
        ;
      }
      jj_consume_token(PAREN_CLOSE);
{if ("" != null) return new SourceElement<List<Expr>>(src(t), es);}
      break;
      }
    case CURLY_OPEN:{
      e = TableConstructor();
{if ("" != null) return new SourceElement<List<Expr>>(e.sourceInfo(), Collections.<Expr>singletonList(e));}
      break;
      }
    case LL_BEGIN:
    case LITERAL_STRING:{
      ss = Str();
{if ("" != null) return new SourceElement<List<Expr>>(ss.sourceInfo(), Collections.<Expr>singletonList(Exprs.literal(ss.sourceInfo(), ss.element())));}
      break;
      }
    default:
      jj_la1[20] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public IfStatement IfStatement() throws ParseException {Token t;
        Expr e;
        Block b;
        ConditionalBlock ift;
        ArrayList<ConditionalBlock> elifs = new ArrayList<ConditionalBlock>();
        Block els = null;
    t = jj_consume_token(IF);
    e = Expr();
    jj_consume_token(THEN);
    b = Block();
ift = new ConditionalBlock(e, b);
    label_9:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case ELSEIF:{
        ;
        break;
        }
      default:
        jj_la1[21] = jj_gen;
        break label_9;
      }
      jj_consume_token(ELSEIF);
      e = Expr();
      jj_consume_token(THEN);
      b = Block();
elifs.add(new ConditionalBlock(e, b));
    }
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case ELSE:{
      jj_consume_token(ELSE);
      els = Block();
      break;
      }
    default:
      jj_la1[22] = jj_gen;
      ;
    }
    jj_consume_token(END);
{if ("" != null) return Statements.ifStatement(src(t), ift, elifs, els);}
    throw new Error("Missing return statement in function");
}

/*
	retstat ::= return [explist] [â€?;â€™]
*/
  final public ReturnStatement ReturnStatement() throws ParseException {Token t;
        List<Expr> exprs = Collections.emptyList();
    t = jj_consume_token(RETURN);
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case LL_BEGIN:
    case FALSE:
    case FUNCTION:
    case NIL:
    case NOT:
    case TRUE:
    case NAME:
    case NUMERAL:
    case LITERAL_STRING:
    case MINUS:
    case LEN:
    case BNOT:
    case PAREN_OPEN:
    case CURLY_OPEN:
    case VARARGS:{
      exprs = ExprList();
      break;
      }
    default:
      jj_la1[23] = jj_gen;
      ;
    }
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SEMICOLON:{
      jj_consume_token(SEMICOLON);
      break;
      }
    default:
      jj_la1[24] = jj_gen;
      ;
    }
{if ("" != null) return Statements.returnStatement(src(t), exprs);}
    throw new Error("Missing return statement in function");
}

  final public PostfixOp.FieldAccess __FieldAccessOp() throws ParseException {Token t;
        Expr e;
        SourceElement<Name> sn;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SQUARE_OPEN:{
      t = jj_consume_token(SQUARE_OPEN);
      e = Expr();
      jj_consume_token(SQUARE_CLOSE);
{if ("" != null) return new PostfixOp.FieldAccess(src(t), e);}
      break;
      }
    case DOT:{
      t = jj_consume_token(DOT);
      sn = SrcName();
{if ("" != null) return new PostfixOp.FieldAccess(src(t), Exprs.literal(sn.sourceInfo(), StringLiteral.fromName(sn.element())));}
      break;
      }
    default:
      jj_la1[25] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public PostfixOp.Invoke __InvokeOp() throws ParseException {Name n;
        SourceElement<List<Expr>> args;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case LL_BEGIN:
    case LITERAL_STRING:
    case PAREN_OPEN:
    case CURLY_OPEN:{
      args = Args();
{if ("" != null) return new PostfixOp.Invoke(args, null);}
      break;
      }
    case COLON:{
      jj_consume_token(COLON);
      n = Name();
      args = Args();
{if ("" != null) return new PostfixOp.Invoke(args, n);}
      break;
      }
    default:
      jj_la1[26] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public List<SourceElement<Name>> NameList() throws ParseException {SourceElement<Name> n;
        ArrayList<SourceElement<Name>> ns = new ArrayList<SourceElement<Name>>();
    n = SrcName();
ns.add(n);
    label_10:
    while (true) {
      if (jj_2_5(2)) {
        ;
      } else {
        break label_10;
      }
      jj_consume_token(COMMA);
      n = SrcName();
ns.add(n);
    }
{if ("" != null) return Collections.unmodifiableList(ns);}
    throw new Error("Missing return statement in function");
}

  final public List<Expr> ExprList() throws ParseException {Expr e;
        ArrayList<Expr> es = new ArrayList<Expr>();
    e = Expr();
es.add(e);
    label_11:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case COMMA:{
        ;
        break;
        }
      default:
        jj_la1[27] = jj_gen;
        break label_11;
      }
      jj_consume_token(COMMA);
      e = Expr();
es.add(e);
    }
{if ("" != null) return Collections.unmodifiableList(es);}
    throw new Error("Missing return statement in function");
}

  final public FunctionDefExpr FunctionBody() throws ParseException {Token t;
        FunctionDefExpr.Params params = FunctionDefExpr.Params.empty();
        Block block;
    t = jj_consume_token(PAREN_OPEN);
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case NAME:
    case VARARGS:{
      params = FunctionParams();
      break;
      }
    default:
      jj_la1[28] = jj_gen;
      ;
    }
    jj_consume_token(PAREN_CLOSE);
    block = Block();
    jj_consume_token(END);
{if ("" != null) return Exprs.functionDef(src(t), params, block);}
    throw new Error("Missing return statement in function");
}

  final public FunctionDefExpr.Params FunctionParams() throws ParseException {List<SourceElement<Name>> params;
        boolean vararg = false;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case NAME:{
      params = NameList();
      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
      case COMMA:{
        jj_consume_token(COMMA);
        jj_consume_token(VARARGS);
vararg = true;
        break;
        }
      default:
        jj_la1[29] = jj_gen;
        ;
      }
{if ("" != null) return new FunctionDefExpr.Params(toNameList(params), vararg);}
      break;
      }
    case VARARGS:{
      jj_consume_token(VARARGS);
{if ("" != null) return new FunctionDefExpr.Params(Collections.<Name>emptyList(), true);}
      break;
      }
    default:
      jj_la1[30] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  final public TableConstructorExpr TableConstructor() throws ParseException {Token t;
        TableConstructorExpr.FieldInitialiser fi;
        List<TableConstructorExpr.FieldInitialiser> fields = new ArrayList<TableConstructorExpr.FieldInitialiser>();
    t = jj_consume_token(CURLY_OPEN);
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case LL_BEGIN:
    case FALSE:
    case FUNCTION:
    case NIL:
    case NOT:
    case TRUE:
    case NAME:
    case NUMERAL:
    case LITERAL_STRING:
    case MINUS:
    case LEN:
    case BNOT:
    case PAREN_OPEN:
    case CURLY_OPEN:
    case SQUARE_OPEN:
    case VARARGS:{
      fields = FieldInitialiserList();
      break;
      }
    default:
      jj_la1[31] = jj_gen;
      ;
    }
    jj_consume_token(CURLY_CLOSE);
{if ("" != null) return Exprs.tableConstructor(src(t), fields);}
    throw new Error("Missing return statement in function");
}

  final public void FieldSeparator() throws ParseException {
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case COMMA:{
      jj_consume_token(COMMA);
      break;
      }
    case SEMICOLON:{
      jj_consume_token(SEMICOLON);
      break;
      }
    default:
      jj_la1[32] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
}

  final public List<TableConstructorExpr.FieldInitialiser> FieldInitialiserList() throws ParseException {TableConstructorExpr.FieldInitialiser f;
        ArrayList<TableConstructorExpr.FieldInitialiser> fs = new ArrayList<TableConstructorExpr.FieldInitialiser>();
    f = FieldInitialiser();
fs.add(f);
    label_12:
    while (true) {
      if (jj_2_6(2)) {
        ;
      } else {
        break label_12;
      }
      FieldSeparator();
      f = FieldInitialiser();
fs.add(f);
    }
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SEMICOLON:
    case COMMA:{
      FieldSeparator();
      break;
      }
    default:
      jj_la1[33] = jj_gen;
      ;
    }
{if ("" != null) return Collections.unmodifiableList(fs);}
    throw new Error("Missing return statement in function");
}

  final public TableConstructorExpr.FieldInitialiser FieldInitialiser() throws ParseException {Expr e, f;
        SourceElement<Name> sn;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case SQUARE_OPEN:{
      jj_consume_token(SQUARE_OPEN);
      e = Expr();
      jj_consume_token(SQUARE_CLOSE);
      jj_consume_token(ASSIGN);
      f = Expr();
{if ("" != null) return Exprs.fieldInitialiser(e, f);}
      break;
      }
    default:
      jj_la1[34] = jj_gen;
      if (jj_2_7(2)) {
        sn = SrcName();
        jj_consume_token(ASSIGN);
        e = Expr();
{if ("" != null) return Exprs.fieldInitialiser(Exprs.literal(sn.sourceInfo(), StringLiteral.fromName(sn.element())), e);}
      } else {
        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
        case LL_BEGIN:
        case FALSE:
        case FUNCTION:
        case NIL:
        case NOT:
        case TRUE:
        case NAME:
        case NUMERAL:
        case LITERAL_STRING:
        case MINUS:
        case LEN:
        case BNOT:
        case PAREN_OPEN:
        case CURLY_OPEN:
        case VARARGS:{
          e = Expr();
{if ("" != null) return Exprs.fieldInitialiser(null, e);}
          break;
          }
        default:
          jj_la1[35] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
      }
    }
    throw new Error("Missing return statement in function");
}

/*
	binop ::=  â€?+â€™ | â€?-â€™ | â€?*â€™ | â€?/â€™ | â€?//â€™ | â€?^â€™ | â€?%â€™ |
		 â€?&â€™ | â€?~â€™ | â€?|â€™ | â€?>>â€™ | â€?<<â€™ | â€?..â€™ |
		 â€?<â€™ | â€?<=â€™ | â€?>â€™ | â€?>=â€™ | â€?==â€™ | â€?~=â€™ |
		 and | or
*/
  final public SourceElement<Operator.Binary> BinOp() throws ParseException {Token t;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case PLUS:{
      t = jj_consume_token(PLUS);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.ADD);}
      break;
      }
    case MINUS:{
      t = jj_consume_token(MINUS);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.SUB);}
      break;
      }
    case MUL:{
      t = jj_consume_token(MUL);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.MUL);}
      break;
      }
    case DIV:{
      t = jj_consume_token(DIV);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.DIV);}
      break;
      }
    case IDIV:{
      t = jj_consume_token(IDIV);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.IDIV);}
      break;
      }
    case POW:{
      t = jj_consume_token(POW);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.POW);}
      break;
      }
    case MOD:{
      t = jj_consume_token(MOD);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.MOD);}
      break;
      }
    case BAND:{
      t = jj_consume_token(BAND);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.BAND);}
      break;
      }
    case BNOT:{
      t = jj_consume_token(BNOT);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.BXOR);}
      break;
      }
    case BOR:{
      t = jj_consume_token(BOR);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.BOR);}
      break;
      }
    case SHR:{
      t = jj_consume_token(SHR);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.SHR);}
      break;
      }
    case SHL:{
      t = jj_consume_token(SHL);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.SHL);}
      break;
      }
    case DBL_DOT:{
      t = jj_consume_token(DBL_DOT);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.CONCAT);}
      break;
      }
    case LT:{
      t = jj_consume_token(LT);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.LT);}
      break;
      }
    case LE:{
      t = jj_consume_token(LE);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.LE);}
      break;
      }
    case GT:{
      t = jj_consume_token(GT);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.GT);}
      break;
      }
    case GE:{
      t = jj_consume_token(GE);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.GE);}
      break;
      }
    case EQ:{
      t = jj_consume_token(EQ);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.EQ);}
      break;
      }
    case NEQ:{
      t = jj_consume_token(NEQ);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.NEQ);}
      break;
      }
    case AND:{
      t = jj_consume_token(AND);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.AND);}
      break;
      }
    case OR:{
      t = jj_consume_token(OR);
{if ("" != null) return SourceElement.of(src(t), Operator.Binary.OR);}
      break;
      }
    default:
      jj_la1[36] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

/*
	unop ::= â€?-â€™ | not | â€?#â€™ | â€?~â€™
*/
  final public SourceElement<Operator.Unary> UnOp() throws ParseException {Token t;
    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
    case MINUS:{
      t = jj_consume_token(MINUS);
{if ("" != null) return SourceElement.of(src(t), Operator.Unary.UNM);}
      break;
      }
    case NOT:{
      t = jj_consume_token(NOT);
{if ("" != null) return SourceElement.of(src(t), Operator.Unary.NOT);}
      break;
      }
    case LEN:{
      t = jj_consume_token(LEN);
{if ("" != null) return SourceElement.of(src(t), Operator.Unary.LEN);}
      break;
      }
    case BNOT:{
      t = jj_consume_token(BNOT);
{if ("" != null) return SourceElement.of(src(t), Operator.Unary.BNOT);}
      break;
      }
    default:
      jj_la1[37] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
}

  private boolean jj_2_1(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_1()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(0, xla); }
  }

  private boolean jj_2_2(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_2()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(1, xla); }
  }

  private boolean jj_2_3(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_3()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(2, xla); }
  }

  private boolean jj_2_4(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_4()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(3, xla); }
  }

  private boolean jj_2_5(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_5()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(4, xla); }
  }

  private boolean jj_2_6(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_6()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(5, xla); }
  }

  private boolean jj_2_7(int xla)
 {
    jj_la = xla; jj_lastpos = jj_scanpos = token;
    try { return (!jj_3_7()); }
    catch(LookaheadSuccess ls) { return true; }
    finally { jj_save(6, xla); }
  }

  private boolean jj_3R_UnOp_753_9_59()
 {
    if (jj_scan_token(BNOT)) return true;
    return false;
  }

  private boolean jj_3R_UnOp_752_9_58()
 {
    if (jj_scan_token(LEN)) return true;
    return false;
  }

  private boolean jj_3R_UnOp_751_9_57()
 {
    if (jj_scan_token(NOT)) return true;
    return false;
  }

  private boolean jj_3R_UnOp_750_9_42()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_UnOp_750_9_56()) {
    jj_scanpos = xsp;
    if (jj_3R_UnOp_751_9_57()) {
    jj_scanpos = xsp;
    if (jj_3R_UnOp_752_9_58()) {
    jj_scanpos = xsp;
    if (jj_3R_UnOp_753_9_59()) return true;
    }
    }
    }
    return false;
  }

  private boolean jj_3R_UnOp_750_9_56()
 {
    if (jj_scan_token(MINUS)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_739_9_41()
 {
    if (jj_scan_token(OR)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_738_9_40()
 {
    if (jj_scan_token(AND)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_737_9_39()
 {
    if (jj_scan_token(NEQ)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_736_9_38()
 {
    if (jj_scan_token(EQ)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_735_9_37()
 {
    if (jj_scan_token(GE)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_734_9_36()
 {
    if (jj_scan_token(GT)) return true;
    return false;
  }

  private boolean jj_3R_Str_306_54_85()
 {
    if (jj_scan_token(LL_TAIL)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_733_9_35()
 {
    if (jj_scan_token(LE)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_732_9_34()
 {
    if (jj_scan_token(LT)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_731_9_33()
 {
    if (jj_scan_token(DBL_DOT)) return true;
    return false;
  }

  private boolean jj_3_6()
 {
    if (jj_3R_FieldSeparator_684_9_19()) return true;
    if (jj_3R_FieldInitialiser_703_9_20()) return true;
    return false;
  }

  private boolean jj_3R_BinOp_730_9_32()
 {
    if (jj_scan_token(SHL)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_729_9_31()
 {
    if (jj_scan_token(SHR)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_728_9_30()
 {
    if (jj_scan_token(BOR)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_727_9_29()
 {
    if (jj_scan_token(BNOT)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_726_9_28()
 {
    if (jj_scan_token(BAND)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_725_9_27()
 {
    if (jj_scan_token(MOD)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_724_9_26()
 {
    if (jj_scan_token(POW)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_723_9_25()
 {
    if (jj_scan_token(IDIV)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_722_9_24()
 {
    if (jj_scan_token(DIV)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_721_9_23()
 {
    if (jj_scan_token(MUL)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_720_9_22()
 {
    if (jj_scan_token(MINUS)) return true;
    return false;
  }

  private boolean jj_3R_BinOp_719_9_14()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_BinOp_719_9_21()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_720_9_22()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_721_9_23()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_722_9_24()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_723_9_25()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_724_9_26()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_725_9_27()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_726_9_28()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_727_9_29()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_728_9_30()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_729_9_31()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_730_9_32()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_731_9_33()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_732_9_34()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_733_9_35()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_734_9_36()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_735_9_37()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_736_9_38()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_737_9_39()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_738_9_40()) {
    jj_scanpos = xsp;
    if (jj_3R_BinOp_739_9_41()) return true;
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    return false;
  }

  private boolean jj_3R_BinOp_719_9_21()
 {
    if (jj_scan_token(PLUS)) return true;
    return false;
  }

  private boolean jj_3R_Num_325_9_60()
 {
    if (jj_scan_token(NUMERAL)) return true;
    return false;
  }

  private boolean jj_3R_FieldInitialiser_705_9_55()
 {
    if (jj_3R_Expr_457_9_66()) return true;
    return false;
  }

  private boolean jj_3_7()
 {
    if (jj_3R_SrcName_288_9_18()) return true;
    if (jj_scan_token(ASSIGN)) return true;
    return false;
  }

  private boolean jj_3R_FieldInitialiser_703_9_20()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_FieldInitialiser_703_9_54()) {
    jj_scanpos = xsp;
    if (jj_3_7()) {
    jj_scanpos = xsp;
    if (jj_3R_FieldInitialiser_705_9_55()) return true;
    }
    }
    return false;
  }

  private boolean jj_3R_FieldInitialiser_703_9_54()
 {
    if (jj_scan_token(SQUARE_OPEN)) return true;
    return false;
  }

  private boolean jj_3R___PostfixOp_510_9_53()
 {
    if (jj_3R___InvokeOp_628_9_65()) return true;
    return false;
  }

  private boolean jj_3R___PostfixOp_509_9_17()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R___PostfixOp_509_9_52()) {
    jj_scanpos = xsp;
    if (jj_3R___PostfixOp_510_9_53()) return true;
    }
    return false;
  }

  private boolean jj_3R___PostfixOp_509_9_52()
 {
    if (jj_3R___FieldAccessOp_619_9_64()) return true;
    return false;
  }

  private boolean jj_3_4()
 {
    if (jj_3R___PostfixOp_509_9_17()) return true;
    return false;
  }

  private boolean jj_3R_FieldInitialiserList_694_9_84()
 {
    if (jj_3R_FieldInitialiser_703_9_20()) return true;
    return false;
  }

  private boolean jj_3R_TableConstructor_678_25_83()
 {
    if (jj_3R_FieldInitialiserList_694_9_84()) return true;
    return false;
  }

  private boolean jj_3R_VarExpr_501_9_76()
 {
    if (jj_scan_token(PAREN_OPEN)) return true;
    return false;
  }

  private boolean jj_3R_VarExpr_500_9_69()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_VarExpr_500_9_75()) {
    jj_scanpos = xsp;
    if (jj_3R_VarExpr_501_9_76()) return true;
    }
    return false;
  }

  private boolean jj_3R_VarExpr_500_9_75()
 {
    if (jj_3R_SrcName_288_9_18()) return true;
    return false;
  }

  private boolean jj_3R_Str_306_9_68()
 {
    if (jj_scan_token(LL_BEGIN)) return true;
    Token xsp;
    if (jj_3R_Str_306_54_85()) return true;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_Str_306_54_85()) { jj_scanpos = xsp; break; }
    }
    return false;
  }

  private boolean jj_3R_Str_305_9_61()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_Str_305_9_67()) {
    jj_scanpos = xsp;
    if (jj_3R_Str_306_9_68()) return true;
    }
    return false;
  }

  private boolean jj_3R_Str_305_9_67()
 {
    if (jj_scan_token(LITERAL_STRING)) return true;
    return false;
  }

  private boolean jj_3R_Expr_460_42_15()
 {
    if (jj_3R_UnOp_750_9_42()) return true;
    return false;
  }

  private boolean jj_3R_FieldSeparator_684_9_19()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_scan_token(92)) {
    jj_scanpos = xsp;
    if (jj_scan_token(90)) return true;
    }
    return false;
  }

  private boolean jj_3R_PrefixExpr_491_9_62()
 {
    if (jj_3R_VarExpr_500_9_69()) return true;
    return false;
  }

  private boolean jj_3R_Name_296_9_13()
 {
    if (jj_3R_SrcName_288_9_18()) return true;
    return false;
  }

  private boolean jj_3R_TableConstructor_678_9_63()
 {
    if (jj_scan_token(CURLY_OPEN)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_TableConstructor_678_25_83()) jj_scanpos = xsp;
    if (jj_scan_token(CURLY_CLOSE)) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_482_9_51()
 {
    if (jj_3R_TableConstructor_678_9_63()) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_481_9_50()
 {
    if (jj_3R_PrefixExpr_491_9_62()) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_480_9_49()
 {
    if (jj_scan_token(FUNCTION)) return true;
    return false;
  }

  private boolean jj_3R_SrcName_288_9_18()
 {
    if (jj_scan_token(NAME)) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_479_9_48()
 {
    if (jj_scan_token(VARARGS)) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_478_9_47()
 {
    if (jj_3R_Str_305_9_61()) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_477_9_46()
 {
    if (jj_3R_Num_325_9_60()) return true;
    return false;
  }

  private boolean jj_3_3()
 {
    if (jj_3R_BinOp_719_9_14()) return true;
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_Expr_460_42_15()) { jj_scanpos = xsp; break; }
    }
    if (jj_3R_SimpleExpr_474_9_16()) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_476_9_45()
 {
    if (jj_scan_token(TRUE)) return true;
    return false;
  }

  private boolean jj_3_5()
 {
    if (jj_scan_token(COMMA)) return true;
    if (jj_3R_SrcName_288_9_18()) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_475_9_44()
 {
    if (jj_scan_token(FALSE)) return true;
    return false;
  }

  private boolean jj_3R_SimpleExpr_474_9_16()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_SimpleExpr_474_9_43()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_475_9_44()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_476_9_45()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_477_9_46()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_478_9_47()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_479_9_48()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_480_9_49()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_481_9_50()) {
    jj_scanpos = xsp;
    if (jj_3R_SimpleExpr_482_9_51()) return true;
    }
    }
    }
    }
    }
    }
    }
    }
    return false;
  }

  private boolean jj_3R_SimpleExpr_474_9_43()
 {
    if (jj_scan_token(NIL)) return true;
    return false;
  }

  private boolean jj_3R_Expr_457_10_74()
 {
    if (jj_3R_UnOp_750_9_42()) return true;
    return false;
  }

  private boolean jj_3R_ExprList_648_9_82()
 {
    if (jj_3R_Expr_457_9_66()) return true;
    return false;
  }

  private boolean jj_3R_Expr_457_9_66()
 {
    Token xsp;
    while (true) {
      xsp = jj_scanpos;
      if (jj_3R_Expr_457_10_74()) { jj_scanpos = xsp; break; }
    }
    if (jj_3R_SimpleExpr_474_9_16()) return true;
    return false;
  }

  private boolean jj_3R___InvokeOp_629_9_73()
 {
    if (jj_scan_token(COLON)) return true;
    if (jj_3R_Name_296_9_13()) return true;
    return false;
  }

  private boolean jj_3R___InvokeOp_628_9_65()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R___InvokeOp_628_9_72()) {
    jj_scanpos = xsp;
    if (jj_3R___InvokeOp_629_9_73()) return true;
    }
    return false;
  }

  private boolean jj_3R___InvokeOp_628_9_72()
 {
    if (jj_3R_Args_579_9_77()) return true;
    return false;
  }

  private boolean jj_3_2()
 {
    if (jj_scan_token(LOCAL)) return true;
    if (jj_scan_token(FUNCTION)) return true;
    return false;
  }

  private boolean jj_3R___FieldAccessOp_620_9_71()
 {
    if (jj_scan_token(DOT)) return true;
    if (jj_3R_SrcName_288_9_18()) return true;
    return false;
  }

  private boolean jj_3R___FieldAccessOp_619_9_64()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R___FieldAccessOp_619_9_70()) {
    jj_scanpos = xsp;
    if (jj_3R___FieldAccessOp_620_9_71()) return true;
    }
    return false;
  }

  private boolean jj_3R___FieldAccessOp_619_9_70()
 {
    if (jj_scan_token(SQUARE_OPEN)) return true;
    if (jj_3R_Expr_457_9_66()) return true;
    return false;
  }

  private boolean jj_3R_Args_579_25_81()
 {
    if (jj_3R_ExprList_648_9_82()) return true;
    return false;
  }

  private boolean jj_3_1()
 {
    if (jj_scan_token(FOR)) return true;
    if (jj_3R_Name_296_9_13()) return true;
    if (jj_scan_token(ASSIGN)) return true;
    return false;
  }

  private boolean jj_3R_Args_581_9_80()
 {
    if (jj_3R_Str_305_9_61()) return true;
    return false;
  }

  private boolean jj_3R_Args_580_9_79()
 {
    if (jj_3R_TableConstructor_678_9_63()) return true;
    return false;
  }

  private boolean jj_3R_Args_579_9_78()
 {
    if (jj_scan_token(PAREN_OPEN)) return true;
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_Args_579_25_81()) jj_scanpos = xsp;
    if (jj_scan_token(PAREN_CLOSE)) return true;
    return false;
  }

  private boolean jj_3R_Args_579_9_77()
 {
    Token xsp;
    xsp = jj_scanpos;
    if (jj_3R_Args_579_9_78()) {
    jj_scanpos = xsp;
    if (jj_3R_Args_580_9_79()) {
    jj_scanpos = xsp;
    if (jj_3R_Args_581_9_80()) return true;
    }
    }
    return false;
  }

  /** Generated Token Manager. */
  public ParserTokenManager token_source;
  SimpleCharStream jj_input_stream;
  /** Current token. */
  public Token token;
  /** Next token. */
  public Token jj_nt;
  private int jj_ntk;
  private Token jj_scanpos, jj_lastpos;
  private int jj_la;
  private int jj_gen;
  final private int[] jj_la1 = new int[38];
  static private int[] jj_la1_0;
  static private int[] jj_la1_1;
  static private int[] jj_la1_2;
  static {
	   jj_la1_init_0();
	   jj_la1_init_1();
	   jj_la1_init_2();
	}
	private static void jj_la1_init_0() {
	   jj_la1_0 = new int[] {0x400,0x40,0x78600000,0x0,0x0,0x0,0x0,0x0,0x60600000,0x18000000,0x0,0x0,0x0,0x14000040,0x0,0x40,0x0,0x0,0x0,0x14000040,0x40,0x1000000,0x800000,0x14000040,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x14000040,0x0,0x0,0x0,0x14000040,0x100000,0x0,};
	}
	private static void jj_la1_init_1() {
	   jj_la1_1 = new int[] {0x0,0x100000,0x611,0x20,0x0,0x0,0x0,0x0,0x610,0x0,0x1,0x80000004,0x80000004,0x100c82,0x400,0x100000,0x0,0x0,0x0,0x80100c86,0x100000,0x0,0x0,0x80100c86,0x0,0x0,0x100000,0x0,0x400,0x0,0x400,0x80100c86,0x0,0x0,0x0,0x80100c86,0xc0000008,0x80000004,};
	}
	private static void jj_la1_init_2() {
	   jj_la1_2 = new int[] {0x0,0x0,0x6080000,0x0,0x10000000,0x20000000,0x8000000,0x40000,0x6080000,0x0,0x0,0x50,0x50,0x40280000,0x80000,0x28a80000,0x10040000,0x10000000,0x10040000,0x40280050,0x280000,0x0,0x0,0x40280050,0x4000000,0x20800000,0x8280000,0x10000000,0x40000000,0x10000000,0x40000000,0x40a80050,0x14000000,0x14000000,0x800000,0x40280050,0x3ffef,0x50,};
	}
  final private JJCalls[] jj_2_rtns = new JJCalls[7];
  private boolean jj_rescan = false;
  private int jj_gc = 0;

  /** Constructor with InputStream. */
  public Parser(java.io.InputStream stream) {
	  this(stream, null);
  }
  /** Constructor with InputStream and supplied encoding */
  public Parser(java.io.InputStream stream, String encoding) {
	 try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
	 token_source = new ParserTokenManager(jj_input_stream);
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(java.io.InputStream stream) {
	  ReInit(stream, null);
  }
  /** Reinitialise. */
  public void ReInit(java.io.InputStream stream, String encoding) {
	 try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
	 token_source.ReInit(jj_input_stream);
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Constructor. */
  public Parser(java.io.Reader stream) {
	 jj_input_stream = new SimpleCharStream(stream, 1, 1);
	 token_source = new ParserTokenManager(jj_input_stream);
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(java.io.Reader stream) {
	if (jj_input_stream == null) {
	   jj_input_stream = new SimpleCharStream(stream, 1, 1);
	} else {
	   jj_input_stream.ReInit(stream, 1, 1);
	}
	if (token_source == null) {
 token_source = new ParserTokenManager(jj_input_stream);
	}

	 token_source.ReInit(jj_input_stream);
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Constructor with generated Token Manager. */
  public Parser(ParserTokenManager tm) {
	 token_source = tm;
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  /** Reinitialise. */
  public void ReInit(ParserTokenManager tm) {
	 token_source = tm;
	 token = new Token();
	 jj_ntk = -1;
	 jj_gen = 0;
	 for (int i = 0; i < 38; i++) jj_la1[i] = -1;
	 for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
  }

  private Token jj_consume_token(int kind) throws ParseException {
	 Token oldToken;
	 if ((oldToken = token).next != null) token = token.next;
	 else token = token.next = token_source.getNextToken();
	 jj_ntk = -1;
	 if (token.kind == kind) {
	   jj_gen++;
	   if (++jj_gc > 100) {
		 jj_gc = 0;
		 for (int i = 0; i < jj_2_rtns.length; i++) {
		   JJCalls c = jj_2_rtns[i];
		   while (c != null) {
			 if (c.gen < jj_gen) c.first = null;
			 c = c.next;
		   }
		 }
	   }
	   return token;
	 }
	 token = oldToken;
	 jj_kind = kind;
	 throw generateParseException();
  }

  @SuppressWarnings("serial")
  static private final class LookaheadSuccess extends java.lang.Error {
    @Override
    public Throwable fillInStackTrace() {
      return this;
    }
  }
  static private final LookaheadSuccess jj_ls = new LookaheadSuccess();
  private boolean jj_scan_token(int kind) {
	 if (jj_scanpos == jj_lastpos) {
	   jj_la--;
	   if (jj_scanpos.next == null) {
		 jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
	   } else {
		 jj_lastpos = jj_scanpos = jj_scanpos.next;
	   }
	 } else {
	   jj_scanpos = jj_scanpos.next;
	 }
	 if (jj_rescan) {
	   int i = 0; Token tok = token;
	   while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
	   if (tok != null) jj_add_error_token(kind, i);
	 }
	 if (jj_scanpos.kind != kind) return true;
	 if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
	 return false;
  }


/** Get the next Token. */
  final public Token getNextToken() {
	 if (token.next != null) token = token.next;
	 else token = token.next = token_source.getNextToken();
	 jj_ntk = -1;
	 jj_gen++;
	 return token;
  }

/** Get the specific Token. */
  final public Token getToken(int index) {
	 Token t = token;
	 for (int i = 0; i < index; i++) {
	   if (t.next != null) t = t.next;
	   else t = t.next = token_source.getNextToken();
	 }
	 return t;
  }

  private int jj_ntk_f() {
	 if ((jj_nt=token.next) == null)
	   return (jj_ntk = (token.next=token_source.getNextToken()).kind);
	 else
	   return (jj_ntk = jj_nt.kind);
  }

  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
  private int[] jj_expentry;
  private int jj_kind = -1;
  private int[] jj_lasttokens = new int[100];
  private int jj_endpos;

  private void jj_add_error_token(int kind, int pos) {
	 if (pos >= 100) {
		return;
	 }

	 if (pos == jj_endpos + 1) {
	   jj_lasttokens[jj_endpos++] = kind;
	 } else if (jj_endpos != 0) {
	   jj_expentry = new int[jj_endpos];

	   for (int i = 0; i < jj_endpos; i++) {
		 jj_expentry[i] = jj_lasttokens[i];
	   }

	   for (int[] oldentry : jj_expentries) {
		 if (oldentry.length == jj_expentry.length) {
		   boolean isMatched = true;

		   for (int i = 0; i < jj_expentry.length; i++) {
			 if (oldentry[i] != jj_expentry[i]) {
			   isMatched = false;
			   break;
			 }

		   }
		   if (isMatched) {
			 jj_expentries.add(jj_expentry);
			 break;
		   }
		 }
	   }

	   if (pos != 0) {
		 jj_lasttokens[(jj_endpos = pos) - 1] = kind;
	   }
	 }
  }

  /** Generate ParseException. */
  public ParseException generateParseException() {
	 jj_expentries.clear();
	 boolean[] la1tokens = new boolean[95];
	 if (jj_kind >= 0) {
	   la1tokens[jj_kind] = true;
	   jj_kind = -1;
	 }
	 for (int i = 0; i < 38; i++) {
	   if (jj_la1[i] == jj_gen) {
		 for (int j = 0; j < 32; j++) {
		   if ((jj_la1_0[i] & (1<<j)) != 0) {
			 la1tokens[j] = true;
		   }
		   if ((jj_la1_1[i] & (1<<j)) != 0) {
			 la1tokens[32+j] = true;
		   }
		   if ((jj_la1_2[i] & (1<<j)) != 0) {
			 la1tokens[64+j] = true;
		   }
		 }
	   }
	 }
	 for (int i = 0; i < 95; i++) {
	   if (la1tokens[i]) {
		 jj_expentry = new int[1];
		 jj_expentry[0] = i;
		 jj_expentries.add(jj_expentry);
	   }
	 }
	 jj_endpos = 0;
	 jj_rescan_token();
	 jj_add_error_token(0, 0);
	 int[][] exptokseq = new int[jj_expentries.size()][];
	 for (int i = 0; i < jj_expentries.size(); i++) {
	   exptokseq[i] = jj_expentries.get(i);
	 }
	 return new ParseException(token, exptokseq, tokenImage);
  }

  private boolean trace_enabled;

/** Trace enabled. */
  final public boolean trace_enabled() {
	 return trace_enabled;
  }

  /** Enable tracing. */
  final public void enable_tracing() {
  }

  /** Disable tracing. */
  final public void disable_tracing() {
  }

  private void jj_rescan_token() {
	 jj_rescan = true;
	 for (int i = 0; i < 7; i++) {
	   try {
		 JJCalls p = jj_2_rtns[i];

		 do {
		   if (p.gen > jj_gen) {
			 jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
			 switch (i) {
			   case 0: jj_3_1(); break;
			   case 1: jj_3_2(); break;
			   case 2: jj_3_3(); break;
			   case 3: jj_3_4(); break;
			   case 4: jj_3_5(); break;
			   case 5: jj_3_6(); break;
			   case 6: jj_3_7(); break;
			 }
		   }
		   p = p.next;
		 } while (p != null);

		 } catch(LookaheadSuccess ls) { }
	 }
	 jj_rescan = false;
  }

  private void jj_save(int index, int xla) {
	 JJCalls p = jj_2_rtns[index];
	 while (p.gen > jj_gen) {
	   if (p.next == null) { p = p.next = new JJCalls(); break; }
	   p = p.next;
	 }

	 p.gen = jj_gen + xla - jj_la; 
	 p.first = token;
	 p.arg = xla;
  }

  static final class JJCalls {
	 int gen;
	 Token first;
	 int arg;
	 JJCalls next;
  }

}
