private NodeList<Stmt> buildLookaheadWithAmountCondition(
      List<GLocation> location,
      int lookahead,
      int amount,
      NodeList<FormalParameter> params,
      NodeList<Expr> args) {
    NodeList<Stmt> stmts = emptyList();
    if (amount == 0) {
      stmts = stmts.append(returnStmt().withExpr(LOOKAHEAD));
    } else {
      GContinuations c = new GContinuations(location, productions, lookahead > 0);
      c.next();

      Map<String, List<GLocation>> terminals = c.perTerminalLocations();
      if (terminals.isEmpty()) {
        stmts = stmts.append(returnStmt().withExpr(LOOKAHEAD));
      } else {
        for (Map.Entry<String, List<GLocation>> entry : terminals.entrySet()) {
          String terminal = entry.getKey();
          List<GLocation> following = entry.getValue();

          stmts =
              stmts.append(
                  ifStmt(
                      binaryExpr(
                          matchCall(terminal, literalExpr(lookahead)),
                          BinaryOp.NotEqual,
                          FAILED_LOOKAHEAD),
                      blockStmt()
                          .withStmts(
                              buildLookaheadWithAmountCondition(
                                  following, lookahead + 1, amount - 1, params, args))));
        }
      }
    }
    return stmts;
  }
 private List<String> firstTerminalsOf(GExpansion expansion) {
   GContinuations c = new GContinuations(expansion.location(), productions, false);
   c.next();
   return c.terminals();
 }